1

重複の可能性:
c++パスからディレクトリを作成する方法

設定を使用できるように、アプリケーションデータフォルダーに.iniファイルを作成しようとしています。試してみましたが、既に存在するかどうかを確認し、存在しない場合はサブディレクトリと.iniファイルを作成する方法がわかりませんでした。

最後のエラーメッセージが表示されると、「システムは指定されたパスを見つけることができません」と表示されます。

#include <string>
using namespace std;

#include <Windows.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#pragma comment(lib, "shlwapi.lib")

namespace Settings
{
    CIni        Ini;
    bool        Available = false;
    char        Directory[MAX_PATH];
    const char *IniFileName = "Settings.ini";

    void CheckError() {
        LPVOID lpMsgBuf;
        LPVOID lpDisplayBuf;
        DWORD dw = GetLastError(); 

        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | 
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL, dw,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf, 0, NULL
        );

        string msg = (LPTSTR)lpMsgBuf;
        Error(msg); // MessageBox
    }

    void Initialize() {
        // Get AppData directory
        if (SHGetFolderPath(0, CSIDL_COMMON_APPDATA, 0, 0, Directory) >= 0) {
            string fullpath;
            string subDir = "\\MyCompany\\MyProgram\\1.0\\";

            PathAppend(Directory, subDir.c_str());
            fullpath = Directory;
            fullpath += IniFileName;

            // If directory doesn't exist, create it.
            DWORD attrib = GetFileAttributes(Directory);
            if (!(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY))) {

                if (CreateDirectory(Directory, NULL)) {
                    HANDLE file = CreateFile(
                        fullpath.c_str(), GENERIC_WRITE, 0, 0,
                        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
                    );

                    if (file != INVALID_HANDLE_VALUE) {
                        CloseHandle(file);
                    } else {
                        CheckError();
                        return;
                    }
                } else {
                    CheckError();
                    return;
                }
            }

            Ini.SetPathName(fullpath.c_str());
            Available = true;
        }
    }
}

チェックしたところ、への呼び出しCreateDirectory()がfalseを返しています。ファイルとディレクトリが存在するかどうかを確認し、存在しない場合は作成するにはどうすればよいですか?

4

2 に答える 2

1

サブフォルダは一度に1レベルずつ作成する必要があります。

つまり、「MyCompany」、「MyProgram」、「1.0」の順に作成します。VCLのForceDirectoriesと同様に、これを行う関数を作成できます。

さらに、管理者権限で実行しない限り、一般的なアプリデータはWindows7で書き込み可能ではないことに注意してください。アプリケーションインストーラーがサブフォルダーを作成し、アクセスを許可するために適切なセキュリティACLを設定しない限り。可能であれば避けて、ユーザーアプリのデータフォルダーを使用してください。

于 2012-10-11T12:12:06.317 に答える
1
if (SHCreateDirectoryEx(NULL, Directory, NULL) || 
    GetLastError() == ERROR_ALREADY_EXISTS) 
   {
   HANDLE file = CreateFile(
      fullpath.c_str(), GENERIC_WRITE, 0, 0,
      CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);

   if (file != INVALID_HANDLE_VALUE) 
     {
     CloseHandle(file);
     } 
     else if (GetLastError() != ERROR_FILE_EXISTS) 
       {
       CheckError();
       return;
       }
   } 
   else 
   {
   CheckError();
   return;
   }
于 2012-10-11T12:17:21.730 に答える