Created
April 13, 2017 21:34
-
-
Save danzek/d7192d250c951804dec05125f5223a30 to your computer and use it in GitHub Desktop.
Create Directory Recursively with Windows API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* From http://blog.nuclex-games.com/2012/06/how-to-create-directories-recursively-with-win32/ | |
* Retrieved April 12, 2017 | |
* Posted by user Cygon (http://blog.nuclex-games.com/author/cygon/) | |
* | |
* This code is free for the taking and you can use it however you want. | |
* | |
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT | |
* LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
* | |
* As I just found out, the CreateDirectory function on Win32 can only create one directory at a time. | |
* If one, for example, specifies C:\Users\All Users\FirstNew\SecondNew as the directory to create, and | |
* both FirstNew and SecondNew do not exist, then CreateDirectory() fails.... Here's a workaround: | |
*/ | |
/// <summary>Creates all directories down to the specified path</summary> | |
/// <param name="directory">Directory that will be created recursively</param> | |
/// <remarks> | |
/// The provided directory must not be terminated with a path separator. | |
/// </remarks> | |
void createDirectoryRecursively(const std::wstring &directory) { | |
static const std::wstring separators(L"\\/"); | |
// If the specified directory name doesn't exist, do our thing | |
DWORD fileAttributes = ::GetFileAttributesW(directory.c_str()); | |
if(fileAttributes == INVALID_FILE_ATTRIBUTES) { | |
// Recursively do it all again for the parent directory, if any | |
std::size_t slashIndex = directory.find_last_of(separators); | |
if(slashIndex != std::wstring::npos) { | |
createDirectoryRecursively(directory.substr(0, slashIndex)); | |
} | |
// Create the last directory on the path (the recursive calls will have taken | |
// care of the parent directories by now) | |
BOOL result = ::CreateDirectoryW(directory.c_str(), nullptr); | |
if(result == FALSE) { | |
throw std::runtime_error("Could not create directory"); | |
} | |
} else { // Specified directory name already exists as a file or directory | |
bool isDirectoryOrJunction = | |
((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) || | |
((fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0); | |
if(!isDirectoryOrJunction) { | |
throw std::runtime_error( | |
"Could not create directory because a file with the same name exists" | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment