Как настроить службу Windows в коде для доступа к рабочему столу? - PullRequest
3 голосов
/ 22 декабря 2009

Я создал службу Windows. Я хочу открыть приложение для Windows на основе этого сервиса.

Но мой Windows-сервис не может запускать настольные приложения. Чтобы включить доступ, мне пришлось сделать следующие шаги:

  1. Открыт административный инструмент "Услуги"

  2. Щелкните правой кнопкой мыши по моему сервису и пришлось выбрать «свойства»

  3. Затем на вкладке «Вход в систему» ​​выберите «Разрешить сервису взаимодействовать с рабочим столом».

После этого мой сервис может открывать нужные процессы на базе Windows.

Могу ли я настроить свою службу Windows в коде (C #) для доступа к рабочему столу, чтобы мне не пришлось изменять разрешение доступа вручную после установки?

Ответы [ 2 ]

3 голосов
/ 22 декабря 2009

Просто ... не надо. Это не работа службы. Для этой работы вы должны использовать пользовательское приложение (возможно, при его запуске), которое (при необходимости) общается со службой через IPC. Я считаю план состоит в том, чтобы в какой-то момент сделать пользовательский интерфейс недоступным для служб (в Vista и далее? Я перестал обслуживать <=> рабочий стол долго давно).

Для рассмотрения:

  • что делать, если в систему вошли несколько пользователей (быстрое переключение пользователей)?
  • что если у вас несколько сеансов RDP?

То, что вы предлагаете, в действительности масштабируется только до 1, и, возможно, не случится так, что, если учесть, что «сессия 0» зарезервирована для использования администратором в некоторых системах (поэтому интерактивный пользователь не обязательно обязательно в сессия 0).

3 голосов
/ 22 декабря 2009

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