Консольное приложение устанавливается как сервис - PullRequest
3 голосов
/ 09 марта 2012

Я ищу и пытаюсь установить консольное приложение в качестве службы, но не понял, как это сделать.

есть рекомендации?

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

program Project1;

  Uses
  Windows,
  SysUtils,
  Dialogs,
  Messages,TlHelp32,Classes, Graphics, Controls, SvcMgr,ExtCtrls;

 Const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  DOMAIN_ALIAS_RID_ADMINS = $00000220;

  type
  TService1 = class(TService)
  private
  public
    function GetServiceController: TServiceController; override;
  end;


  var
  Service1: TService1;
  Msg: TMsg;

 Procedure ServiceController(CtrlCode: DWord); stdcall;
  begin
   Service1.Controller(CtrlCode);
 end;


 Function TService1.GetServiceController: TServiceController;
  begin
    Result := ServiceController;
 end;

Function IsAdmin: Boolean;
var
  hAccessToken: THandle;
  ptgGroups: PTokenGroups;
  dwInfoBufferSize: DWORD;
  psidAdministrators: PSID;
  x: Integer;
  bSuccess: BOOL;
begin
  Result   := False;
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
    hAccessToken);
  if not bSuccess then
  begin
    if GetLastError = ERROR_NO_TOKEN then
      bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
        hAccessToken);
  end;
  if bSuccess then
  begin
    GetMem(ptgGroups, 1024);
    bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
      ptgGroups, 1024, dwInfoBufferSize);
    CloseHandle(hAccessToken);
    if bSuccess then
    begin
      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
        SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0, psidAdministrators);
      {$R-}
      for x := 0 to ptgGroups.GroupCount - 1 do
        if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
        begin
          Result := True;
          Break;
        end;
      {$R+}
      FreeSid(psidAdministrators);
    end;
    FreeMem(ptgGroups);
  end;
end;

begin

 if IsAdmin then
   begin
                 // Install me as service 
   end else
 begin
    ShowMessage('Not Running As Admin');
 end;


  while GetMessage(Msg, 0, 0, 0) do
   begin
   TranslateMessage(Msg);
   DispatchMessage(Msg);
  end;

end.

Ответы [ 2 ]

5 голосов
/ 09 марта 2012

Существует как минимум два пути: один из них - «правильный», а другой - «неправильный» (но работает.)

неправильный, но работает

Вы можете запускать любое приложение как службу через (хост) вспомогательные утилиты, такие как:

  • ServiceEx , - бесплатное приложение Windows, которое позволяет нормальной программе работать как Windowsоказание услуг".Я никогда не использовал это, я только нашел это через Googling.
  • Одна из двух утилит Microsoft предоставляет (так как это от MS, я бы использовал это).

    Почему это неправильный путь?Потому что, если вы хотите, чтобы ваше приложение запускалось как служба, вы должны создать приложение-службу.И так уж получилось, что с Delphi это очень просто.Это правильный путь:

    Правильный путь: создать сервисное приложение

    В этой статье на delphi.about.com содержится много информации о сервисных приложениях .Однако все довольно просто: создайте новое приложение-службу через File> New> [возможно Other>> Service Application.Установите отображаемое имя и т. Д. Чтобы установить его, запустите с параметром командной строки /install;удалить запустить с /uninstall.

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

3 голосов
/ 09 марта 2012

TService требуется приложение TServiceApplication для его создания и запуска, точно так же, как для TForm требуется приложение TApplication для его создания и запуска.

Application.Initialize;
Application.CreateForm(TService1, TService1);
Application.Run;

Конечно, с TServiceApplication это больше не консольное приложение.

Насколько я знаю, если вы действительно хотите написать консольный сервис, вам нужно пропустить TService и использовать почти чисто Window API для достижения Console Service.

В сети есть старый пример с объяснениями: Сервисное и консольное приложение NT

Цитата из этой статьи:

Компилятор Delphi поддерживает разработку служб NT с использованием TServiceApplication и TService классы. Но подход Delphi не поддерживает двойной интерфейс и приносит очень много накладные расходы. Я покажу, как написать легкое приложение-службу с двойным интерфейсом, используя Windows API функция. Даже пример приложения написан на Delphi, его очень легко перенести на другой компилятор. поскольку используются только собственные функции API.

Я бы сказал, что сделать Delphi TServiceApplication намного проще ...

...