C# запуск приложения Windows Form из службы (и в Vista)



Я пишу приложение на C#, которое должно работать как Служба, но также иметь взаимодействие с пользователем. Я понимаю, что службы не имеют пользовательского интерфейса и т. д., Поэтому я разделил свою программу на приложение windows form и службу, которые могут взаимодействовать друг с другом.



Проблема, с которой я сталкиваюсь, заключается в том, что мне нужна Служба, чтобы убедиться, что приложение windows form всегда работает и перезапустить его, если это не так. Я могу определить, работает ли он, и перезапустить его со следующим кодом Windows 2000 / XP:



System.Diagnostics.Process.Start("ExePath");


Но в Vista он запускает новый процесс как локальный / системный процесс, который невидим для пользователя. Кто-нибудь может обойти это? Есть ли способ определить, какой пользователь в данный момент вошел в систему, и запустить новый процесс от имени этого пользователя? Мне не нужно учитывать быстрое переключение пользователей в этот момент. Чего - то-чего угодно-основного будет достаточно.

Я был бы признателен за любую помощь или советы, которые у вас есть по этому вопросу.

Мне нужно уточнить, что я устанавливаю параметр "Разрешить службе взаимодействовать с рабочим столом" при установке службы. Это то, что позволяет ему работать на 2000/XP. Однако у Vista все еще есть вышеупомянутая проблема.

958   8  

8 ответов:

Общая идея для такого рода вещей заключается в том, что если пользователю необходимо взаимодействовать с сервисом, он должен запустить отдельное приложение. Если вы хотите помочь им, вы можете настроить это отдельное приложение для запуска с windows, поместив ярлык в меню Пуск. Вы также можете встроить аварийное восстановление в свое приложение, чтобы оно могло автоматически перезапускаться.

Вы не должны полагаться на мониторинг приложения forms, что делать, если никто не вошел в систему? Что делать, если несколько человек вы вошли в систему? Это просто становится грязным делать вещи таким образом.

То, что Служба просто сидит там и вещает слушателям, - это путь. Когда приложение forms запускается, оно может уведомить службу, которая хочет прослушивать события.

См. Вопрос: Как служба Windows может выполнить приложение с графическим интерфейсом?. Он обращается к тому же вопросу из C / C++ (краткий ответ: CreateProcessAsUser), но ответ все еще действителен (с некоторыми P/Invoke) для C#.

В этом случае вы должны будете иметь третий процесс монитора, который обнаруживает, если программа выходит из строя и перезапустить его в этом случае.

Однако здесь вы сталкиваетесь с неразрешимой проблемой, так как за процессом монитора нужно следить, чтобы он не был выключен, и так далее, и так далее, и так далее.

Возможно, вы захотите пересмотреть этот подход.

Это сложная ситуация. Как упоминалось в нескольких местах, если вы должны иметь пользовательский интерфейс, то технически вы не должны использовать сервис. В конце концов, службы работают даже без входа пользователя в систему. Если никто не вошел в систему, у вас не может быть пользовательского интерфейса.

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

В вашем случае я бы использовал очередь. Когда пользователь входит в систему, вы можете автоматически запустить приложение для них, которое отслеживает очередь. Если приложение запущено, то при получении сообщения они также получают предупреждение. Однако если пользователь закрывает приложение, то происходит то же самое... они ничего не узнают.

Во-первых, быстрый ответ: позволяет ли опция "разрешить службе взаимодействовать с рабочим столом" (service - > Properties - > LogOn) или указание учетной записи разрешить то, что вы хотите? Если да,то оба эти параметра можно настроить в классе установщика служб.

Как и другие, я подозреваю, что есть лучший подход к этому, и либо одно из следующих верно: - Код внутри службы может быть включен в приложение winforms (возможно, запущенное в фоновом режиме) и добавлен при запуске windows. Оба будут работать - Приложение winforms может просто слушать службу, когда она включена, и не нуждается в запуске из службы. Или аналогично, приложение может быть добавлено в автозагрузку.

Чтобы ваша служба запустила приложение от имени пользователя (что, похоже, вы и пытаетесь сделать), вам нужно сделать следующее:

System.Security.SecureString ss = new System.Security.SecureString();

foreach (char c in password)
  ss.AppendChar(c);

System.Diagnostics.Process proc = Process.Start(path, arguments, username, ss, domain);

Где:

  • path = полный путь (включая имя файла) к исполняемому файлу.
  • аргументы = строка аргументов (использовать пустую строку-нет)
  • username = имя учетной записи Пользователя на вашем сервере / компьютере
  • домен = ваш сетевой домен (если вы используете сетевую учетную запись-пусто, если нет)

Также по порядку чтобы ваша служба имела разрешение на запуск приложения, она также должна работать как служба. Для этого необходимо добавить следующие строки в класс установщика служб:

serviceProcessInstaller.Account = ServiceAccount.User;

serviceProcessInstaller.Username = "yourdomain\\yourAccountName"; //Or just "AccountName" for local accounts..            

serviceProcessInstaller.Password = "yourPassword";

В Windows 2000 и XP есть опция (флажок) на вкладке вход в систему окна Свойства службы, чтобы позволить службе взаимодействовать с рабочим столом. Я верю, что это то, что вы ищете. Я только что написал краткое обслуживание в VB.NET с помощью процесса.Начало ("calc.exe") и калькулятор Windows открылся просто отлично.

Я не уверен на 100%, что это работает так же, как в Vista.

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

Comments

    Ничего не найдено.