Windows服务如何执行GUI应用程序?
我写了一个Windows服务,允许我远程运行和停止应用程序。 这些应用程序使用CreateProcess运行,这对我来说很有用,因为它们大多数只执行后端处理。 最近,我需要运行向当前login用户呈现GUI的应用程序。 如何在C ++中编写代码以允许我的服务find当前活动的桌面并在其上运行GUI?
Roger Lipscombe的回答是,使用WTSEnumerateSessionsfind正确的桌面,然后CreateProcessAsUser在该桌面上启动应用程序(将其作为STARTUPINFO结构的一部分传递给桌面的句柄)是正确的。
不过,我强烈build议不要这样做。 在一些环境中,比如terminal服务器主机上有许多活跃的用户,确定哪个桌面是“主动”的是不容易的,甚至可能是不可能的。
但最重要的是,如果一个应用程序突然出现在用户的桌面上,这可能会发生在一个糟糕的时间(或者是因为用户根本没有期望它,或者是因为你正在尝试启动应用程序,当会话不是还没有初始化,在closures的过程中,或者其他什么)。
更传统的方法是在全球启动组中为您的服务添加一个小型客户端应用程序的快捷方式。 这个应用程序随后将随每个用户会话一起启动,并可用于启动其他应用程序(如果需要的话),而不需要任何用户证书,会话和/或桌面的杂耍。
而且,这个快捷方式可以根据需要由pipe理员移动/禁用,这将使应用程序的部署变得更容易,因为它不会偏离其他Windows应用程序所使用的标准。
简短的回答是“你不要”,因为打开在另一个用户上下文中运行的GUI程序是一个安全漏洞,通常称为“ 破碎攻击”(Shatter Attack) 。
看看这个MSDN文章: 交互式服务 。 它提供了一些服务与用户交互的选项。
总之你有这些select:
-
在用户的会话中使用WTSSendMessage函数显示一个对话框。
-
创build一个单独的隐藏的GUI应用程序,并使用CreateProcessAsUser函数在交互式用户的上下文中运行应用程序。 deviseGUI应用程序通过进程间通信(IPC)的某种方法与服务进行通信,例如命名pipe道。 该服务与GUI应用程序通信以告诉它何时显示GUI。 应用程序将用户交互的结果传回服务,以便服务可以采取适当的措施。 请注意,除非使用适当的访问控制列表(ACL),否则IPC可以通过networking公开您的服务接口。
如果此服务在多用户系统上运行,请将该应用程序添加到以下registry项,以便在每个会话中运行:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run。 如果应用程序使用IPC的命名pipe道,则服务器可以通过为每个pipe道根据会话ID指定一个唯一的名称来区分多个用户进程。
WTSEnumerateSessions和CreateProcessAsUser。
有几个人提出了WTSEnumerateSessions和CreateProcessAsUser。 我想知道为什么没有人build议WTSGetActiveConsoleSessionId,因为你说你只想定位一个login用户。
虽然有几个人确定是正确的build议CreateProcessAsUser。 如果按照您所说的方式调用普通的CreateProcess,那么应用程序的GUI将以您的服务的特权而不是用户的特权运行。
这个问题会话0,交互式服务,Windows服务允许服务与Windows 7或Windows Vista上的桌面进行交互
你可以阅读这篇文章http://www.codeproject.com/KB/vista-security/SubvertingVistaUAC.aspx
我尝试在这里解释它在Windows 7上工作
在Win2K,XP和Win2K3上,控制台用户在会话0中login,这是服务所在的会话。如果服务configuration为交互式,则可以在用户的桌面上显示用户界面。
但是,在Vista上,没有用户可以在会话0中login。从服务中显示UI有点棘手。 您需要使用WTSEnumerateSessions API枚举活动会话,find控制台会话并以该用户身份创build该进程。 当然,你也需要一个令牌或用户凭证才能做到这一点。 你可以在这里阅读关于这个过程的更多细节。
我想只要你只有一个用户login,它会自动显示在用户的桌面上。
无论如何,当服务启动一个EXE时要非常小心。
如果对exe文件夹的写入访问权限不受限制,任何用户都可以用其他程序replace该exe文件,然后使用系统权限运行该程序。 以cmd.exe为例(所有的Windows系统都可用)。 下一次该服务试图启动您的exe文件,你会得到一个系统权限的命令shell…
如果从服务启动GUI,它将显示在当前活动的桌面上。
但是,只有当您调整服务权限时:您需要允许它与桌面进行交互 。
重要服务从Windows Vista开始,不能直接与用户交互。 因此,标题为“使用交互式服务”一节中提到的技术不应在新代码中使用。
这取自: http : //msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx