Определить, работает ли код как служба - PullRequest
7 голосов
/ 05 января 2009

Есть ли способ для библиотеки .NET определить, запускается ли она как служба?

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

Ответы [ 7 ]

12 голосов
/ 07 октября 2009

После долгих поисков в intellisense, отладчике и документации мы не смогли найти ничего строго надежного. Может быть возможно получить текущий идентификатор процесса и попытаться выяснить, зарегистрирован ли этот процесс в SCM, но, хотя .NET предоставляет способ получения набора всех служб, их идентификаторы процессов не входят в число доступной информации. Сравнение имени процесса с именами служб возможно, но не обязательно надежно.

Тем не менее, есть две вещи, которые относительно легко проверить и которые могут быть достаточными для разницы, которая вам нужна, если не совсем «Этот код работает как служба?»

<a href="http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx" rel="nofollow noreferrer">System.Environment.UserInteractive</a>: (как заметил Стивен Мартин) Если это правда, это не может быть услуга. Большинство процессов, которые не являются службой (и не драйвером устройства), скажут true. Некоторые консольные приложения могут показывать false при запуске в неинтерактивных условиях, таких как часть процесса сборки.

<a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.process.getcurrentprocess.aspx" rel="nofollow noreferrer">System.Diagnostics.Process.GetCurrentProcess</a>().<a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.process.sessionid.aspx" rel="nofollow noreferrer">SessionId</a>: (я думаю, это то же самое, что и Пьер). Если это не 0, он не был запущен как сервис. Большинство нормальных приложений не будет в сеансе 0 (с некоторыми необычными исключениями, как отмечают Пьер и Стивен). Самый большой вопрос заключается в том, как это ведет себя в более старых ОС, таких как XP или раньше. XP и Windows 2000, очевидно, имеют службы, работающие в сеансе 0, но обычные приложения также будут в сеансе 0. Некоторые конфигурации XP (например, не в домене) допускают одновременное использование нескольких пользовательских сеансов, и каждый из них получает свой идентификатор сеанса, но первый получает сеанс 0. Таким образом, проверка до Vista не так эффективна.

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

5 голосов
/ 05 января 2009

Нет никакого способа узнать, работает ли ваша библиотека в контексте службы или нет, хотя вы можете использовать Environment.UserInteractive, чтобы сделать предположение.

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

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

РЕДАКТИРОВАТЬ: Я бы приветствовал комментарии на ваш вопрос, если бы мог. При необходимости используйте перегруженные методы и / или просто не работайте, если не предоставлена ​​вся необходимая информация.

2 голосов
/ 25 декабря 2011

Немного опоздал на вечеринку, но как насчет получения списка сервисов с помощью ServiceController.GetServices и сверки идентификатора вашего процесса с этими?

(«Как запустить идентификатор процесса службы Windows?»: http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/a979351c-800f-41e7-b153-2d53ff6aac29)

2 голосов
/ 09 февраля 2010

Быстрый и грязный способ - применить параметр командной строки к записи в реестре в папке HKLM \ System \ CurrentControlSet \ services \ MyService \ ImagePath , а затем проверить этот переключатель в основной функции.

Затем вы узнаете, был ли запущен services.exe или нет. Да, это взлом.

2 голосов
/ 05 января 2009

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

  [DllImport("kernel32.dll")]
  private static extern int WTSGetActiveConsoleSessionId();
1 голос
/ 24 мая 2010

Ответ от 0xA3 до на этот вопрос на самом деле содержит код C # для запроса SCM, так же, как Роб Паркер описывает в своем ответе.

1 голос
/ 06 января 2009

Один из способов - взглянуть на пользовательский контекст вашего приложения. Если вы видите, что он работает как пользователь «SYSTEM», то вы работаете как служба (или, по крайней мере, с разрешениями уровня обслуживания).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...