Delphi Windows 11 での Windows サービスの開発: ベスト プラクティスとツール

Windows ソフトウェアを開発するとき、1 日 24 時間実行する必要がある特定の種類のアプリケーション、または実際にはコンピューターの実行中に継続的に実行する必要があるアプリケーションに遭遇することがあります。通常、これらのコンピュータは Web サーバーまたはデスクトップ上のアプリケーションを監視しています。このような場合、最小限の対話を行うか、完全にサイレントなコンソール アプリケーションを作成することを検討するかもしれませんが、それよりも優れた解決策があります。

単純なコンソールまたは最小化された通常の GUI アプリケーションでは、Windows セッションの終了、再起動、ユーザー権限などの問題が発生する可能性があります。この問題の解決策は、Windows サービスを開発することです。このチュートリアルでは、Delphi を使用した Windows サービスの構築について詳しく説明します。その後、Windows サービスのテンプレートとして使用できます。

目次

Windows サービスを作成する必要があるのはなぜですか?

Windows サービスを開発するための前提条件は何ですか?

Windows サービス アプリケーションはどのように動作しますか?

Windows サービスを作成する必要があるのはどのような場合ですか?

Delphi で Windows サービス プロジェクトを作成するにはどうすればよいですか?

Delphi を使用して Windows サービス アプリケーションを実装するにはどうすればよいですか?

Windows サービス アプリケーションの機能を実装するにはどうすればよいですか?

Windows サービス マネージャーを使用してサービスをテストする

サービスアプリケーションのデバッグ


Windows サービスを作成する必要があるのはなぜですか?

長時間実行されるサービスを作成する理由は次のとおりです。

  • CPU 負荷の高いデータを処理します。
  • 作業項目はバックグラウンドでキューに入れられます。
  • timetable に対して時間ベースの操作を実行する
  • 「ヘルパー」またはユーティリティ関数の目立たない操作

バックグラウンド サービスの処理には通常、ユーザー インターフェイス (UI) が関与しませんが、バックグラウンド サービスの処理を中心に UI を構築することができます

Windows サービスを開発するための前提条件は何ですか?

サービス アプリケーションの開発に入る前に、Delphi IDE の最新バージョンを確認することをお勧めします。多数の機能強化と新機能により、開発プロセスはさらにスムーズになります。さらに、Delphi Community Edition を無料で使用して、Delphi プログラミング言語とその構文に慣れることができます。

Windows サービス アプリケーションはどのように動作しますか?

サービス アプリケーションは、クライアント アプリケーションからリクエストを受信し、それらのリクエストを処理して、クライアント アプリケーションに情報を返します。Web、FTP、または電子メール サーバーは、サービス アプリケーションの例です。

Windows サービス アプリケーションは、ユーザーがログオンしなくても実行できる Windows アプリケーションです。Windows サービス アプリケーションがデスクトップと対話することはほとんどありません。このチュートリアルでは、Delphi を使用して Windows サービス アプリケーションを作成します。

サービス プログラムの実行中に、仮想「サービス ユーザー」として、またはシステムにアクセスできる実際の一般ユーザーとして、一連のデフォルトのユーザー権限を使用するように設定できます。重要なのは、これらのユーザー権限は、サービス アプリケーションがアクセスできるフォルダーだけでなく、「マップされた」ネットワーク フォルダーにも影響することです。誰かがネットワーク フォルダーを指す "Z" などのマッピングを作成した場合、次のようになります。使えない。可能であれば、常に完全な UNC パス名を使用する必要があります。または、Windows システム コールまたは Delphi のランタイム TPath タイプ関数を使用して、%APPDATA% フォルダや「マイ ドキュメント」タイプの仮想フォルダの場所など、特別なフォルダの正しい場所を取得します。道。

Windows サービス アプリケーションは多くの機能を提供できます。サービスユーティリティを起動するときにリストを確認してください。これらのサービスは、使用するメイン GUI アプリケーションの中核となることができます。

Windows サービスを作成する必要があるのはどのような場合ですか?

少し前、ファイル サーバーの空きディスク領域を監視するシステム監視ツールが必要でした。私は毎分チェックしてその情報をログ ファイルに書き込むツールを作成しました。ただし、ユーザーがログインする必要があり、ユーザーがログアウトするとアプリが終了します。解決策は、プログラムを Windows サービスとして再作成し、ユーザーがログオンしていなくても、コンピューターの電源が入っているときに実行し続けることです。

RAD Studio は、Delphi または C++ Builder を使用した一般的なユーザー向け対話型アプリケーション向けに最適化されていますが、サービス アプリケーションを簡単に作成できる機能も備えています。

Delphi で Windows サービス プロジェクトを作成するにはどうすればよいですか?

Delphi で新しいプロジェクトを作成するには、コンピュータに Delphi 開発環境がインストールされている必要があります。Delphi をインストールして実行したら、新しいプロジェクトの作成を開始できます。

RAD Studio で Delphi を使用して新しい Windows サービス プロジェクトを作成するには、次の手順を実行します。

  1. 「ファイル」メニューをクリックし、「新規」→「その他」を選択します。これにより、「新しいプロジェクト」ダイアログが表示されます。
  2. ダイアログの左側で [Delphi] を選択し、[Windows] カテゴリから [Windows サービス] プロジェクト タイプを選択します。
  3. 「OK」をクリックして新しいプロジェクトを作成します。

 このプロセスは C++ Builder を使用する場合と同様であることに注意してください。

新しいプロジェクトが作成されたら、プロジェクトのプロパティとオプションを設定する必要があります。これを行うには、[プロジェクト マネージャー] ウィンドウでプロジェクト名を右クリックし、[オプション] を選択します。これにより、「プロジェクト オプション」ダイアログが表示されます。このダイアログでは、ターゲット プラットフォーム、出力ディレクトリ、コンパイラ オプションなど、プロジェクトのさまざまなオプションを設定できます。サービスの開発を続行する前に、プロジェクトの要件に従ってこれらのオプションを設定してください。

Delphi を使用して Windows サービス アプリケーションを実装するにはどうすればよいですか?

Delphi で新しい Windows サービス プロジェクトを作成し、プロジェクトのプロパティとオプションを設定したら、次のステップはサービス自体を実装することです。これには、メイン サービス ユニットにコードを追加することが含まれます。通常、デフォルトは「Unit1.pas」です。

まず、 「プロジェクト マネージャー」ウィンドウで「 Unit1.pas 」ファイルをダブルクリックして、コード エディターで開きます。これにより、Delphi サービス アプリケーションのスケルトン コードが含まれるユニットのコード ファイルが表示されます。

ユニットに独自のコードを追加するには、さまざまなサービス イベントを処理してサービスの動作を定義する必要があります。これらのイベントには、開始、停止、一時停止イベントが含まれており、それぞれサービスが開始、停止、または一時停止されたときに発生します。

これらのイベントを処理するには、Delphi の組み込みサービス コンポーネントである「TService」クラスを使用できます。このコンポーネントは、「開始」メソッドや「停止」メソッドなど、サービスの動作を制御するために使用できるさまざまなメソッドとプロパティを提供します。

たとえば、「OnStart」イベント ハンドラーを使用して、サービスの開始時に実行するコードを定義できます。これを行うには、次のコードを「Unit1.pas」ファイルに追加します。

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
  // code you want to execute when the service starts
  // such as making a log entry
end;

開始イベントと停止イベントに加えて、サービスが一時停止されたときに発生する一時停止イベントも処理する必要がある場合があります。これを行うには、「OnStart」および「OnStop」イベント ハンドラーと同様の「OnPause」イベント ハンドラーを使用できます。

たとえば、次のコードを「Unit1.pas」ファイルに追加して、一時停止イベントを処理できます。

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
  // Add your code here for things to happen when the user
  // chooses "pause" from the service menu or uses the service control
  // commands to pause your service.
  // This is NOT the same as the service being stopped!
end;

各イベント ハンドラー内に独自のコードを追加して、それぞれのイベントが発生したときのサービスの動作を定義できます。たとえば、「TService」コンポーネントの「Start」および「Stop」メソッドを使用してタイマーまたはスレッドを開始または停止したり、「Pause」メソッドを使用してタスクの実行を一時停止したりできます。

メイン サービス ユニットにコードを追加し、サービスのイベントを処理したら、Delphi デバッガーと Windows サービス マネージャーを使用してサービスのデバッグとテストを続けることができます。

Windows サービス アプリケーションの機能を実装するにはどうすればよいですか?

Vcl.SvcMgrユニットをUnit の Uses 句に追加します

次のように TForm クラスの宣言を変更して、メイン フォームの祖先をTServiceに変更します。

type
  TService1 = class(TService)

完全なソースコードは次のとおりです。

unit ServiceUnit;

interface

uses
  Winapi.Windows
, Winapi.Messages
, System.SysUtils
, System.Classes
, Vcl.Graphics
, Vcl.Controls
, Vcl.SvcMgr
, Vcl.Dialogs
, BackgroundThreadUnit
, System.Win.Registry;

type
  TService1 = class(TService)
    procedure ServiceExecute(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServicePause(Sender: TService; var Paused: Boolean);
    procedure ServiceContinue(Sender: TService; var Continued: Boolean);
    procedure ServiceAfterInstall(Sender: TService);
  private
    FBackgroundThread: TBackgroundThread;
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

{$R *.dfm}

var
  MyService: TService1;

implementation

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  MyService.Controller(CtrlCode);
end;

procedure TService1.ServiceExecute(Sender: TService);
begin
  while not Terminated do
  begin
    ServiceThread.ProcessRequests(false);
    TThread.Sleep(1000);
  end;
end;

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

procedure TService1.ServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
  FBackgroundThread.Continue;
  Continued := True;
end;

procedure TService1.ServiceAfterInstall(Sender: TService);
var
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('SYSTEMCurrentControlSetServices' + name, false) then
    begin
      Reg.WriteString('Description', 'Blogs.Embarcadero.com');
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
end;

procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
begin
  FBackgroundThread.Pause;
  Paused := True;
end;

procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
begin
  FBackgroundThread.Terminate;
  FBackgroundThread.WaitFor;
  FreeAndNil(FBackgroundThread);
  Stopped := True;
end;

procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
begin
  FBackgroundThread := TBackgroundThread.Create(True);
  FBackgroundThread.Start;
  Started := True;
end;

end.

ここでのバックグラウンド スレッドのコードは次のとおりです。

unit BackgroundThreadUnit;

interface

uses
  System.Classes;

type
  TBackgroundThread = class(TThread)
  private
    FPaused: Boolean;
    // FTerminated: Boolean;
    // FOnTerminate: TNotifyEvent;
  protected
    procedure Execute; override;
  public
    procedure Pause;
    procedure Continue;
    // procedure Terminate;
    // property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
  end;

implementation

uses
  System.SysUtils, System.IOUtils;

procedure TBackgroundThread.Continue;
begin
  FPaused := False;
end;

  // process something here
procedure TBackgroundThread.Execute;
var
  LogFile: TextFile;
begin
  try
    FPaused := False;
    AssignFile(LogFile, 'C:TempLogs.log');
    Rewrite(LogFile);

    while not Terminated do
    begin
      if not FPaused then
      begin
        WriteLn(LogFile, 'Logs From Background Thread: ' + DateTimeToStr(Now));
      end;
      TThread.Sleep(1000);
    end;
  finally
    CloseFile(LogFile);
  end;
end;

procedure TBackgroundThread.Pause;
begin
  FPaused := True;
end;

end.

これでサービスを作成できるようになりました。プロジェクト ウィンドウでコンテキスト メニューを開いて、次のようにサービスを作成できます。

Delphi が Windows サービスを構築

Windows サービス マネージャーを使用してサービスをテストする

Windows サービス マネージャーを使用してサービスをテストできます。このツールを使用すると、サービスを開始、停止、一時停止、再開したり、サービスのステータスや発生する可能性のあるエラーを表示したりできます。

サービスをインストールするには、次の手順に従う必要があります。

  • フォルダーに移動し、ターミナルで開きます (実行可能ファイルは管理者権限で実行するように構成されている必要があります)
  • 「/install」コマンドでサービス名を入力します

そのフォルダーに移動し、ターミナルで開きます

ターミナルを使用して Windows サービスをインストールする

サービスがインストールされたら、Windows サービス マネージャーを使用してサービスを開始、停止、一時停止、または再開できます。これを行うには、Windows コントロール パネルの管理ツール フォルダーにあるサービス アプリケーションを開きます。サービスのリストでサービスを見つけて右クリックし、コンテキスト メニューから目的のアクションを選択します。

ここでサービスを開始、停止、一時停止できます

数秒後、サービス マネージャーからサービスを停止し、ログ ファイルを確認します。

付録:

サービスアプリケーションのデバッグ

サービス アプリケーションをデバッグするには、サービス アプリケーションがすでに実行されている間にサービス アプリケーション プロセスにアタッチします (つまり、サービスを開始してからデバッガーにアタッチします)。サービス アプリケーション プロセスに接続するには、  [実行] > [プロセスに接続]を選択し、表示されるダイアログでサービス アプリケーションを選択します。

場合によっては、権限が不十分なためにこのメソッドが失敗することがあります。この問題が発生した場合は、サービス コントロール マネージャーを使用して、サービスがデバッガーで動作できるようにすることができます。

デバッグするには:

  1. まず、レジストリの場所 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion に Image File Execution Options という名前のキーを作成します。
  2. サービスと同じ名前のサブキーを作成します (たとえば、MYSERV.EXE)。このサブキーに、Debugger という名前のタイプ REG_SZ の値を追加します。bds.exe へのフルパスを文字列値として使用します。
  3. [サービス] コントロール パネル アプレットでサービスを選択し、[開始] をクリックして、サービスにデスクトップとの対話を許可するにチェックを入れます。

Windows NT の場合:

Windows NT システムでは、別の方法を使用してサービス アプリケーションをデバッグできます。ただし、このアプローチは非常に短い時間間隔を必要とするため、難しい場合があります。

  1. まず、デバッガーでアプリケーションを起動します。読み込みが完了するまで数秒待ちます。
  2. コントロール パネルまたはコマンド ラインからサービスをすばやく開始します: start MyServ

サービスが開始されていない場合、アプリケーションは終了してしまうため、すぐに (アプリケーションの開始後 15 ~ 30 秒以内に) サービスを開始する必要があります。

Windows サービスを削除するにはどうすればよいですか?

管理者として PowerShell を開き、次のコマンドを入力します。 sc delete ServiceName

Windows サービス アプリをサイレント インストールするにはどうすればよいですか?

/silent次のようにコマンド ラインの末尾に 「 」を追加すると、メッセージ ボックスの表示を回避できます。myserviceapp.exe /install /silent

32 ビット サービスは 64 ビット Windows 上で実行できますか?

はい、32 ビット サービスは 64 ビット バージョンの Windows 上で通常どおり実行できます。ただし、ネットワーク システム管理者によっては、   64 ビット サービス以外の実行を禁止する Windows グループ ポリシー オプションが設定されている場合があることに注意してください。ほとんどの人は これを行いません が、可能です。

おすすめ

転載: blog.csdn.net/sensor_WU/article/details/131252304