How can I configure my windows service in the code

2019-02-11 03:14发布

I have created an windows service. I want to open some windows based application from this service.

But my windows service is unable to start desktop applications. To enable the access I had to do the following steps:

  1. Opened the administrative tool "Services"

  2. Right clicked on my service and had to select "properties"

  3. Then in the "Log On" tab, selected "Allow service to interact with desktop".

After that my service can open desired windows based processes.

Can I configure my windows service in the code (C#) to access the desktop so that I won't have to change the access permission manually after installation?

2条回答
仙女界的扛把子
2楼-- · 2019-02-11 03:21

In .NET you can override the OnCommited method of the service installer class to configure the service to access the desktop. The code will look as follows:

[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));
            }
        }
    }
}
查看更多
甜甜的少女心
3楼-- · 2019-02-11 03:29

Just... don't. That isn't the job of a service. For this job you should be using a user app (perhaps in their startup) that (if necessary) talks to a service via IPC. I'm believe the plan is to make the UI unavailable from services at some point (Vista onwards? I stopped doing service<=>desktop a long time ago).

For considerations:

  • what if you have multiple users logged in (fast user switching)?
  • what if you have multiple RDP sessions?

What you are proposing only really scales to 1, and possibly not event that if you consider that "session 0" is reserved for admin use on some systems (so the interactive user isn't necessarily on session 0).

查看更多
登录 后发表回答