简体   繁体   中英

How can I configure my windows service in the code to access the desktop?

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?

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));
            }
        }
    }
}

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM