关于Windows服务:在python中使用CreateProcessAsUser不会将用户环境传递给创建的进程

Using CreateProcessAsUser in python does not pass the user's environment to the created process

首先感谢您阅读本文所花费的时间。

我使用以下代码从交互式用户下的Windows服务中成功启动了一个应用程序可执行文件(简称为MyApp.exe):

1
2
3
4
5
6
7
8
9
#MyWindowsService.py

console_session_id = win32ts.WTSGetActiveConsoleSessionId()
console_user_token = win32ts.WTSQueryUserToken(console_session_id)

my_app_path= os.path.normpath(r"/Path\\to\\MyApp.exe")
startup = win32process.STARTUPINFO()
priority = win32con.NORMAL_PRIORITY_CLASS
handle, thread_id ,pid, tid = win32process.CreateProcessAsUser(console_user_token, my_app_path, None, None, None, True, priority, None, None, startup)

从MyApp内部,我需要获取属于交互式用户的环境路径。例如,我使用以下代码来获取用户的%appdata%的路径:

1
2
3
#MyApp.py

user_app_data_path = os.getenv('APPDATA')

它应该返回:

C:\\\\ Users \\\\交互式用户名\\\\ AppData \\
绿化

但是返回的值是:

C:\\\\ Windows \\\\ System32 \\\\ config \\\\ systemprofile \\\\ AppData \\
绿化

这意味着尽管MyApp.exe是用交互用户名启动的,但它为Windows服务在其下运行Windows服务的系统用户提供了环境。

我的问题是如何获取属于用户而非系统的环境路径。

非常感谢,

P.S。我正在使用py2exe将MyApp和Windows服务转换为可执行文件。


我发现了答案,以防有人感兴趣:

如果未明确指定环境,则此过程将继承父级的环境。使用此环境可以获取环境并将其传递给CreateProcessAsUser。

只需遵循以下代码中的环境字即可。

1
2
3
4
5
6
7
8
9
10
#MyWindowsService.py

console_session_id = win32ts.WTSGetActiveConsoleSessionId()
console_user_token = win32ts.WTSQueryUserToken(console_session_id)

my_app_path= os.path.normpath(r"/Path\\to\\MyApp.exe")
startup = win32process.STARTUPINFO()
priority = win32con.NORMAL_PRIORITY_CLASS
environment = win32profile.CreateEnvironmentBlock(console_user_token, False)
handle, thread_id ,pid, tid = win32process.CreateProcessAsUser(console_user_token, my_app_path, None, None, None, True, priority, environment, None, startup)