5

In Win32 API, there is CopyFile that literally copies a file. However, this API doesn't create folders. For example, I'd like to copy C:\Data\output.txt to D:\Temp\Data\output.txt. But, the target folders, D:\Temp and D:\Temp\Data', do not exist. In this case, this API just fails.

Is there a handy API that can automatically and recursively create directory structure on copy? Definitely, I can make such function, but I expect someone already made the function.

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
minjang
  • 8,860
  • 9
  • 42
  • 61

2 Answers2

6

SHFileOperation should do the trick. From MSDN:

Copy and Move operations can specify destination directories that do not exist. In those cases, the system attempts to create them and normally displays a dialog box to ask the user if they want to create the new directory. To suppress this dialog box and have the directories created silently, set the FOF_NOCONFIRMMKDIR flag in fFlags.

Aaron Klotz
  • 11,287
  • 1
  • 28
  • 22
  • 1
    Thanks. `SHFileOperation` creates folder structures, but some glitch in actual file copy. It just created a folder with the name of source file name! Anyway, `SHFileOperation` + `CopyFile` did the job. – minjang Dec 21 '09 at 08:09
0

You can achieve desired result using SHCreateDirectoryEx. Here is an example:

inline void EnsureDirExists(const std::wstring& fullDirPath)
{
    HWND hwnd = NULL;
    const SECURITY_ATTRIBUTES *psa = NULL;
    int retval = SHCreateDirectoryEx(hwnd, fullDirPath.c_str(), psa);
    if (retval == ERROR_SUCCESS || retval == ERROR_FILE_EXISTS || retval == ERROR_ALREADY_EXISTS)
    return; //success

    throw boost::str(boost::wformat(L"Error accessing directory path: %1%; win32 error code: %2%") 
       % fullDirPath
       % boost::lexical_cast<std::wstring>(retval));

    //TODO *djg* must do error handling here, this can fail for permissions and that sort of thing
}
Marko Popovic
  • 3,999
  • 3
  • 22
  • 37
Dustin Getz
  • 21,282
  • 15
  • 82
  • 131