一、SHCreateDirectoryEx 函数(支持安全属性)
SHCreateDirectoryEx 函数是 Windows API 中用于创建目录的函数。它允许开发者创建一个指定路径的目录,如果该目录已经存在,则不会进行任何操作。
- HRESULT SHCreateDirectoryEx(
- HWND hwnd,
- PCWSTR pszPath,
- LPSECURITY_ATTRIBUTES psa
- );
-
以下是一个简单的示例,展示如何使用 SHCreateDirectoryEx 逐级创建目录:
- #include <windows.h>
- #include <shlobj.h>
- #include <iostream>
-
- int main()
- {
- // 要创建的目录路径
- PCWSTR path = L"C:\\Example\\1\\2\\3";
-
- // 调用 SHCreateDirectoryEx
- HRESULT result = SHCreateDirectoryEx(NULL, path, NULL);
-
- if (SUCCEEDED(result))
- {
- std::wcout << L"目录创建成功: " << path << std::endl;
- }
- else
- {
- std::wcerr << L"目录创建失败,错误代码: " << result << std::endl;
- }
-
- return 0;
- }
-
二、SHCreateDirectory 函数(不支持安全属性)
SHCreateDirectory 函数是 Windows API 用于创建一个新目录的函数。与 SHCreateDirectoryEx 相似,但 SHCreateDirectory 不支持安全属性参数,适合用于简单的目录创建任务。
- HRESULT SHCreateDirectory(
- HWND hwnd,
- PCWSTR pszPath
- );
-
以下是一个简单的示例,展示如何使用 SHCreateDirectory 逐级创建目录:
- #include <windows.h>
- #include <shlobj.h>
- #include <iostream>
-
- int main()
- {
- // 要创建的目录路径
- PCWSTR path = L"C:\\Example\\1\\2\\3";
-
- // 调用 SHCreateDirectory
- HRESULT result = SHCreateDirectory(NULL, path);
-
- if (SUCCEEDED(result))
- {
- std::wcout << L"目录创建成功: " << path << std::endl;
- }
- else
- {
- std::wcerr << L"目录创建失败,错误代码: " << HRESULT_CODE(result) << std::endl;
- }
-
- return 0;
- }
-
三、仿照上述API实现 CreateDirectoryRecursively 函数
-
- #include <windows.h>
- #include <iostream>
- #include <string>
-
-
- bool DirectoryExists(const std::string& path)
- {
- DWORD attributes = GetFileAttributes(path.c_str());
- return (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY));
- }
-
-
- bool CreateDirectoryRecursively(const std::string& path, DWORD attributes = 0)
- {
- // 检查目录是否已经存在
- //if (DirectoryExists(path))
- //{
- // return true; // 目录已存在
- //}
-
- DWORD attr = GetFileAttributes(path.c_str());
- bool result = (attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY));
- if (result)
- {
- return true; // 目录已存在
- }
-
- // 分割路径以获取逐级目录
- std::string currentPath;
- size_t pos = 0;
-
- while ((pos = path.find_first_of("\\/", pos)) != std::string::npos)
- {
- currentPath = path.substr(0, pos);
-
- // 创建当前逐级目录
- if (!currentPath.empty())
- {
- if (CreateDirectory(currentPath.c_str(), NULL) ||
- GetLastError() == ERROR_ALREADY_EXISTS)
- {
- // 如果成功或目录已存在,则继续
- }
- else
- {
- // 如果创建失败,输出错误信息并返回 false
- std::cerr << "创建目录失败: " << currentPath << ", 错误代码: " << GetLastError() << std::endl;
- return false;
- }
- }
-
- pos++; // 移动到下一个分隔符
- }
-
- // 最后创建目标目录,并应用属性
- if (!CreateDirectory(path.c_str(), NULL) && GetLastError() != ERROR_ALREADY_EXISTS)
- {
- std::cerr << "创建目录失败: " << path << ", 错误代码: " << GetLastError() << std::endl;
- return false;
- }
-
- // 应用目录属性(如果需要)
- if (attributes != 0)
- {
- SetFileAttributes(path.c_str(), attributes);
- }
-
- return true;
- }
-
- int main()
- {
- std::string path = "C:\\Users\\Admin\\Desktop\\Example\\SubDirectory1\\SubDirectory2";
- DWORD attributes = FILE_ATTRIBUTE_NORMAL; // 设定想要的属性
-
- if (CreateDirectoryRecursively(path, attributes))
- {
- std::cout << "目录创建成功: " << path << std::endl;
- }
- else
- {
- std::cerr << "目录创建失败: " << path << std::endl;
- }
-
- std::cin.get();
- return 0;
- }
-
-