Сервис/консоль в nt.
От: vadimus  
Дата: 11.03.02 15:44
Оценка:
Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.
Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.
GetStdHandle() (если запуск произошел из сервисов) возвращает 0, но не INVALID_HANDLE_VALUE — как в m s d n написано, т.е. непонятно норамльный это хендл или нет.
А где еще рыть ума не приложу.
Re: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 11.03.02 15:50
Оценка:
Здравствуйте vadimus, Вы писали:

V>Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.

V>Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.
V>GetStdHandle() (если запуск произошел из сервисов) возвращает 0, но не INVALID_HANDLE_VALUE — как в m s d n написано, т.е. непонятно норамльный это хендл или нет.
V>А где еще рыть ума не приложу.

Это уже как-то раз здесь обсуждали. Просто вызываешь StartServiceCtrlDispatcher — если облом, то работаем как обычная консоль, иначе как сервис.
Re[2]: Сервис/консоль в nt.
От: vadimus  
Дата: 11.03.02 15:57
Оценка:
Здравствуйте Lexey, Вы писали:

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


V>>Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.

V>>Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.
V>>GetStdHandle() (если запуск произошел из сервисов) возвращает 0, но не INVALID_HANDLE_VALUE — как в m s d n написано, т.е. непонятно норамльный это хендл или нет.
V>>А где еще рыть ума не приложу.

L>Это уже как-то раз здесь обсуждали. Просто вызываешь StartServiceCtrlDispatcher — если облом, то работаем как обычная консоль, иначе как сервис.


Это тоже пробовал, но там таймаут какой-то непонятный (хотя догадываюсь почему), секунд 10, вроде тоже глюкаво как-то выходит.
Re[3]: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 11.03.02 16:02
Оценка:
Здравствуйте vadimus, Вы писали:

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


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


V>>>Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.

V>>>Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.
V>>>GetStdHandle() (если запуск произошел из сервисов) возвращает 0, но не INVALID_HANDLE_VALUE — как в m s d n написано, т.е. непонятно норамльный это хендл или нет.
V>>>А где еще рыть ума не приложу.

L>>Это уже как-то раз здесь обсуждали. Просто вызываешь StartServiceCtrlDispatcher — если облом, то работаем как обычная консоль, иначе как сервис.


V>Это тоже пробовал, но там таймаут какой-то непонятный (хотя догадываюсь почему), секунд 10, вроде тоже глюкаво как-то выходит.


Какой таймаут??? Сколько не отлаживал стартап своего сервиса — этот вызов сразу выпадает с ошибкой, если программу стратует не SCM.
Re[4]: Сервис/консоль в nt.
От: vadimus  
Дата: 11.03.02 16:14
Оценка:
L>Какой таймаут??? Сколько не отлаживал стартап своего сервиса — этот вызов сразу выпадает с ошибкой, если программу стратует не SCM.

void main( )
{
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ "MyService", MyServiceStart },
{ NULL, NULL }
};

if (!StartServiceCtrlDispatcher( dispatchTable))
{
// если консоль — сюда приходим через 10 сек.
}
}

У меня так
Re[5]: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 11.03.02 16:25
Оценка:
Здравствуйте vadimus, Вы писали:

L>>Какой таймаут??? Сколько не отлаживал стартап своего сервиса — этот вызов сразу выпадает с ошибкой, если программу стратует не SCM.


V>void main( )

V>{
V> SERVICE_TABLE_ENTRY dispatchTable[] =
V> {
V> { "MyService", MyServiceStart },
V> { NULL, NULL }
V> };
V>
V> if (!StartServiceCtrlDispatcher( dispatchTable))
V> {
V>// если консоль — сюда приходим через 10 сек.
V> }
V>}

V>У меня так


У меня сразу вываливается. А у тебя сервис с таким именем зарегистрирован?
Re: Сервис/консоль в nt.
От: Alex Fedotov США  
Дата: 11.03.02 16:37
Оценка:
Здравствуйте vadimus, Вы писали:

V>Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.

V>Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.

1. Можно проверять свойства window station, к которой присоединен процесс. Фокус пройдет, если заранее известно, что сервис никогда не будет интерактивным. Тогда можно просто проверять на winsta0\default. Кстати, возможно, это правильное решение для целей выдачи лога: если есть доступ к экрану — лог на экране, если нет — в eventlog.

2. Можно взять токен процесса и перечислить все его группы. Если есть группа Service Logon (S-1-5-6), то процесс запущен в логон-сессии сервиса. Это означает, что либо сам процесс является сервисом, либо запущен (возможно, опосредованно) сервисом.

3. ID родительского процесса на Win2K/XP можно получить с помощью документированных функций Toolhelp32.
-- Alex Fedotov
Re[6]: Сервис/консоль в nt.
От: vadimus  
Дата: 11.03.02 16:45
Оценка:
L>У меня сразу вываливается. А у тебя сервис с таким именем зарегистрирован?

Это я для примера написал, но все равно имена одинаковые.
В отладчике сейчас посмотрел —

call advapi32.StartServiceCtrlDispatcherA
...
kernel32.WaitNamePipeW
...
ntdll.ZwFsControlFile
...
int 0x2e << вот тут таймаут
Re[2]: Сервис/консоль в nt.
От: Alex Fedotov США  
Дата: 11.03.02 18:06
Оценка: 3 (1)
Здравствуйте Alex Fedotov, Вы писали:

V>>Есть ли "документированная" возможность определить в программе как она запущена — из сервисов или как консоль? Пример — апач можно и так и эдак пускать, если консоль — весь лог на экране, если сервис — то в eventLog-e.

V>>Недокументированная возможность есть — "NtQueryInformationProcess" из ntdll.dll позволяет получить id породившего процесса, но не подходит — начальник не позволяет.

AF>1. Можно проверять свойства window station, к которой присоединен процесс. Фокус пройдет, если заранее известно, что сервис никогда не будет интерактивным. Тогда можно просто проверять на winsta0\default. Кстати, возможно, это правильное решение для целей выдачи лога: если есть доступ к экрану — лог на экране, если нет — в eventlog.


AF>2. Можно взять токен процесса и перечислить все его группы. Если есть группа Service Logon (S-1-5-6), то процесс запущен в логон-сессии сервиса. Это означает, что либо сам процесс является сервисом, либо запущен (возможно, опосредованно) сервисом.


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

AF>3. ID родительского процесса на Win2K/XP можно получить с помощью документированных функций Toolhelp32.


И, наконец, я забыл последний способ, самый очевидный:

4. При регистрации сервиса указать параметр командной строки, по которому потом определять, что процесс был запущен как служба. Это, пожалуй, единственный способ, дающий 100% результат, поскольку, скажем, тот факт, что родительским процессом службы является services.exe является не более документированным, чем функции из ntdll.dll.
-- Alex Fedotov
Re[3]: Сервис/консоль в nt.
От: vadimus  
Дата: 12.03.02 08:35
Оценка:
Здравствуйте Alex Fedotov, Вы писали:


AF>>1. Можно проверять свойства window station, к которой присоединен процесс. Фокус пройдет, если заранее известно, что сервис никогда не будет интерактивным. Тогда можно просто проверять на winsta0\default. Кстати, возможно, это правильное решение для целей выдачи лога: если есть доступ к экрану — лог на экране, если нет — в eventlog.


Консоль возвращает Winsta0\default, а сервис — просто default? Наверно этим и воспользуюсь

AF>И, наконец, я забыл последний способ, самый очевидный:


AF>4. При регистрации сервиса указать параметр командной строки, по которому потом определять, что процесс был запущен как служба. Это, пожалуй, единственный способ, дающий 100% результат, поскольку, скажем, тот факт, что родительским процессом службы является services.exe является не более документированным, чем функции из ntdll.dll.



Если я не понял — поправьте... С командной строкой вообще не охота связываться — тогда все просто — с таким параметром — как консоль, без него — сервис, но ведь и сервису можно параметры передать Или в CreateService можно что-нибудь эдакое сказать?
Re[4]: Сервис/консоль в nt.
От: Alex Fedotov США  
Дата: 12.03.02 08:49
Оценка:
Здравствуйте vadimus, Вы писали:

V>Здравствуйте Alex Fedotov, Вы писали:



AF>>>1. Можно проверять свойства window station, к которой присоединен процесс. Фокус пройдет, если заранее известно, что сервис никогда не будет интерактивным. Тогда можно просто проверять на winsta0\default. Кстати, возможно, это правильное решение для целей выдачи лога: если есть доступ к экрану — лог на экране, если нет — в eventlog.


V>Консоль возвращает Winsta0\default, а сервис — просто default? Наверно этим и воспользуюсь


У интерактивного сервиса будет те же winsta0\default, а у неинтерактивного будет нечто вроде Service-0x0-3e7$\default

AF>>И, наконец, я забыл последний способ, самый очевидный:


AF>>4. При регистрации сервиса указать параметр командной строки, по которому потом определять, что процесс был запущен как служба. Это, пожалуй, единственный способ, дающий 100% результат, поскольку, скажем, тот факт, что родительским процессом службы является services.exe является не более документированным, чем функции из ntdll.dll.


V>Если я не понял — поправьте... С командной строкой вообще не охота связываться — тогда все просто — с таким параметром — как консоль, без него — сервис, но ведь и сервису можно параметры передать Или в CreateService можно что-нибудь эдакое сказать?


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

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

CreateService(..., _T("\"C:\\WINNT\\system32\\myservice.exe\" /service"), ...);


Теперь при запуске службы эта командная строка будет использоваться для создания процесса службы. Соответственно, myservice.exe получит параметр /service в командной строке, если запущен как служба.
-- Alex Fedotov
Re[5]: Сервис/консоль в nt.
От: vadimus  
Дата: 12.03.02 09:05
Оценка:
Здравствуйте Alex Fedotov, Вы писали:

AF>У интерактивного сервиса будет те же winsta0\default, а у неинтерактивного будет нечто вроде Service-0x0-3e7$\default


У меня почему-то сервис возвращает просто default. Создавал его так

newService = CreateService(
scm, argv[1], // name
argv[2], // display name
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
argv[3], // full path
0, 0, 0, 0, 0);

И еще вопрос. Кроме как созданием "message file-а" в eventLog ничего путного не написать выходит? Получается на Borlande ничего не выйдет?
Re[6]: Сервис/консоль в nt.
От: Alex Fedotov США  
Дата: 12.03.02 09:40
Оценка:
Здравствуйте vadimus, Вы писали:

AF>>У интерактивного сервиса будет те же winsta0\default, а у неинтерактивного будет нечто вроде Service-0x0-3e7$\default


V>У меня почему-то сервис возвращает просто default. Создавал его так


Возвращает на что? Service-0x0-3e7$\default — это имя оконной станции и имя десктопа. Оконная станция здесь — Service-0x0-3e7$, десктоп — default.


V>И еще вопрос. Кроме как созданием "message file-а" в eventLog ничего путного не написать выходит?


Нет, не выходит.

V>Получается на Borlande ничего не выйдет?


Ну почему, не выйдет? У него что, mc.exe в поставке нет? Ну так можно из Platform SDK взять.
-- Alex Fedotov
Re[7]: Сервис/консоль в nt.
От: vadimus  
Дата: 12.03.02 10:22
Оценка:
Здравствуйте Alex Fedotov, Вы писали:


AF>Возвращает на что? Service-0x0-3e7$\default — это имя оконной станции и имя десктопа. Оконная станция здесь — Service-0x0-3e7$, десктоп — default.


С этим вроде разобрался, кстати еще прочитал про StdHandle в первоисточнике —

The value of the handles returned by GetStdHandle will not be 0, 1, and 2, so the standard predefined stream constants in the STDIO.H header file (STDIN, STDOUT, and STDERR) cannot be used in functions that require a console handle

а сервис всегда возвращает 0.

AF>Ну почему, не выйдет? У него что, mc.exe в поставке нет? Ну так можно из Platform SDK взять.


Я сомневаюсь что получится —
создам *.mc, получу *.rc,*.rh,*.bin, собиру exe-шник борландом, куда подцепплю ресурсы собранные микрософтом И все это должно работать???
Re[8]: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 12.03.02 10:26
Оценка:
Здравствуйте vadimus, Вы писали:

AF>>Возвращает на что? Service-0x0-3e7$\default — это имя оконной станции и имя десктопа. Оконная станция здесь — Service-0x0-3e7$, десктоп — default.


V>С этим вроде разобрался, кстати еще прочитал про StdHandle в первоисточнике —


V>The value of the handles returned by GetStdHandle will not be 0, 1, and 2, so the standard predefined stream constants in the STDIO.H header file (STDIN, STDOUT, and STDERR) cannot be used in functions that require a console handle


V>а сервис всегда возвращает 0.


AF>>Ну почему, не выйдет? У него что, mc.exe в поставке нет? Ну так можно из Platform SDK взять.


V>Я сомневаюсь что получится —

V>создам *.mc, получу *.rc,*.rh,*.bin, собиру exe-шник борландом, куда подцепплю ресурсы собранные микрософтом И все это должно работать???

Хм, по идее формат ресурсов должен быть одинаковым. В крайнем случае можешь собрать отдельную resource-only dll с помощью VC++.
Re[9]: Сервис/консоль в nt.
От: vadimus  
Дата: 12.03.02 13:24
Оценка:
L>Хм, по идее формат ресурсов должен быть одинаковым. В крайнем случае можешь собрать отдельную resource-only dll с помощью VC++.

Все получилось — вижуалом надо только бинарники сделать, с остальным борланд справился.

Всем спасибо за участие.
Re[4]: Сервис/консоль в nt.
От: Dront Россия  
Дата: 12.03.02 14:21
Оценка:
Здравствуйте Lexey, Вы писали:

V>>Это тоже пробовал, но там таймаут какой-то непонятный (хотя догадываюсь почему), секунд 10, вроде тоже глюкаво как-то выходит.


L>Какой таймаут??? Сколько не отлаживал стартап своего сервиса — этот вызов сразу выпадает с ошибкой, если программу стратует не SCM.


Может, у вас ОС разные? В смысле NT и W2K?
WBR, Andrey Reznik (2:5020/2999, Andrey_Reznik@rambler.ru)
Re[5]: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 12.03.02 15:06
Оценка:
Здравствуйте Dront, Вы писали:

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


V>>>Это тоже пробовал, но там таймаут какой-то непонятный (хотя догадываюсь почему), секунд 10, вроде тоже глюкаво как-то выходит.


L>>Какой таймаут??? Сколько не отлаживал стартап своего сервиса — этот вызов сразу выпадает с ошибкой, если программу стратует не SCM.


D>Может, у вас ОС разные? В смысле NT и W2K?


Почти однозначно разные.
Re[6]: Сервис/консоль в nt.
От: vadimus  
Дата: 12.03.02 15:50
Оценка:
Здравствуйте Lexey, Вы писали:

L>Почти однозначно разные.


NT 4.0 + SP5
Re[7]: Сервис/консоль в nt.
От: Lexey Россия  
Дата: 13.03.02 07:45
Оценка:
Здравствуйте vadimus, Вы писали:

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


L>>Почти однозначно разные.


V>NT 4.0 + SP5


.NET Server beta 3 Думаю, на W2K оно тоже должно сразу отваливаться.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.