【问题标题】:Windows Services can't create subprocesses?Windows 服务无法创建子进程?
【发布时间】:2017-11-10 18:27:35
【问题描述】:

我正在编写一个 Python 脚本,它必须在 Windows 系统上运行一些命令。我选择的方式是使用subprocess.Popen,因为我需要捕获和管道一些输出。我已经编译好了,当我手动运行.exe 时一切正常。

该脚本被认为在每次系统启动时都会运行,因此我创建了一个执行它的 Windows 服务,这就是问题出现的时候。基本上,它可以运行并且可以做一些其他的事情,所以服务创建成功,但无法创建子进程并执行其上的命令。

因为我手动运行它时它运行良好,所以我假设代码中没有错误,并且问题与 Windows 服务有关。也许它不能创建子子进程?有人收到了吗?

【问题讨论】:

  • 最初一个工作站有两个会话。会话 0 用于服务,会话 1 用于第一次交互式登录。会话包含 WindowStation 对象,其中包含桌面对象,其中包含用户对象,例如窗口。每个 Session 都有一个名为“WinSta0”的 WindowStation,它是唯一允许与 Session 用户交互的窗口。最初,它有一个用于登录和 UAC 同意的安全“Winlogon”桌面,以及一个用于 shell 的“默认”桌面。
  • Session 0 WinSta0 但是,是非交互式的,而且每个服务进程都使用为其 LSA 登录会话创建的 WindowStation。因此,服务不能简单地通过subprocess.Popen(即CreateProcess)以常规方式创建交互过程。可以通过WTSGetActiveConsoleSessionId查询当前附加到物理控制台的Session,或者通过WTSEnumerateSessions找到一个活跃的Session(包括远程会话)。如果您想在另一个 Session 中启动一个进程,请通过WTSQueryUserToken 为其获取一个 Token,并通过CreateProcessAsUser 创建该进程。

标签: windows python-2.7 service popen


【解决方案1】:

我遇到了同样的问题(在 Windows Server 2012 R2 上),并且真的不想深入到 Win32 API 调用的级别来让我的(GUI 应用程序运行而不关心 GUI 上的内容)exe on正确的会话桌面。但是,我确实注意到我们有另一个进程正常运行,作为 MSBuild 脚本的一部分。

我想出的解决方法是生成一个非常简单的 msbuild 文件来执行我想要启动的进程并运行它。似乎运行良好,但如果您需要将系统管道输入/输出 .exe,可能会不高兴。

没有工作:

subprocess.call("MyExe.exe")

有效:

with open("temp.msbuild", "w") as mb:
    mb.write('<?xml version="1.0" encoding="utf-8" ?>\n')
    mb.write('<Project DefaultTargets="Run" xmlns="' 
             + 'http://schemas.microsoft.com/developer/msbuild/2003'
             + '">\n')
    mb.write('  <Target Name="Run">\n')
    mb.write('    <Exec Command="MyExe.exe"\>\n')
    mb.write('  </Target>\n')
    mb.write('</Project>\n')
subprocess.call("msbuild temp.msbuild")
os.remove("temp.msbuild")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    相关资源
    最近更新 更多