Как служба Windows может запустить процесс при возникновении события Timer? - PullRequest
7 голосов
/ 23 декабря 2010

Я создал службу Windows с таймером, а в случае запуска timer.Elapsed я создаю процесс (System.Diagnostics.Process.Start(exe path)) с интервалом в 5 секунд.Но этот процесс не создается при запуске события.

Есть ли другой способ сделать это?

Заранее спасибо.

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{       

    Process pr = new Process();
    pr.StartInfo.FileName = @"C:\Program Files\Messenger\msmsgs.exe";
    pr.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
    pr.StartInfo.CreateNoWindow = false;
    pr.Start();
}

Ответы [ 4 ]

19 голосов
/ 23 декабря 2010

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

То, что вы пытаетесь выполнить, называется "Интерактивная служба" , которая позволяет напрямую взаимодействовать с пользователем и рабочим столом (т. Е. Показывать окно или диалоговое окно). ).
Если вы используете Windows XP (и ваша служба будет работать только под когда-либо под Windows XP), вы можете следовать инструкциям в этой статье, чтобы запустить службу в интерактивном режиме, который позволит вам отображать окно приложения Adobe Acrobat, как вы ожидаете. Однако, как также указывается в этой документации, эта функция не работает в Windows Vista и более поздних версиях:

Важно Службы не могут напрямую взаимодействовать с пользователем начиная с Windows Vista. Поэтому методы, упомянутые в разделе «Использование интерактивного сервиса» не должен использоваться в новом коде.

Более конкретно, в этих версиях были внесены изменения в работу служб и приложений. Сервисы теперь изолированы системой в сеансе 0, а приложения запускаются в других сеансах. Это предназначено для изоляции сервисов от атак, которые происходят в коде приложения. Следовательно, ни один пользовательский интерфейс, отображаемый службой, никогда не будет виден любому пользователю системы, включая простое окно сообщения. Вы можете прочитать официальный документ, который объясняет эти изменения более подробно здесь . Если вы более визуальный человек, обратитесь к следующей диаграмме, иллюстрирующей новую модель, уделяя особое внимание разделительным линиям:

Windows process isolation model under Windows Vista/7

В результате вы можете использовать эту лазейку, если вы нацеливаетесь на эти версии или вам когда-нибудь понадобится нацелиться на эти версии. Я говорю «лазейка», потому что, как я уже упоминал в комментарии, суть в том, что Службы Windows не предназначены для того, чтобы быть интерактивными . То, что вы пытаетесь сделать здесь, противоречит цели и дизайну сервиса. Раньше это не рекомендовалось, и теперь оно совершенно не работает. Если вам нужна эта конкретная функциональность, вы должны создать приложение другого типа. Windows Forms и WPF предназначены для приложений пользовательского режима, и оба могут запускать процессы и открывать новые окна по мере необходимости. Я настоятельно рекомендую вместо этого перейти на этот стиль приложения.

0 голосов
/ 12 августа 2015

Есть обходной путь, но я бы посоветовал сделать это, только если ВЫ УВЕРЕНЫ, ЧТОБЫ ПРИНЯТЬ ВОПРОС БЕЗОПАСНОСТИ!

Это может быть ответом на вашу проблему: CreateProcessAsUser .

Пример демонстрирует, как интерактивно создавать / запускать процесс в сеансе вошедшего в систему пользователя из приложения-службы, написанного на C # .Net.

0 голосов
/ 10 июля 2015

Я понимаю, что немного опоздал на эту вечеринку. Но так как этот вопрос возник в моем поиске решения, я дам ответ на вопрос ОП.

Вы можете запустить программу из службы, используя CreateProcessAsUser, используя токен вошедшего в систему пользователя. MSDN предоставляет хороший пример приложения, демонстрирующего это; ищите CSCreateProcessAsUserFromService: https://code.msdn.microsoft.com/windowsapps/CSCreateProcessAsUserFromSe-b682134e#content

Я попробовал, и это работает. Я могу создать новый процесс для моего существующего приложения .NET из службы, и он работает просто отлично. Я установил свойства входа службы в локальную системную учетную запись, но оставил флажок «Разрешить службе взаимодействовать с рабочим столом». Мое приложение создается по истечении времени таймера и работает так же, как и при обычном запуске, включая представление в графическом интерфейсе и взаимодействие с пользователем.

Является ли это неправильным или нежелательным занятием, - это другое обсуждение. Но это действительно возможно, и на самом деле не так уж и сложно.

0 голосов
/ 23 декабря 2010

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

...