Из службы запускать приложение.
От: dzuyba  
Дата: 03.03.11 06:22
Оценка:
Мною написана служба. Ее задача состоит в том что бы отлавливать событие когда логинится пользователь (локально или по RDP) и нужно у данного пользователя запустить специальное приложение. Событие служба отлавливает а вот приложение запускается не всегда. Немогу понять в чем дело. CreateProcessAsUser возвращает false, а SysErrorMessage(GetLastError) говорить что процесс был успешно запущен. Вот хочу узать кто нибудь решил данную задачу, или у кого нибудь есть полезные ссылки.

Спасибо.
Re: Из службы запускать приложение.
От: __serj  
Дата: 03.03.11 07:26
Оценка:
Здравствуйте, dzuyba, Вы писали:

D>Мною написана служба. Ее задача состоит в том что бы отлавливать событие когда логинится пользователь (локально или по RDP) и нужно у данного пользователя запустить специальное приложение. Событие служба отлавливает а вот приложение запускается не всегда. Немогу понять в чем дело. CreateProcessAsUser возвращает false, а SysErrorMessage(GetLastError) говорить что процесс был успешно запущен. Вот хочу узать кто нибудь решил данную задачу, или у кого нибудь есть полезные ссылки.


D>Спасибо.


Для запуска службы требуются права администратора. Если у файла правильно настроем манифест, то UAC запросит разрешение на повышение привилегий, иначе возможно будет описанный Вами эффект.
Re: Из службы запускать приложение.
От: Jolly Roger  
Дата: 03.03.11 07:32
Оценка:
Здравствуйте, dzuyba, Вы писали:

D>CreateProcessAsUser возвращает false, а SysErrorMessage(GetLastError) говорить что процесс был успешно запущен.


"Так не бывает"(с).

Во всяком случае, я такого не видел никогда. Покажите лучше Ваш код, а также приведите полное сообщение об ошибке, без интерпретации. А лучше — код самой ошибки.

Вообще, данная задача многократно обсуждалась на этом форуме, поиск по CreateProcessAsUser поможет.
"Нормальные герои всегда идут в обход!"
Re: Из службы запускать приложение.
От: okman Беларусь https://searchinform.ru/
Дата: 03.03.11 07:38
Оценка:
Здравствуйте, dzuyba, Вы писали:

D>Мною написана служба. Ее задача состоит в том что бы отлавливать событие когда логинится пользователь (локально или по RDP) и нужно у данного пользователя запустить специальное приложение. Событие служба отлавливает а вот приложение запускается не всегда. Немогу понять в чем дело. CreateProcessAsUser возвращает false, а SysErrorMessage(GetLastError) говорить что процесс был успешно запущен. Вот хочу узать кто нибудь решил данную задачу, или у кого нибудь есть полезные ссылки.


Загляните вот в эту
Автор: okman
Дата: 09.02.11
тему.
Re[2]: Из службы запускать приложение.
От: dzuyba  
Дата: 09.03.11 04:48
Оценка:
__>Для запуска службы требуются права администратора. Если у файла правильно настроем манифест, то UAC запросит разрешение на повышение привилегий, иначе возможно будет описанный Вами эффект.

Приложение не запускается на Win2003 и там UAC нет
Re[2]: Из службы запускать приложение.
От: dzuyba  
Дата: 09.03.11 05:03
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

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


D>>CreateProcessAsUser возвращает false, а SysErrorMessage(GetLastError) говорить что процесс был успешно запущен.


JR>"Так не бывает"(с).


JR>Во всяком случае, я такого не видел никогда. Покажите лучше Ваш код, а также приведите полное сообщение об ошибке, без интерпретации. А лучше — код самой ошибки.


JR>Вообще, данная задача многократно обсуждалась на этом форуме, поиск по CreateProcessAsUser поможет.



procedure TCSService.ServiceControlEvent(Sender: TNTService;
  const Msg: TMsg);
var ControlCode: DWord;
begin
  ControlCode := Msg.message;
  if ControlCode = SERVICE_CONTROL_SESSIONCHANGE then
  begin
    TJrlClientOperationsHelper.InfoEvent(
      Format('ServiceControlEvent ControlCode = SERVICE_CONTROL_SESSIONCHANGE ' +
        'Msg.lParam = %d, Msg.wParam = %d', [Msg.lParam, Msg.wParam]));
    LaunchBatchAgent(Msg.lParam, Msg.wParam, True);
  end;
end;


procedure TCSService.LaunchAgent(SessionID, EventType: Integer; DoWaite: Boolean);
var hToken: Cardinal;
    si: _STARTUPINFOW;
    pi: _PROCESS_INFORMATION;
    LSTError: Cardinal;
//    siw: _STARTUPINFOW;
//    saP: _SECURITY_ATTRIBUTES;
//    saT: _SECURITY_ATTRIBUTES;
//    sdP: TSecurityDescriptor;
//    sdT: TSecurityDescriptor;
begin
  // WTS_SESSION_LOGON = 5
  if EventType <> 5 then
    Exit;
  TJrlClientOperationsHelper.WarningEvent('Запуск BatchAgent для сессии=' + IntToStr(SessionID));

  if EnableProcessPrivilege(True, SE_TCB_NAME)
{    and EnableProcessPrivilege(True, SE_INCREASE_QUOTA_NAME)
    and EnableProcessPrivilege(True, SE_ASSIGNPRIMARYTOKEN_NAME)} then
    if WTSQueryUserToken(SessionID, hToken) then
    try
      ZeroMemory(@si, SizeOf(si));
      si.cb := SizeOf(si);
      si.lpDesktop := nil;


// Закоментировал для теста, в релизе раскоментировать Disa 2011.03.09
//      if DoWaite then
//        Sleep(6000);

      if CreateProcessAsUser(hToken, PWideChar(ExtractFilePath(ParamStr(0)) + 'BatchAgent.exe'),
        PWideChar('"' + ExtractFilePath(ParamStr(0)) + 'BatchAgent.exe' + '"'), nil {@saP}, nil {@saT},
        False, NORMAL_PRIORITY_CLASS{ 0{CREATE_SUSPENDED}, nil, nil, si, pi) then
      begin
        TJrlClientOperationsHelper.InfoEvent(Format('Успешный запуск приложения %s',
          [ExtractFilePath(ParamStr(0)) + 'BatchAgent.exe']));
      end
      else
      begin
// Вот тут ошибка. LSTError = 0; SysErrorMessage = Операция успешно завершена.
        LSTError := GetLastError;
        TJrlClientOperationsHelper.ErrorEvent(Format('Ошибка запуска %s: %d - %s',
          [ExtractFilePath(ParamStr(0)) + 'BatchAgent.exe',
          LSTError, SysErrorMessage(LSTError)]));
      end;
    finally
      CloseHandle(hToken);
    end
    else
      TJrlClientOperationsHelper.ErrorEvent('Ошибка получения токена пользователя: ' +
        SysErrorMessage(GetLastError))
  else
      TJrlClientOperationsHelper.ErrorEvent('Ошибка получения привилегии: ' +
        SysErrorMessage(GetLastError))
end;


Данный LaunchAgent метод вызывается в службе когда пользователь логиниться в систему (на консоль или в терминал). Вызов CreateProcessAsUser возвращает false и дальше
GetLastError = 0 а SysErrorMessage = Операция успешно завершена
Заметил еще следующее, если раскоментировать Sleep(6000) то все срабатывает нормально, но мне кажеться это не совсем правильное решение.
У кого будут какие мысли.
Re[3]: Из службы запускать приложение.
От: dzuyba  
Дата: 09.03.11 05:26
Оценка:
Приложение запускается на Win2003
Re[3]: Из службы запускать приложение.
От: Tujh Голландия  
Дата: 09.03.11 07:08
Оценка:
Здравствуйте, dzuyba, Вы писали:

D>У кого будут какие мысли.


Проверьте две вещи:
Во-первых, в CreateProcessAsUser флаг выставить CREATE_DEFAULT_ERROR_MODE вместо NORMAL_PRIORITY_CLASS
Во-вторых, попробуйте, для проверки, в LaunchAgent SessionID получать через WTSGetActiveConsoleSessionId
Re[3]: Из службы запускать приложение.
От: Jolly Roger  
Дата: 09.03.11 09:30
Оценка:
Здравствуйте, dzuyba, Вы писали:

Как-то у Вас тут намешано, и имена методов не совпадают, и Msg.message на SERVICE_CONTROL_SESSIONCHANGE почему-то проверяете, и откуда оно приходит, не понятно. Вы уверены, что с нотификацией всё в порядке? Попробуйте получать уведомления через WTSRegisterSessionNotification.
"Нормальные герои всегда идут в обход!"
Re[4]: Из службы запускать приложение.
От: dzuyba  
Дата: 10.03.11 05:30
Оценка:
Здравствуйте, Tujh, Вы писали:

T>Во-первых, в CreateProcessAsUser флаг выставить CREATE_DEFAULT_ERROR_MODE вместо NORMAL_PRIORITY_CLASS

Выставил и никаких изменений.

T>Во-вторых, попробуйте, для проверки, в LaunchAgent SessionID получать через WTSGetActiveConsoleSessionId

Зачем мне получать SessionID с помощью WTSGetActiveConsoleSessionId, ведь эта ф-ия вернет идентификатор текущего
прользователя Local System равный 0. А мне нужен идентификатор сессии логиневшегося в данный момент пользователя,
и этот идентификатор приходит в сообщении SERVICE_CONTROL_SESSIONCHANGE в службе когда новый пользователь логинится
Msg.lParam — идентификатор сессии
Msg.wParam — тип события
Re[4]: Из службы запускать приложение.
От: dzuyba  
Дата: 10.03.11 05:35
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

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


JR>Как-то у Вас тут намешано, и имена методов не совпадают, и Msg.message на SERVICE_CONTROL_SESSIONCHANGE почему-то проверяете, и откуда оно приходит, не понятно. Вы уверены, что с нотификацией всё в порядке? Попробуйте получать уведомления через WTSRegisterSessionNotification.


Просто это моя реализация TNTService службы виндоус вместо стандартной в Delphi. С нотификацией все работает 100% механизм отлажен очень давно. Тем более это стандартный механизм служб получать сообщения SERVICE_CONTROL_SESSIONCHANGE.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.