2025年2月24日 星期一 甲辰(龙)年 腊月廿四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > VC/VC++

逐级创建目录(WIndowsAPI:SHCreateDirectoryEx函数和SHCreateDirectory函数)

时间:10-19来源:作者:点击数:30

一、SHCreateDirectoryEx 函数(支持安全属性)

SHCreateDirectoryEx 函数是 Windows API 中用于创建目录的函数。它允许开发者创建一个指定路径的目录,如果该目录已经存在,则不会进行任何操作。

函数原型
  • HRESULT SHCreateDirectoryEx(
  • HWND hwnd,
  • PCWSTR pszPath,
  • LPSECURITY_ATTRIBUTES psa
  • );
参数说明
  • hwnd:
    • 类型:HWND
    • 描述:一个窗口句柄,通常用于显示任何可能的错误消息。如果不需要显示错误消息,可以传递 NULL
  • pszPath:
    • 类型:PCWSTR
    • 描述:指向要创建的目录的路径的指针。该路径可以是相对路径或绝对路径。
  • psa:
    • 类型:LPSECURITY_ATTRIBUTES
    • 描述:指向 SECURITY_ATTRIBUTES 结构的指针,该结构定义了新目录的安全描述符。如果不需要自定义安全性,可以传递 NULL
返回值
  • 如果函数成功,返回 S_OK
  • 如果函数失败,返回相应的 HRESULT 错误代码。
使用示例

以下是一个简单的示例,展示如何使用 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;
  • }
注意事项
  1. 错误处理: 在使用时务必检查返回值,以确保目录创建成功。
  2. Unicode 支持SHCreateDirectoryEx 是支持 Unicode 的,因此建议使用宽字符字符串(如示例中所示)。
  3. 权限问题: 创建目录可能会受到用户权限的限制。确保程序有足够的权限以创建指定位置的目录。
  4. 包含头文件和库: 使用该函数时,需要包含 <windows.h> 和 <shlobj.h> 头文件,并在编译时链接到 Shell32.lib

二、SHCreateDirectory 函数(不支持安全属性)

SHCreateDirectory 函数是 Windows API 用于创建一个新目录的函数。与 SHCreateDirectoryEx 相似,但 SHCreateDirectory 不支持安全属性参数,适合用于简单的目录创建任务。

函数原型
  • HRESULT SHCreateDirectory(
  • HWND hwnd,
  • PCWSTR pszPath
  • );
参数说明
  • hwnd:
    • 类型:HWND
    • 描述:一个窗口句柄,用于显示可能的错误消息。如果不需要显示错误消息,可以传递 NULL
  • pszPath:
    • 类型:PCWSTR
    • 描述:指向要创建的目录路径的指针。该路径可以是相对路径或绝对路径。
返回值
  • 如果函数成功,返回 S_OK
  • 如果函数失败,返回相应的 HRESULT 错误代码,可以使用 HRESULT_FROM_WIN32(GetLastError()) 来获取更多的错误信息。
使用示例

以下是一个简单的示例,展示如何使用 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;
  • }
注意事项
  1. 错误处理: 确保检查返回值,以确保目录创建成功,并可以根据返回的 HRESULT 错误代码执行适当的错误处理。
  2. Unicode 支持SHCreateDirectory 是支持 Unicode 的,因此建议使用宽字符字符串(如示例中所示)。
  3. 权限问题: 创建目录可能会受到用户权限限制,因此确保程序有足够的权限来创建指定位置的目录。
  4. 包含头文件和库: 使用该函数时,需要包含 <windows.h> 和 <shlobj.h> 头文件,并在编译时链接到 Shell32.lib

三、仿照上述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;
  • }
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐