Работа программы как служба или как обычная программа
От: Dan123  
Дата: 23.09.10 20:05
Оценка:
Здравствуйте!

Во многих приложениях есть возможность запуска приложения как службы windows. Каким образом это реализуется?
В предыдущем проекте я создавал отдельно службу и отдельно WinForm программу (Монитор). С помощью Монитора
создавались и редактировались задачи, а служба выполняла эти задачи. Но сейчас возникла задача предоставить
пользователю решать самому хочет он пользоваться обычной программой или использовать ее как службу. Неужели надо
дублировать код. Т.е. если программа не используется как служба, то все делает Монитор, а если служба используется
то в Мониторе задействуется механизм работы со службой? Но в основном это будет дублированный код.

Хочу рассмотреть это на примере. Допустим стоит задача создать программу, которая будет делать архивные копии файлов на диске.
1-й вариант — это обычная программа. Пользователь запустил ее, создал задачу какие файлы куда и когда копировать, свернул в трей и программа выполняет свою
работу.
2-вариант — пользователь захотел, чтобы программа работала как служба. Т.е. чтобы создавать и изменять задачи по копированию файлов он должен зайти
в систему и запустить графический интерфейс. А выполнять эти задачи будет уже служба, причем делать она это начнет еще до авторизации пользователя в системе.
Как осуществляется такая возможность переключения между этими двумя вариантами?

Еще один нюанс. Допустим перед началом копирования требуется запустить какую-нибудь другую программу. В первом варианте с этим нет проблем. А во втором насколько я знаю это невозможно, т.к. нельзя из службы запустить программу с графическим интерфейсом.

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

Как реализуется такой механизм?
Re: Работа программы как служба или как обычная программа
От: Lloyd Россия  
Дата: 23.09.10 20:31
Оценка:
Здравствуйте, Dan123, Вы писали:

D>Во многих приложениях есть возможность запуска приложения как службы windows. Каким образом это реализуется?

D>В предыдущем проекте я создавал отдельно службу и отдельно WinForm программу (Монитор). С помощью Монитора
D>создавались и редактировались задачи, а служба выполняла эти задачи. Но сейчас возникла задача предоставить
D>пользователю решать самому хочет он пользоваться обычной программой или использовать ее как службу. Неужели надо
D>дублировать код. Т.е. если программа не используется как служба, то все делает Монитор, а если служба используется
D>то в Мониторе задействуется механизм работы со службой? Но в основном это будет дублированный код.

Откуда дублирование возьмется? В случае сервиса ты в OnStart-те будешь пускать поток, который будет ожидать команды и передавать их обработчику. В случае консольой программы — просто парсить параметры и также передавать их на обработку. Никакого дублирования вроде как не предвилится.

D>Хочу рассмотреть это на примере. Допустим стоит задача создать программу, которая будет делать архивные копии файлов на диске.

D>1-й вариант — это обычная программа. Пользователь запустил ее, создал задачу какие файлы куда и когда копировать, свернул в трей и программа выполняет свою
D>работу.
D>2-вариант — пользователь захотел, чтобы программа работала как служба. Т.е. чтобы создавать и изменять задачи по копированию файлов он должен зайти
D>в систему и запустить графический интерфейс. А выполнять эти задачи будет уже служба, причем делать она это начнет еще до авторизации пользователя в системе.
D>Как осуществляется такая возможность переключения между этими двумя вариантами?

Я когда делал похожее, просто у сервиса в параметрах командной строки передавал параметр -service, говорящий, что программа запущена как сервис. Может быть есть более кошерные способы, не знаю.
Re[2]: Работа программы как служба или как обычная программа
От: Dan123  
Дата: 23.09.10 20:43
Оценка:
Спасибо за быстрый отклик! Просто для меня эта тема нова. Наверное я себе не совсем все правильно представляю, так что извиняюсь если вопросы буду глупые.

L>Откуда дублирование возьмется? В случае сервиса ты в OnStart-те будешь пускать поток, который будет ожидать команды и передавать их обработчику. В случае консольой программы — просто парсить параметры и также передавать их на обработку. Никакого дублирования вроде как не предвилится.


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

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


Не очень понятно. Служба это проект "Служба Windows" и она должна быть установлена как служба Windows. Служба запускается до авторизации пользователя в системе. Как все это можно разрулить с помощью командной строки?
Re[3]: Работа программы как служба или как обычная программа
От: Lloyd Россия  
Дата: 23.09.10 20:50
Оценка:
Здравствуйте, Dan123, Вы писали:

L>>Откуда дублирование возьмется? В случае сервиса ты в OnStart-те будешь пускать поток, который будет ожидать команды и передавать их обработчику. В случае консольой программы — просто парсить параметры и также передавать их на обработку. Никакого дублирования вроде как не предвилится.


D>Т.е. надо делать два варианта (службу и консольную программу)? Обе имеют одинаковый код, обе ждут команды на выполнение. Только запускается из них в зависимости от настроек или служба или консольная программа?


Зачем 2 программы-то? Не понимаю.

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


D>Не очень понятно. Служба это проект "Служба Windows" и она должна быть установлена как служба Windows. Служба запускается до авторизации пользователя в системе. Как все это можно разрулить с помощью командной строки?


Да, можно. Я же делал как-то.
Завтра до работы доберусь, посмотрю, как это делается.
Re: Работа программы как служба или как обычная программа
От: Jolly Roger  
Дата: 24.09.10 01:29
Оценка: 3 (1) +1
Здравствуйте, Dan123, Вы писали:

Возможно, Вас устроит SRVANY.EXE, подробности есть в MSDN. Сам я, правда, ей не пользовался, но народ вроде применяет.

Разница в запуске службы и обычного приложения в том, что служба при старте должна вызвать RegisterServiceCtrlHandler(Ex), установив связь с SCM. В NET в этот вызов попадаем через ServiceBase.Run. То есть при старте в виде обычного приложения нужно его просто не вызывать и экземпляры сервисов не создавать.

Но должен заметить, что вариант с раздельными приложениями всё-же лучше. А чтобы код не дублировать, можно использовать для него отдельную сборку.
"Нормальные герои всегда идут в обход!"
Re: Работа программы как служба или как обычная программа
От: shakm Россия  
Дата: 24.09.10 04:32
Оценка:
Ни какого дублирования!

1-я сборка — исполнитель твоих задач, которые, к примеру, считываются из xml
2-я сборка — WinForms приложение, с интерфейсом настройки задач. Сохраняет настройки, к примеру, в тот самый xml, который считывается исполнителем — 1ой сборкой. Эта же форма может выполнять методы 1-й сборки, когда пользователь не хочет пользоваться сервисом.
3-я сборка — Windows Service, который просто выполняет методы 1-ой сборки, которая считывает настройки из xml...
)

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

а вот на счет использования одного WinForms приложения, то:

Jolly Roger, Вы писали:
JR>Разница в запуске службы и обычного приложения в том, что служба при старте должна вызвать RegisterServiceCtrlHandler(Ex), установив связь с SCM. В NET в этот вызов попадаем через ServiceBase.Run. То есть при старте в виде обычного приложения нужно его просто не вызывать и экземпляры сервисов не создавать.

Не подскажете как? Как можно понять, что я запущен как сервис, а не как приложение? Пока я не нашел ответа. И запуск сервиса с параметром — тоже неизвестно, как это делается....
Re[2]: Работа программы как служба или как обычная программа
От: Jolly Roger  
Дата: 24.09.10 05:19
Оценка: 3 (1) +1
Здравствуйте, shakm, Вы писали:

S>Как можно понять, что я запущен как сервис, а не как приложение?


Документированного способа нет. Я использовал проверку результата RegisterServiceCtrlHandler(Ex). Если она вернула ошибку, значит SCM недоступен, а это означает, что стартуем как обычное приложение. Но на счёт применимости такого способа в DotNet надо отдельно разбираться.

S>И запуск сервиса с параметром — тоже неизвестно, как это делается....


В принципе, это описано в MSDN. Надо создать в реестре ключ
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<ИмяСлужбы>\Parameters
и эти параметры при старте сервиса будут переданы ему через аргументы ServiceMain, а в NET — в виртуальный метод ServiceBase.OnStart.
"Нормальные герои всегда идут в обход!"
Re[3]: Работа программы как служба или как обычная программа
От: shakm Россия  
Дата: 24.09.10 05:22
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, shakm, Вы писали:


S>>Как можно понять, что я запущен как сервис, а не как приложение?


JR>Документированного способа нет. Я использовал проверку результата RegisterServiceCtrlHandler(Ex). Если она вернула ошибку, значит SCM недоступен, а это означает, что стартуем как обычное приложение. Но на счёт применимости такого способа в DotNet надо отдельно разбираться.


S>>И запуск сервиса с параметром — тоже неизвестно, как это делается....


JR>В принципе, это описано в MSDN. Надо создать в реестре ключ

JR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<ИмяСлужбы>\Parameters
JR>и эти параметры при старте сервиса будут переданы ему через аргументы ServiceMain, а в NET — в виртуальный метод ServiceBase.OnStart.

Вот спасибки! Сам не нашел про реестр или тормознул совсем. Просто я тоже для упрощения управления сборками хотел все воткнуть в одну сборку. Но пока у меня все отлично работает так, как описал.
Re[4]: Работа программы как служба или как обычная программа
От: Jolly Roger  
Дата: 24.09.10 06:01
Оценка: 3 (1) +1
Здравствуйте, shakm, Вы писали:

Написал, потом засомневался и полез в код. В общем, соврамши я по беспамятству Ключ Parameters надо самому вычитывать из реестра, автоматически он не передаётся.
"Нормальные герои всегда идут в обход!"
Re[5]: Работа программы как служба или как обычная программа
От: shakm Россия  
Дата: 24.09.10 06:02
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, shakm, Вы писали:


JR>Написал, потом засомневался и полез в код. В общем, соврамши я по беспамятству Ключ Parameters надо самому вычитывать из реестра, автоматически он не передаётся.


Да, еще раз спасибо, не добрался пока до того кода, учту!
Re[6]: Работа программы как служба или как обычная программа
От: Jolly Roger  
Дата: 24.09.10 06:09
Оценка: 3 (1) +1
Здравствуйте, shakm, Вы писали:

S>Да, еще раз спасибо, не добрался пока до того кода, учту!


Заодно уж Параметры, которые доступны конкретной службе, можно передать через функцию SCM StartService. А параметры уровня приложения-контейнера служб можно добавить к ImagePath в конфигурации службы в реестре, и они будут доступны через аргументы метода Main приложения-контейнера.
"Нормальные герои всегда идут в обход!"
Re[7]: Работа программы как служба или как обычная программа
От: shakm Россия  
Дата: 24.09.10 06:35
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, shakm, Вы писали:


S>>Да, еще раз спасибо, не добрался пока до того кода, учту!


JR>Заодно уж Параметры, которые доступны конкретной службе, можно передать через функцию SCM StartService. А параметры уровня приложения-контейнера служб можно добавить к ImagePath в конфигурации службы в реестре, и они будут доступны через аргументы метода Main приложения-контейнера.


Все! Огромный спасиб! Все что написал, я попробовал и "о чудо, оно работает" !
Re: Работа программы как служба или как обычная программа
От: okman Беларусь https://searchinform.ru/
Дата: 24.09.10 06:53
Оценка:
Здравствуйте, Dan123, Вы писали:

...нельзя из службы запустить программу с графическим интерфейсом.

Можно. Хоть от имени пользователя, хоть от LocalSystem.
Нужно только присоединиться к интерактивному окружению.
Re[2]: Работа программы как служба или как обычная программа
От: shakm Россия  
Дата: 24.09.10 08:36
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Dan123, Вы писали:


O>...нельзя из службы запустить программу с графическим интерфейсом.


O>Можно. Хоть от имени пользователя, хоть от LocalSystem.

O>Нужно только присоединиться к интерактивному окружению.

А подробней? Что значит присоединиться? Пробовали? Мелкософт где то в документации пишет, что типа это плохое дело, не чистое, что так делать — чуть ли не хакерство. Так что, вы бы показали официальный способ, как это сделать из самого сервиса, и шоб это было санкционировано, и если што не работает, шоб можно было на мелкософт поругаться и поматериться и он после этого сделает заплатку ) Просто я не знаю...
Re[3]: Работа программы как служба или как обычная программа
От: HowardLovekraft  
Дата: 24.09.10 09:07
Оценка:
Здравствуйте, shakm, Вы писали:

S>А подробней? Что значит присоединиться?

About Window Stations and Desktops.
Re[4]: Ну и собственно про присоединение
От: HowardLovekraft  
Дата: 24.09.10 09:11
Оценка:
Process Connection to a Window Station.
Thread Connection to a Desktop.
Re[5]: Ну и собственно про присоединение
От: shakm Россия  
Дата: 24.09.10 09:29
Оценка: +1
Здравствуйте, HowardLovekraft, Вы писали:

HL>Process Connection to a Window Station.

HL>Thread Connection to a Desktop.

Это не ответ!
Сервису может быть не разрешено общаться с десктопом. И как тогда? Перечислить все WindowStaion, потом все Desktop. А если у тебя терминальный сервер с парой сотен пользователей? А если на серваке нет ни одного визуального десктопа, там стоят сервсисные службы. Кому ты выплюнешь окно? А откуда возьмешь права?
Зачем такие заморочки, если проще в .Net общаться через ремотинг, а в других средах — сеть, файлы, разделяемая память и мало ли что еще...

Ведь основная суть — информировать того, кому это нужно. Запускать что-то — не нужен десктоп. А кому нужно — должен сам подписаться на информирование. И тогда сервис его будет информировать.
Re[6]: Ну и собственно про присоединение
От: HowardLovekraft  
Дата: 24.09.10 09:41
Оценка: +1
Здравствуйте, shakm, Вы писали:

S>А если на серваке нет ни одного визуального десктопа

Что такое "визуальный декстоп"? Чем он отличается от "невизуального декстопа"?
S>если проще в .Net общаться через ремотинг
Ремоутинг — УГ. Особенно после выхода WCF.
S>Ведь основная суть — информировать того, кому это нужно
Ви таки пытаетесь убедить меня в том, что интерактивные сервисы — это плохо, а задача вывода на desktop не тривальна?
Не нужно, я сам избегаю создания интерактивных сервисов.

Однако, вы просили "официальный способ" — он есть. И это не злобный хак.
Пользоваться этим способом я вас не заставляю.
Re[7]: Ну и собственно про присоединение
От: Jolly Roger  
Дата: 24.09.10 09:55
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>а задача вывода на desktop не тривальна?


Ну задача-то такая решается просто, но полностью согласен, что этого не следует делать без реальной необходимости.
"Нормальные герои всегда идут в обход!"
Re[7]: Ну и собственно про присоединение
От: shakm Россия  
Дата: 24.09.10 10:08
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, shakm, Вы писали:


HL>Что такое "визуальный декстоп"? Чем он отличается от "невизуального декстопа"?


Я сократил длинное описание WindowsStation -> Desktop... Мне показалось Вам будет понятно...

S>>если проще в .Net общаться через ремотинг

HL>Ремоутинг — УГ. Особенно после выхода WCF.

Это ваш выбор, я привел примеры, разве я не сказал — много чего еще...

S>>Ведь основная суть — информировать того, кому это нужно

HL>Ви таки пытаетесь убедить меня в том, что интерактивные сервисы — это плохо, а задача вывода на desktop не тривальна?
HL>Не нужно, я сам избегаю создания интерактивных сервисов.
HL>Однако, вы просили "официальный способ" — он есть. И это не злобный хак.
HL>Пользоваться этим способом я вас не заставляю.

Я "таки" не пытаюсЯ вас ни в чем убеждать. Напишите пример сервиса, способного серди всех пользователей сервера выбрать админа Мойшу Гоймана, выбросить ему окно ввода его пинкода его кредитиной карточки, и принять данные.... тем способом, который вы защищаете... условие: что у вашего сервиса нет прав работать с админом Мойшей Гойманом, а есть назначение у этого сервиса — запрашивать данные у "таких-то" пользователей "такой-то-системы"... Что вы смешиваете API предназначенное для более системных задач, с задачами конкретной бизнес-логики конкретной системы?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.