C语言获取Windows桌面路径
总述
桌面路径一般存储在Windows的注册表中的HKEY_CURRENT_USER/Software/Micorsoft/Windows/CurrentVersion/Explorer/user Shell Folders
下的Desktop
键值下,通过读取这个键值可以通过程序获取用户的桌面路径。
那为什么要费这么大劲获取桌面路径而不是直接在程序中将桌面路径设定为一个确定位置呢?通过上文我们得知桌面的路径是存储在注册表中的,也就是说用户其实可以通过修改注册表(或者是通过资源管理器)修改桌面文件夹的所在位置,所以我们如果需要用户准确的桌面位置最好的方法就是获取。
本文讲述通过C语言获取桌面路径的方法。提供实现思路和相关函数的基本使用,函数更详细的使用方法请移步百度。
思路
其实思路很简单,上文中我们得知,桌面的路径存储在注册表中的键值中,那么我们可以通过读取注册表键值来获取到桌面的路径。
函数
C语言并未提供读取Windows注册表的函数,但我们可以通过Windows提供的API函数来读取到相应的注册表键值。
这里一共需要使用到两个Windows API函数:
RegOpenKeyEx()
RegQueryValueeXW()
函数RegOpenKeyEx()
这个函数定义在atltransactionmanager.h
头文件中,
函数原型:
inline LSTATUS CAtlTransactionManager::RegOpenKeyEx(
HKEY hKey,
LPCTSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult
);
若执行成功,则返回ERROR_SUCCESS
若执行失败,则返回一个在Windows.h中定义的非零值
RegOpenKeyEx()参数
类型 | 参数 | 用途 |
---|---|---|
HKEY | hkey | 传递给打开注册表项的句柄。一般指注册表中五个根键之一 |
LPCTSTR | lpSubkey | 指子键的路径 |
DWORD | ulOptions | 保留参数,此参数必须为0 |
REGSAM | samDesired | 函数访问的权限掩码,即函数访问注册表的某些内容的权限 |
PHKEY | phkResult | 用于接收函数返回指向注册表项的指针 |
RegOpenKeyEx()权限掩码
掩码名 | 对应权限 |
---|---|
KEY_CREATE_LINK | 许可创建一个符号连接 |
KEY_CREATE_SUB_KEY | 许可创建子键 |
KEY_ENUMERATE_SUB_KEYS | 许可列举子键 |
KEY_EXECUTE | 许可读访问 |
KEY_NOTIFY | 许可提供更改通知 |
KEY_QUERY_VALUE | 许可查询子键数据 |
KEY_SET_VALUE | 许可设置子键数据 |
KEY_ALL_ACCESS | 联合了 KEY_QUERY_VALUE , KEY_ENUMERATE_SUB_KEYS , KEY_NOTIFY , KEY_CREATE_SUB_KEY , KEY_CREATE_LINK ,KEY_SET_VALUE 访问权限并且加上所有的标准访问权限除了SYNCHRONIZE |
KEY_READ | 联合了 STANDARD_RIGHTS_READ , KEY_QUERY_VALUE,KEY_ENUMERATE_SUB_KEYS ,KEY_NOTIFY 访问权限 |
KEY_WOW64_64KEY | 使64位或者32位应用程序打开64位键 |
KEY_WOW64_32KEY | 使64位或者32位应用程序打开32位键 |
KEY_WRITE | 联合 STANDARD_RIGHTS_WRITE , KEY_SET_VALUE , KEY_CREATE_SUB_KEY 访问权限 |
注册表五个主键
根键 | 包含的内容 |
---|---|
HKEY_CLASSES_ROOT | 包含了所有应用程序运行时必需的信息,是系统中控制所有数据文件的项 |
HKEY_CURRENT_CONFIG | 在HKEY_LOCAL_MACHINE 中当前硬件配置信息的映射 |
HKEY_USERS | 仅包含了缺省用户设置和登陆用户的信息 |
HKEY_LOCAL_MACHINE | 保存了注册表里的所有与这台计算机有关的配置信息,只是一个公共配置信息单元 |
HKEY_CURRENT_USER | 管理系统当前的用户信息 |
了解上信息后写出下面的代码
//桌面注册表键指针
HKEY Desktop;
//函数打开正确性返回值
long ReturnKey = -1;
//打开桌面路径注册表键
ReturnKey = RegOpenKeyEx(HKEY_CURRENT_USER,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"),
0,
KEY_WOW64_32KEY | KEY_ALL_ACCESS,
&Desktop);
通过上述代码获得指向HKEY_CURRENT_USER
主键的指针Desktop
。
至此,打开注册表子键完成。
得到一个返回值ReturnKey
存储RegOpenKeyEx
的返回值和指向Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders
的指针Desktop
函数RegQueryValueExW()
函数定义在Windows.h
头文件中
函数原型:
LSTATUS _stdcall RegQueryValueExW(
HKEY hKey,
LPCWSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
返回值与上个函数相同
若执行成功,则返回ERROR_SUCCESS
若执行失败,则返回一个在Windows.h中定义的非零值
RegQueryValueExW()参数
类型 | 参数 | 用途 |
---|---|---|
HKEY | hKey | 一个已打开项的句柄,可用上文中的Desktop 指针 |
LPCWSTR | lpValueName | 要查询注册表键值的名字字符串,注册表键的名字 |
LPDWORD | lpReserved | 未用,设为0(NULL ) |
LPDWORD | lpType | 用于装载取回数据类型的一个变量 |
LPBYTE | lpData | 用于装载指定值的一个缓冲区 |
LPDWORD | lpcbData | 用于装载lpData 缓冲区长度的一个变量 |
那么得知以上关于RegQueryValueExW()
函数的信息后我们可以写出下面的代码
了解上信息后写出下面的代码
ReturnKey = RegQueryValueExW(Desktop,
TEXT("Desktop"),
NULL,
NULL,
(LPBYTE)&Path,
&DFsize);
上面代码中,我们仍然使用ReturnKey
作为函数返回值存储变量,由函数的参数得知,Desktop
是从RegOpenKeyEx()
函数中返回的,那么此时若ReturnKey = NULL
,则这个函数将变得毫无意义,出现错误。所以我们应该使用之前应该判断RegOpenKeyEx()
函数是否执行成功,这里不再赘述。
如果RegQueryValueExW()
函数执行成功,那么Path
变量中存储的将是以WCHAR
变量类型存储的键值,在这里也就是我们所需要的桌面的路径。
信息的转换
通常情况下,我们所需要的数据一般是以char
类型处理,这样的话处理起来也相对方便,兼容性也更高。但上面方法得到的路径是WCHAR
(宽字符型)的,所以我们可以使用一个函数来将WCHAR
类型转换为char
类型。
函数
WideCharToMultiByte()函数
函数存在于Windows.h
头文件下
函数原型:
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cchMultiByte,
LPCSTR lpDefaultChar,
LPBOOL pfUsedDefaultChar
);
WideCharToMultiByte()参数
参数 | 作用 |
---|---|
UINT CodePage, | 指定执行转换的代码页 |
DWORD dwFlags, | 允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 |
LPCWSTR lpWideCharStr, | 指定要转换为宽字节字符串的缓冲区 |
int cchWideChar | 指定由参数lpWideCharStr 指向的缓冲区的字符个数 |
LPSTR lpMultiByteStr | 指向接收被转换字符串的缓冲区 |
int cchMultiByte | 指定由参数lpMultiByteStr 指向的缓冲区最大值 |
LPCSTR lpDefaultChar | 遇到一个不能转换的宽字符,函数便会使用pDefaultChar |
LPBOOL pfUsedDefaultChar | 至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE |
WideCharToMultiByte()返回值
状态 | 条件 | 返回值 |
---|---|---|
成功 | cchMultiByte 不为零 | 由 lpMultiByteStr 指向的缓冲区中写入的字节数 |
成功 | cchMultiByte 为零 | 接收到待转换字符串的缓冲区所必需的字节数 |
失败 | 0 |
通过WideCharToMultiByte()转换结果
WideCharToMultiByte(CP_UTF8, 0, Path, -1, N_Path, 256, NULL, NULL);
Path
是原来的WCHAR
类型的路径,N_Path
是转换后的char
类型的路径。
结果
通过上述过程,我们就得到了char类型的桌面路径的字符串。
我们可以通过这种方法在某些需要在用户桌面操作的程序中获取正确的桌面路径。
参考文献
本文中出现的思路,程序代码均为原创,其中函数用法有参考其他内容:
函数WideCharToMultiByte()用法
百度百科 RegOpenKeyEx
百度百科 RegQueryValueExW
文章结束,感谢大家的阅读。