Что эквивалентно Application.ProcessMessages, Application.Handle и Application.Terolved в приложении службы Windows? - PullRequest
3 голосов
/ 24 марта 2010

Я новичок в написании приложений Windows Service и у меня возникли проблемы.

Написанный на Delphi, я написал обычное приложение для Windows для проверки и отладки основных частей кода, и теперь мне нужно преобразовать его в службу NT.

Мой код должен запустить приложение Windows, которое я делаю, используя следующий код.

function Run_Program : boolean;
   var SEInfo : TShellExecuteInfo;
   ExitCode : DWORD;
   begin
     Result := false;
     FillChar(SEInfo, SizeOf(SEInfo),0);
     SEInfo.cbSize :=SizeOf(TShellExecuteInfo);
     With SEInfo do
     begin
       fMask := SEE_MASK_NOCLOSEPROCESS;
       Wnd := **Application.Handle**;
       lpFile := PChar(Exe_Prog);
       lpParameters := PChar(Exe_Param);
       nShow := SW_SHOWNORMAL;
     end;
     If ShellExecuteEx(@SEInfo) then
     begin
       repeat
         Application.ProcessMessages;
         GetExitCodeProcess(SEInfo.hProcess, ExitCode);
       until (ExitCode <> STILL_ACTIVE) OR Application.Terminated OR NOT q1.fieldbyName('Delay').AsBoolean;
       If ExitCode <> STILL_ACTIVE then Record_Event(Exe_Prog + ' completed ') else
          Record_Event(Exe_Prog + ' activated ');
       Result := true;
     end
     else Record_Event('Error Starting '+ Exe_Prog+ ' ');
  end;

Когда это помещено в сервисное приложение, компилятор завершается с 3 ошибками: необъявленные идентификаторы. 1) ручка 2) ProcessMessages и 3) Прекращено.

У меня вопрос: есть ли эквивалентные процедуры, которые можно использовать в приложении-службе, или я должен по-другому подходить к проблеме в приложении-службе?

Любая помощь будет оценена

Ответы [ 2 ]

5 голосов
/ 28 марта 2010

Имейте в виду, что запуск приложений из службы в Vista и 7 может работать не так, как ожидалось. Службы в Vista и 7 работают на другой станции Windows, которая не видна вошедшему в систему пользователю.

Также следует помнить, что если приложение выполняется службой, оно запускается с привилегией пользователя службы - его следует запускать с помощью CreateProcessAsUser (), чтобы избежать запуска приложения с очень повышенными привилегиями (например, LocalSystem, если только причина), потому что это может подвергнуть систему большим рискам безопасности.

Если вам нужно проверить, выходит ли приложение, нет необходимости ждать в таком цикле. Используйте WaitForSingleObject () в отдельном потоке. Он не проглотит все эти циклы ЦП, сама Windows будет вежливо сигнализировать о выходе.

Главный поток службы должен просто прослушивать команды Service Control Manager. Delphi позволяет использовать ProcessRequests () для обработки этих вызовов при использовании основного потока для фактической обработки, но лучше следовать документации и использовать отдельный поток для обработки.

4 голосов
/ 27 марта 2010

Не используйте ShellExecute () для запуска .exe-файла.Это особенно важно в сервисах, которые не запускаются в командной консоли с самого начала.Для этого используйте CreateProcess () (в Vista и более поздних версиях используйте вместо него CreateProcesAsUser ()).

Используйте ServiceThread.ProcessRequests () и ServiceThread.Termination вместо Application.ProcessMessages () и Application.Termination.

...