发布网友 发布时间:2024-10-18 21:49
共1个回答
热心网友 时间:2024-10-24 06:46
典型情况下,服务是那些被设计没有图形用户界面的无人控制的控制台应用程序。但是,一些服务可能需要与用户偶尔进行交互。这个页面讨论了从服务与用户进行交互的最好方法。
截至Windows Vista,服务不能与用户直接进行交互。(注:意义为在Windows Vista前都可以)然而,在标题为“使用交互服务”一节中提到的方法不应该在新的代码中被使用。(注:仅为了兼容) 你可以使用下列技术来从运行于所有版本Windows的服务与用户进行交互:
1、通过使用WTSSendMessage 来在用户的会话中弹出对话框。(注:对话框实际属于指定会话的csrss.exe,可以使用WTSGetActiveConsoleSessionId 来获得当前活动会话号)
2、创建一个的隐藏GUI应用(注:指不显示界面)并使用CreateProcessAsUser函数来在活动用户上下文中运行应用程序。将GUI应用程序设计为通过一些进程间通信(IPC)方法,比如命名管道,与服务通信。服务与GUI应用交流以告诉它(GUI应用)何时显示GUI。应用程序将与用户的交互结果回复给服务,服务由此可以进行适当的操作。注意IPC可能将服务接口暴露在网络上,除非你使用适当的ACL。
如果服务运行在一个多用户系统,将应用程序(注:指GUI应用)添加在下列键中由此它可以运行在每一个会话中:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run。如果应用为IPC使用命名管道,服务器可以通过给每一个管道基于会话ID的唯一名字区分出每一个用户的进程
下列技术在Windows Server 2003与Windows XP中也有效:
通过调用包含MB_SERVICE_NOTIFICATION的MessageBox显示一个信息盒子。这是显示简单状态信息的推荐方法。不要在服务的初始化中或从HandlerEx例行程序中调用MessageBox,除非你从一个单独的线程中调用,由此你可以在及时方法中返回服务控制管理(SCM,Services Control Manager)。 默认情况下,服务使用不交互窗口站并无法与用户交互。然而,一个交互式服务可以显示用户界面并接受用户输入。
注意:服务运行在更高的安全上下文中,例如LocalSystem账户,不应该在活动桌面创建窗口,因为在交互桌面运行的其他应用可以与此窗口交互。这将将服务暴露于登陆的用户运行的一切应用程序中。类似的,作为LocalSystem登陆的服务不应该使用OpenWindowStation或GetThreadDesktop函数使用当前桌面
为了添加交互式服务,用以下方法调用CreateService函数:
1.使用NULL作为lpServiceStartName的参数值以将服务运行为LocalSystem账户上下文。
2.使用SERVICE_INTERACTIVE_PROCESS。
为了测试服务是否作为交互式服务运行,调用GetProcessWindowsStation函数来去的窗口站的句柄,并使用GetUserObjectInformation函数测试窗口站是否有WSF_VISIBLE属性。
然而,注意下列注册表键包含的NoInteractiveServices,那控制了SERVICE_INTERACTIVE_PROCESS的作用效果:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows
NoInteractiveServices的值默认为1,那意味着没有服务被允许交互式运行,无论它是否有SERVICE_INTERACTIVE_PROCESS。当NoInteractiveServices被设为0,有SERVICE_INTERACTIVE_PROCESS的服务被允许交互式运行。
对于Windows7, Windows Server 2008 R2, WindowsXP和Windows Server2003,NoInteractiveServices的值默认为0,这意味着使用SERVICE_INTERACTIVE_PROCESS的服务被允许交互式运行。当NoInteractiveServices被设为非0值,没有服务在那之后允许被以交互式运行,无论它是否有SERVICE_INTERACTIVE_PROCESS
重要:所有的服务都在终端服务的0号会话(Terminal Services session 0)运行。然而,如果一个交互式服务(interactive service,注册SERVICE_INTERACTIVE_PROCESS)显示了一个用户界面(user interface,UI),它只对连接到0号会话(session 0)的用户可见。因为没有方法保证交互式用户(interactive user,LogonUser时使用LOGON32_LOGON_INTERACTIVE)连接到0号会话,不要将一个服务设置为在终端服务或在支持快速用户切换(fast user switching)的系统下运行的交互式服务。(快速用户切换是通过终端服务实现的)