在python中使用CreateProcessAsUser不会将用户的环境传递给创建的进程

时间:2015-11-18 11:20:08

标签: python windows-services user-environment

首先感谢您抽出时间阅读这个问题。

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

#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%的路径:

#MyApp.py

user_app_data_path = os.getenv('APPDATA')

它应该返回:

C:\ Users \ 交互式用户名 \ AppData \ Roaming

但是返回的值是:

C:\的Windows \ system32 \设置\ systemprofile \应用程序数据\漫游

这意味着虽然MyApp.exe是在交互式用户的名称下启动的,但它获取了运行Windows服务的 SYSTEM 用户的环境。

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

非常感谢,

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

1 个答案:

答案 0 :(得分:2)

我找到了答案,以防任何人感兴趣:

根据this,如果未明确指定环境,则该进程将继承父项的环境。使用this可以获取环境并将其传递给CreateProcessAsUser。

只需按照以下代码中的环境字即可。

#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)