【问题标题】:Are environment variables affected after impersonating and loading a user profile in a service?在服务中模拟和加载用户配置文件后,环境变量是否会受到影响?
【发布时间】:2013-02-04 18:58:18
【问题描述】:

我有一个在 LocalSystem 帐户下运行的 Windows 服务,我正在尝试访问一些特定于用户的环境变量。当我调用 ExpandEnvironmentStrings("%AppData%") 时,我得到“C:\windows\system32\config\systemprofile\AppData\Roaming”。

我认为模拟和加载用户配置文件应该可以解决这个问题,所以我打电话:

  • Lo​​gonUser()
  • Lo​​adUserProfile()
  • CreateEnvironmentBlock()
  • ImpersonateLoggedOnUser()

而且,ExpandEnvironmentStrings("%AppData%") 返回系统文件夹,而不是像“C:\Users\Username\AppData\Roaming”这样的文件夹。

然后我又搜索了一些,然后发现了 SHGetFolderPath(CSIDL_LOCAL_APPDATA),它的作用就像一个魅力后模仿。

我的问题不是我应该做什么(即 SHGetFolderPath),而是更多关于环境变量如何在服务中工作的问题。我认为我的问题是:

  1. 我的 LoadUserProfile() 代码仍然缺少某些内容,即使一切都返回成功。我无知的一面想说服我,理论上,加载用户配置文件应该使 ExpandEnvironmentStrings() 返回加载的用户的值。

  2. 根据一些读数,服务中的环境变量似乎在系统启动时只读取一次 (http://support.microsoft.com/kb/887693),所以我的服务只知道系统环境变量。

我倾向于 2。但我只需要有人来确认这一点,所以我不认为有什么可能是错误的。

【问题讨论】:

    标签: c++ winapi service environment-variables


    【解决方案1】:

    The docs for Environment variables 表示#2 是正确的。引用,强调:

    每个进程都有一个环境块,其中包含一组 环境变量及其值。

    MSDN 指向ExpandEnvironmentStringForUser() 来解决您原来的问题。

    【讨论】:

    • 这就是为什么我认为CreateEnvironmentBlock() 会获取用户的环境变量。它的 MSDN 文档再简单不过了,“检索指定用户的环境变量”。编辑:再一次,我想这只有在我调用 CreateProcessAsUser() 时才有效,然后能够在该新进程中访问我的用户的环境变量。
    • @ykay: CreateEnvironmentBlock() 只是分配一个包含环境值的内存块,但是你必须将该内存块实际应用到某些东西上。您不能将其应用于调用进程,但您可以将其应用于新进程。
    • 当然,您可以读取从 CreateEnvironmentBlock 返回的变量块,但您必须手动完成 - 据我所知,没有 API 函数可以这样做。
    猜你喜欢
    • 2022-12-01
    • 2023-02-10
    • 2023-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2015-03-27
    相关资源
    最近更新 更多