【问题标题】:How to get user home directory on Windows?如何在 Windows 上获取用户主目录?
【发布时间】:2017-03-09 13:08:28
【问题描述】:

我正在开发一个跨平台库,旨在从用户的主目录加载配置文件。这个想法是自动提供配置参数而不用编辑代码。

此库可用于桌面应用程序或守护程序/服务。在(我假设)大多数 Unix 环境中,我可以使用 getpwuid() 来获取用户的主目录。在 Windows SO told me 中,我可以使用 SHGetKnownFolderPath,但它的文档说它仅适用于桌面应用程序。有没有办法在 Windows 上为运行服务的用户获取此路径?

【问题讨论】:

  • 服务桌面应用程序。关于“仅限桌面应用程序”的条款意味着您不能在例如 Windows Phone 应用程序中使用它。
  • ...当然,您将获得与运行服务的用户帐户关联的文件夹。这可能有意义,具体取决于服务的方式配置。但是,对于图书馆来说似乎不太明智。使用你的库的程序员肯定应该设置参数,而不是最终用户?

标签: c++ windows home-directory


【解决方案1】:

对于控制台应用程序,最简单的方法是检索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 怀疑它们会被覆盖或更改。
【解决方案2】:

您可以使用 ExpandEnvironmentStrings(...) 解析 %HOMEPATH%

【讨论】:

  • 那个变量并不总是存在的。
【解决方案3】:

这个呢:

#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++: How do I create a Shortcut in the Start Menu on Windows

【讨论】:

  • 不,不,不!配置文件目录不是配置文件的正确位置。试试CSIDL_APPDATA
  • 据我了解,他想要用户的主目录。
  • 一直有some disagreement 在有人问错问题时如何做出最好的回应。我坚信你给他们提供他们需要的信息,而不是(或以及)他们要求的信息。
  • ...此外,用户的主目录不一定是他们的个人资料目录。如果用户帐户设置未明确指定主目录,则这只是默认设置。 (我只是在这里吹毛求疵,区别并不重要,特别是因为现代应用程序不应该使用配置文件目录或主目录。)
  • SHGetFolderPathW 似乎已弃用
【解决方案4】:

那么你想让用户主目录处于服务状态吗? - 如果您希望它处于服务状态,则必须使用GetUserToken() 获取用户令牌,然后将它们复制为CreateprocessAsUser() - 否则我认为最好使用SHGetSpecialPath()SHGetTempPath()

【讨论】:

  • 注意!!仅可用于 5.2 ~ 5.3 版本的桌面应用程序。 - MSDN [msdn.microsoft.com/en-us/library/windows/desktop/…
  • 那个页面是404。
  • 你必须删除最后一个字符“]”!我想你没有注意到我的回答。我不会;不再打字了。
  • 感谢您的所有回答! ruipacheco。
猜你喜欢
  • 2012-03-21
  • 2023-03-23
  • 2011-12-16
  • 2021-06-09
  • 2023-03-03
  • 2014-08-23
  • 1970-01-01
  • 2019-06-20
  • 2016-01-25
相关资源
最近更新 更多