C++ Windows HOME-获取(已知)文件夹路径
我正在尝试编写一个函数,以获得Windows与HOME的等效功能。我的C语言技能已经过时了,所以不要介意我的示例代码没有编译。我正在尝试在Windows Vista和更新版本上使用SHGetKnownFolderPath,在Server 2003和更高版本上使用SHGetFolderPath。由于我预计会遇到运行Windows XP的用户,因为它仍然是Windows的头号部署版本,因此我将避免在符号表中引用SHGetKnownFolderPath,因为这将导致二进制文件甚至无法加载到XP上。我知道如何加载库shell32并从中获取ProcAddress,但至少可以说,我在函数指针方面的技能是垃圾 当我编写特性时,它们很难处理,我将它们隔离到一个单独的示例文件中。到目前为止,我举了一个失败的例子: 包括 包括 //将此Vista指针化,以及以后调用XP/2000 compat等。 typedef HRESULT WINAPI*lpSHGetKnownFolderPath REFKNOWNFOLDERID rfid, 德沃德·德弗拉格, 处理赫托肯, PWSTR*ppszPath lpSHGetKnownFolderPath; int main argc,char*argv[] { //SHGetKnownFolderPath方法。 hndl_shell32模块; lpSHGetKnownFolderPath pSHGetKnownFolderPath; hndl_shell32=LoadLibraryshell32; pSHGetKnownFolderPath=GetProcAddresshndl_shell32,shGetKnownFolderPath; ifpSHGetKnownFolderPath!=NULL{ }否则{ } }C++ Windows HOME-获取(已知)文件夹路径,c++,windows,winapi,C++,Windows,Winapi,我正在尝试编写一个函数,以获得Windows与HOME的等效功能。我的C语言技能已经过时了,所以不要介意我的示例代码没有编译。我正在尝试在Windows Vista和更新版本上使用SHGetKnownFolderPath,在Server 2003和更高版本上使用SHGetFolderPath。由于我预计会遇到运行Windows XP的用户,因为它仍然是Windows的头号部署版本,因此我将避免在符号表中引用SHGetKnownFolderPath,因为这将导致二进制文件甚至无法加载到XP上。我知
我的问题是:知道我做错了,我该怎么做才是对的?如果您能解释一下如何在将来正确地做这件事,我们将不胜感激。谢谢。这里是一个小应用程序,它展示了如何使用LoadLibrary和GetProcAddress,并在注释中提供了建议:
#include <windows.h>
#include <stdio.h>
#include <shlobj.h>
/* The name of the function pointer type is
'lpSHGetKnownFolderPath', no need for
additional token after ')'. */
typedef HRESULT (WINAPI* lpSHGetKnownFolderPath)(
REFKNOWNFOLDERID rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR *ppszPath
);
int main()
{
HMODULE hndl_shell32;
lpSHGetKnownFolderPath pSHGetKnownFolderPath;
/* Always check the return value of LoadLibrary. */
hndl_shell32 = LoadLibrary("shell32");
if (NULL != hndl_shell32)
{
/* There is no 'SHGetKnownFolderPathW()'.
You need to cast return value of 'GetProcAddress()'. */
pSHGetKnownFolderPath = (lpSHGetKnownFolderPath)
GetProcAddress(hndl_shell32, "SHGetKnownFolderPath");
if(pSHGetKnownFolderPath != NULL)
{
PWSTR user_dir = 0;
if (SUCCEEDED(pSHGetKnownFolderPath(
FOLDERID_Profile,
0,
NULL,
&user_dir)))
{
/* Use 'user_dir' - remember to:
CoTaskMemFree(user_dir);
when no longer required.
*/
}
}
else
{
fprintf(stderr, "Failed to locate function: %d\n",
GetLastError());
}
/* Always match LoadLibrary with FreeLibrary.
If FreeLibrary() results in the shell32.dll
being unloaded 'pSHGetKnownFolderPath' is
no longer valid.
*/
FreeLibrary(hndl_shell32);
}
else
{
fprintf(stderr, "Failed to load shell32.dll: %d\n", GetLastError());
}
return 0;
}
这是在Windows XP上编译的
Windows XP上的输出:
未能找到函数:127
其中127表示找不到指定的程序
Windows Vista上的输出:
C:\Users\admin
下面是一个小应用程序,演示如何使用LoadLibrary和GetProcAddress,并在注释中提供建议:
#include <windows.h>
#include <stdio.h>
#include <shlobj.h>
/* The name of the function pointer type is
'lpSHGetKnownFolderPath', no need for
additional token after ')'. */
typedef HRESULT (WINAPI* lpSHGetKnownFolderPath)(
REFKNOWNFOLDERID rfid,
DWORD dwFlags,
HANDLE hToken,
PWSTR *ppszPath
);
int main()
{
HMODULE hndl_shell32;
lpSHGetKnownFolderPath pSHGetKnownFolderPath;
/* Always check the return value of LoadLibrary. */
hndl_shell32 = LoadLibrary("shell32");
if (NULL != hndl_shell32)
{
/* There is no 'SHGetKnownFolderPathW()'.
You need to cast return value of 'GetProcAddress()'. */
pSHGetKnownFolderPath = (lpSHGetKnownFolderPath)
GetProcAddress(hndl_shell32, "SHGetKnownFolderPath");
if(pSHGetKnownFolderPath != NULL)
{
PWSTR user_dir = 0;
if (SUCCEEDED(pSHGetKnownFolderPath(
FOLDERID_Profile,
0,
NULL,
&user_dir)))
{
/* Use 'user_dir' - remember to:
CoTaskMemFree(user_dir);
when no longer required.
*/
}
}
else
{
fprintf(stderr, "Failed to locate function: %d\n",
GetLastError());
}
/* Always match LoadLibrary with FreeLibrary.
If FreeLibrary() results in the shell32.dll
being unloaded 'pSHGetKnownFolderPath' is
no longer valid.
*/
FreeLibrary(hndl_shell32);
}
else
{
fprintf(stderr, "Failed to load shell32.dll: %d\n", GetLastError());
}
return 0;
}
这是在Windows XP上编译的
Windows XP上的输出:
未能找到函数:127
其中127表示找不到指定的程序
Windows Vista上的输出:
C:\Users\admin
您可以始终使用getenvHOMEDRIVE和getenvHOMEPATH并连接结果
std::string home = std::string(getenv("HOMEDRIVE")) + getenv("HOMEPATH");
您可以始终使用getenvHOMEDRIVE和getenvHOMEPATH并连接结果
std::string home = std::string(getenv("HOMEDRIVE")) + getenv("HOMEPATH");
Windows等同于HOME的是USERPROFILE。它是一个普通的环境变量,就像在Linux中一样。您可以进行以下调用以检索它:
char *profilepath = getenv("USERPROFILE");
Windows等同于HOME的是USERPROFILE。它是一个普通的环境变量,就像在Linux中一样。您可以进行以下调用以检索它:
char *profilepath = getenv("USERPROFILE");
我将始终调用SHGetFolderPath并使用CSIDL。它简单得多,我看不出它的缺点。SHGetFolderPath函数在Vista和更高版本中被弃用。那又怎样?它有效,并将继续有效。如果你想支持XP,这是一个简单的解决方案。我会一直调用SHGetFolderPath并使用CSIDLs。它简单得多,我看不出它的缺点。SHGetFolderPath函数在Vista和更高版本中被弃用。那又怎样?它有效,并将继续有效。如果你想支持XP,这是一个简单的解决方案。那通常不是粘贴文件的最佳位置。这是一种快速而肮脏的方式来移植现有的Unix应用程序,但并不真正适用于本机Windows代码。True。这通常不是个好地方,但它仍然相当于家。更好的地方是appdata和localappdata。。。。或文件,取决于练习的目的。AFAIK Unix不像Windows那样区分不同的用户目录,因此实际上没有任何与HOME等效的唯一Windows。我有一个单独的函数来获取%AppData%。在Unix上,此函数只是附加到$HOME。通常情况下,这不是粘贴文件的最佳位置。这是一种快速而肮脏的方式来移植现有的Unix应用程序,但并不真正适用于本机Windows代码。True。这通常不是个好地方,但它仍然相当于家。更好的地方是appdata和localappdata。。。。或文件,取决于练习的目的。AFAIK Unix不像Windows那样区分不同的用户目录,因此实际上没有任何与HOME等效的唯一Windows。我有一个单独的函数来获取%AppData%。在Unix上,此函数只是附加到$HOME。这些环境变量并不总是存在。这些环境变量并不总是存在。我必须删除标头才能使其工作,否则它会因为IServiceProvider中的某个模糊符号而哭泣。我还必须为REFKNOWNFOLDERID参数添加新的参数。我必须删除标题才能使其正常工作,否则它会因为IServiceProvider中的某个模糊符号而哭泣。我还必须在REFKNOWNFOLDERID参数中包含。