Delphi Tokyo Service создает процесс только при загрузке - PullRequest
0 голосов
/ 22 июня 2019

У меня есть служебный скрипт для Windows в Delphi Tokyo. Служба запускается при запуске системы и правильно создает процесс x. Запустите таймер, который циклически проверяет, запущен процесс или нет, и, если это не так, он пытается запустить его, но завершается неудачно с кодом ошибки 1008.

function TMyservice.CreaProcessoComeUtenteX(const FileName, Params: string;
  WindowState: Word): Boolean;
var
  SessionID: DWORD;
  UserToken: THandle;
  CmdLine: PChar;
  si: _STARTUPINFOW;
  pi: _PROCESS_INFORMATION;
  ExitCode: Cardinal;
begin
  SessionId:= WtsGetActiveConsoleSessionID;
  if SessionID = $FFFFFFFF then
  begin
    ADDLOG('Exit from CreaProcessoComeUtenteX '+IntToStr(SessionID));
    Result := false;
    Exit;
  end;
  if WTSQueryUserToken(SessionID, UserToken) then
  begin    
    CmdLine:= PWideChar(FileName+Params);
    ZeroMemory(@si, SizeOf(si));
    si.cb := SizeOf(si);
    SI.lpDesktop := PChar('winsta0\Default');
    SI.dwFlags := STARTF_USESHOWWINDOW;
    if WindowState = 1 then
      SI.wShowWindow := SW_SHOWNORMAL;
    if WindowState = 0 then
      SI.wShowWindow := SW_MINIMIZE;
    ZeroMemory(@pi, SizeOf(pi));
    try

      CreateProcessAsUser(UserToken, nil, CmdLine, nil, nil, False,
      0, nil, nil, si, pi);

      ADDLOG(' Create process Ok');
      result := true;
    except on E: Exception do
      begin
        // Log exception ...
        result := false;
        ADDLOG('Err proc: '+ E.Message);
      end;
    end;
    CloseHandle(UserToken);
  end else
  begin
    // Log GetLastError ...
    Result := false;
    ADDLOG('QToken: '+IntToStr(GetLastError));
  end;
end;

Этот код олицетворяет текущего пользователя

function TInfBabeleDS.ConnectAs(const lpszUsername,
  lpszPassword: string): Boolean;
var
  hToken       : THandle;
begin
  Result := LogonUser(PChar(lpszUsername), nil, PChar(lpszPassword), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken);
  if Result then
    Result := ImpersonateLoggedOnUser(hToken)
  else
  RaiseLastOSError;
end;

1 Ответ

0 голосов
/ 23 июня 2019

Код ошибки 1008 - ERROR_NO_TOKEN, что означает, что WTSQueryUserToken() был вызван для идентификатора сеанса, в который не вошел пользователь.

WTSGetActiveConsoleSessionID() не всегда является лучшим сеансом, особенно в системе.автозагрузка, если ваша служба пытается запустить процесс еще до того, как кто-либо из пользователей вошел в систему.Идентификатор сеанса, который прикреплен к локальному физическому монитору / клавиатуре / мыши, не гарантирует, что пользователь вошел в систему в любой момент времени, если вообще когда-либо.

В подобных случаях используйтеWTSEnumerateSessions() вместо этого, чтобы найти сеансы, в которых пользователь вошел в систему.

Кроме того, вы не выполняете обработку ошибок в CreateProcessAsUser().Это не вызывает исключения по ошибке, как ожидает ваш код.Ваш try..except бесполезен.

...