2012-10-11 35 views
1

Possible Duplicate:
c++ how to create a directory from a pathWinAPI的 - 創建.ini文件,如果它不存在

我試圖創建的應用程序數據文件夾,這樣我就可以使用設置的.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。 如何檢查文件和目錄是否存在,如果不存在,然後創建它們?

回答

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; 
    } 
+0

花了我一會兒,看看你改變了什麼,所以基本上我只需要使用'CREATE_NEW'?因爲'CreateDirectory'是返回false的東西,並且在代碼中沒有改變。 –

+0

另一個更改是在嘗試創建目錄後檢查GetLastError()== ERROR_ALREADY_EXISTS。我剛剛用'SHCreateDirectoryEx'替換了'CreateDirectory'' – Andrey

+0

+1代碼和'CREATE_NEW'更正。但我希望它可以在舊版Windows上工作。所以我會一次製作一個分區。 –

1

您需要一次創建一個級別的子文件夾。

即創建「我的公司」,然後「我的程序」,然後「1.0」..你可以寫一個函數來做到這一點,類似於VCL的ForceDirectories。

此外,請注意,除非使用管理員權限運行,否則常見應用程序數據在Windows7上不可寫入。除非您的應用程序安裝程序創建了一個子文件夾並在其上設置適當的安全ACL以允許訪問。避免如果可以並使用用戶應用程序數據文件夾。

+0

如何獲取用戶的AppData文件夾?因爲我想避免必須獲得管理員權限。 –

+0

哦,'CSIDL_APPDATA'還是'CSIDL_APPDATA_LOCAL'?或者會做? –

+0

'CSIDL_APPDATA'。這是一個漫遊配置文件的作品。 –

相關問題