我正在使用第三方 Windows 服务,该服务通过使用 CreateProcessAsUser() 运行脚本和可执行文件来处理一些自动化任务。由于 UAC 以及通过 API 处理 LUA 提升的方式,我在 Windows Server 2008 上遇到了问题。
该服务作为 LocalSystem 运行,并且没有启用“与桌面交互”。这些进程作为管理员组中的用户运行,但不是管理员帐户(不受许多 UAC 限制)。所有 UAC 的默认设置都已到位。
我可以将任意命令或 powershell 代码传递给服务,但我似乎无法“突破”由服务启动的非提升、非交互式进程。
问题的症结似乎是启动提升进程的唯一(公共)API 选项是带有“runas”动词的 ShellExecute(),但据我所知,不能从非交互式调用服务,否则您会收到诸如“此操作需要交互式窗口站”之类的错误。
我发现的唯一解决方法在这里提到: http ://www.eggheadcafe.com/software/aspnet/29620442/how-to-proper-use-sendinp.aspx
在 Vista 中,官方记录的提升进程的方法是仅使用 shell API ShellExecute(Ex)(不是 CreateProcess 或 CreateProcessAsUser)。所以你的应用程序必须调用 ShellExecute(Ex) 来启动一个提升到调用 SendInput 的助手。此外,由于 Session 0 隔离,服务只能使用 CreateProcessAsUser 或 CreateProcessWithLogonW(不能使用 ShellExecute(Ex))来指定交互式桌面。
..我认为没有直接的方法可以从 Windows 服务中生成提升的进程。我们只能首先使用 CreateProcessAsUser 或 CreateProcessWithLogonW 在用户会话(交互式桌面)中生成一个非提升的进程。然后在非提升的进程中,它可以使用 ShellExecute(Ex) 为实际任务生成提升的进程。
要从 .net/powershell 代码执行此操作,看起来我必须做一些复杂的 P/Invoke 操作才能调用 CreateProcessAsUser 或 CreateProcessWithLogonW,因为 .Net System.Diagnostics.ProcessStartInfo 没有我可以使用的 lpDesktop 等价物设置为“winsta0\default”。而且我不清楚 LocalSystem 是否甚至有权调用 CreateProcessAsUser 或 CreateProcessWithLogonW。
我还查看了 http://blogs.msdn.com/alejacma/archive/2007/12/20/how-to-call-createprocesswithlogonw-createprocessasuser-in-net.aspx 和 Process.Start 与 UAC 不同的凭据
基于所有这些,我得出的结论是,没有直接的方法可以做到这一点。我错过了什么吗?这似乎真的不应该那么难。感觉就像 UAC 从未设计用于处理非交互式用例。
如果有任何 Microsoft 人员最终阅读了这篇文章,我注意到 ShellExecute 在内部处理提升的方式是调用应用程序信息服务 (AIS)。为什么不能通过某些 Win32 或 .NET API 对 AIS 进行相同的调用? http://msdn.microsoft.com/en-us/library/bb756945.aspx
抱歉,运行时间有点长。感谢您的任何想法。