如何在代码中配置我的 windows 服务以访问桌面?
Posted
技术标签:
【中文标题】如何在代码中配置我的 windows 服务以访问桌面?【英文标题】:How can I configure my windows service in the code to access the desktop? 【发布时间】:2010-12-29 01:36:46 【问题描述】:我创建了一个 Windows 服务。我想从此服务中打开一些基于 Windows 的应用程序。
但我的 Windows 服务无法启动桌面应用程序。要启用访问权限,我必须执行以下步骤:
打开了管理工具“服务”
右键单击我的服务,必须选择“属性”
然后在“登录”选项卡中,选择“允许服务与桌面交互”。
之后我的服务可以打开所需的基于窗口的进程。
我可以在代码(C#)中配置我的windows服务来访问桌面,这样我就不必在安装后手动更改访问权限了吗?
【问题讨论】:
【参考方案1】:只是...不要。这不是服务的工作。对于这项工作,您应该使用一个用户应用程序(可能在他们的启动中),该应用程序(如有必要)与通过 IPC 与服务进行通信。我相信计划是在某个时候使 UI 无法从服务中使用(从 Vista 开始?我在 很久 之前就停止了服务桌面)。
注意事项:
如果您有多个用户登录(快速用户切换)怎么办? 如果您有多个 RDP 会话怎么办?您所提议的内容仅真正扩展到 1,如果您认为“会话 0”在某些系统上保留供管理员使用(因此交互式用户不是必要在会话 0)。
【讨论】:
我不同意。当通过服务自动化应用程序时,必须为某些应用程序设置允许桌面访问的标志(例如,当唯一的交互方式是通过剪贴板时)。当然,扩展可能是个问题,但不能扩展的解决方案通常总比没有解决方案好(因为可扩展性并不总是必需的)。 那么:不要通过服务自动化应用程序。在用户会话中使用与服务交谈的应用。我在上面的答案中说过。这可能是一个稍微复杂的解决方案,但它是正确的解决方案。 我不会说一件事是对的,另一件事是错的。考虑使用现有应用程序执行诸如自动打印/转换文档之类的任务的服务。通常你不能让应用程序(MS Office、OpenOffice、旧版 WordPerfect 等)监听服务。当一切都由您的服务控制时,您甚至可以并行创建多个会话,而完全不需要交互式用户,因此它非常适合在服务器上运行。当然,命令行工具更适合此类工作,但您并非总是可以选择。 我会:在这里看到“重要”:msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx 但这是关于显示用户界面的服务。那是另一个故事,显然不是。【参考方案2】:在 .NET 中,您可以覆盖服务安装程序类的 OnCommited
方法来配置服务以访问桌面。代码如下所示:
[RunInstaller(true)]
public partial class ProjectInstaller : Installer
private ServiceProcessInstaller serviceProcessInstaller;
private ServiceInstaller serviceInstaller;
public ProjectInstaller()
InitializeComponent();
// adjust configuration to whatever is needed
serviceInstaller = new ServiceInstaller();
serviceInstaller.ServiceName = "My Service";
serviceInstaller.DisplayName = "My Service";
serviceInstaller.StartType = ServiceStartMode.Manual;
this.Installers.Add(serviceInstaller);
serviceProcessInstaller = new ServiceProcessInstaller();
serviceProcessInstaller.Account =
System.ServiceProcess.ServiceAccount.LocalSystem;
serviceProcessInstaller.Password = null;
serviceProcessInstaller.Username = null;
this.Installers.Add(serviceProcessInstaller);
protected override void OnCommitted(IDictionary savedState)
base.OnCommitted(savedState);
// The following code sets the flag to allow desktop interaction
// for the service
//
using (RegistryKey ckey =
Registry.LocalMachine.OpenSubKey(
@"SYSTEM\CurrentControlSet\Services\My Service", true))
if (ckey != null && ckey.GetValue("Type") != null)
ckey.SetValue("Type", (((int)ckey.GetValue("Type")) | 256));
【讨论】:
重新对/错;在这里看到“重要”:msdn.microsoft.com/en-us/library/ms683502(VS.85).aspx 感谢 Marc Gravell。不错的文章,也是实现需求的简单方法。但是现在我的上级不允许我改变结构,这就是我试图解决这个问题的原因。 现在我向您解释我的服务是如何工作的,以便您了解我的要求。我的应用程序处理文档。为了完成这项任务,我使用了一些 3rd 方工具,如 adobe 和 Zprint。有时我们会得到这些 3rd 方工具无法处理的文件,所以我的应用程序在这种情况下挂了。我的服务将监视该过程,如果应用程序挂起,则服务关闭应用程序并重新启动。所以在这里我的服务与我的应用程序以这种方式相交。以上是关于如何在代码中配置我的 windows 服务以访问桌面?的主要内容,如果未能解决你的问题,请参考以下文章
在 Ubuntu 上配置 SFTP 服务器以使用 PhpStorm 远程访问