如何在Windows上获取用户主目录?

9
我正在开发一个跨平台库,旨在从用户的主目录加载配置文件。这个想法是自动提供配置参数而无需编辑代码。
该库可用于桌面应用程序或守护进程/服务。在(我认为)大多数Unix环境中,我可以使用getpwuid()获取用户的主目录。在Windows SO 告诉我,我可以使用SHGetKnownFolderPath,但其文档说它仅适用于桌面应用程序。有没有办法在Windows上为运行服务的用户获取此路径?

2
服务是桌面应用程序。关于“仅限桌面应用程序”的条款意味着您不能在例如 Windows Phone 应用程序中使用它。 - Harry Johnston
当然,您将获得与服务运行的用户帐户相关联的文件夹。这取决于服务的配置,可能是有意义的。不过,对于库来说似乎不太合理;毕竟使用您的库的程序员应该设置参数,而不是最终用户。 - Harry Johnston
4个回答

9

对于控制台应用程序,最简单的方法是获取 USERPROFILE 环境变量或者连接 HOMEDRIVEHOMEPATH 环境变量的值。

使用标准库中的 getenv() 函数:https://msdn.microsoft.com/en-us/library/tehxacec.aspx

示例程序:

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv) {
    printf("USERPROFILE = %s\n", getenv("USERPROFILE"));
    printf("HOMEDRIVE   = %s\n", getenv("HOMEDRIVE"));
    printf("HOMEPATH    = %s\n", getenv("HOMEPATH"));
    return 0;
}

输出:

USERPROFILE = C:\Users\myuser
HOMEDRIVE   = C:
HOMEPATH    = \Users\myuser

这些变量在桌面/手机应用程序中可能会被覆盖吗? - ruipacheco
3
用户个人资料不是配置文件的正确位置。 - Harry Johnston
@ruipacheco 怀疑它们会被覆盖或更改。 - Paul

2
这个如何:

这是什么:

#include <shlobj.h> 

WCHAR profilePath[MAX_PATH];
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, profilePath);
if (SUCCEEDED(result)) {
    // Do whatever you want with it
    // For example:
    // QString::fromWCharArray(profilePath)
}

虽然我没有测试过。

请注意,你收到的是一个wchar数组(用于处理带有特殊字符的路径)。

我认为通过使用hToken参数,也可以查询当前用户以外其他用户的特殊文件夹。

还请参阅文档:https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx

我在另一种情况下使用了这段代码,我想获取开始菜单的位置。请参见此答案:C++:如何在Windows上创建开始菜单中的快捷方式


不,不,不!个人资料目录不是配置文件的正确位置。请尝试使用“CSIDL_APPDATA”。 - Harry Johnston
2
据我所理解,他想要用户的主目录。 - bweber
1
在人们询问错误问题时,如何最好地回答一直存在某种分歧。我坚定地站在一个观点上,即给他们所需的信息,而不仅仅是他们所询问的信息。 - Harry Johnston
此外,用户的主目录并不一定是他们的个人资料目录。如果用户帐户设置没有明确指定主目录,那么这只是默认值。(我只是在挑剔,这种区别实际上并不重要,特别是因为现代应用程序不应该使用个人资料目录或主目录做任何事情。) - Harry Johnston
SHGetFolderPathW 似乎已经过时。 - Adrian Maire
太棒了!谢谢你!我一直对依赖环境变量持谨慎态度,因为它们可能会被更改... - Gregor Hartl Watters

0

所以你想在服务状态下获取用户主目录吗? - 如果你想在服务状态下获取,你必须使用GetUserToken()来获取用户令牌,然后复制它们到CreateprocessAsUser() - 否则我认为最好使用SHGetSpecialPath()SHGetTempPath()


1
注意!仅可用于5.2~5.3版本的桌面应用程序。- MSDN [https://msdn.microsoft.com/zh-cn/library/windows/desktop/bb762181(v=vs.85).aspx] - Bryant
该页面是404错误。 - ruipacheco
你必须删除最后一个字符“]”!我觉得你没有注意到我的回答。我不会再打字了。 - Bryant
感谢您提供的所有答案!ruipacheco。 - Bryant

0
你可以使用 ExpandEnvironmentStrings(...) 解析 %HOMEPATH%。

该变量并不总是存在。 - Harry Johnston

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接