-1
procedure TService1.ServiceExecute(Sender: TService);
var
   FileName : string;
   Strm     : TMemoryStream;
   i        : integer;
   h,m,s,ms : word;
begin

   DecodeTime( now, h, m, s, ms );

   if ( h = 13 ) AND ( m = 6 ) AND ( s = 0 ) then
   begin
      ShowMessage( 'entered' );
      for i := 0 to 3 do
      begin

         DateTimeToString( FileName, 'yyyy-mm-dd-hh-nn-ss', now );

         FileName := ExtractFilePath( Application.ExeName ) + FileName + '.jpg';

         if not FileExists( FileName ) then
         begin
            try

               Strm := TMemoryStream.Create;

               try
                  IdHTTP_ := TIdHTTP.Create( nil );

                  try
                     IdHTTP_.Get( 'http://192.168.1.223/snapshot/view0.jpg', Strm );
                  finally
                     IdHTTP_.Free;
                  end;

                  Strm.Position := 0;
                  Strm.SaveToFile( FileName );

               finally
                  Strm.Free;
               end;

            except

            end;
         end;

         Sleep( 5000 );

      end;

   end;
end;

これは、特定の時間に IP カメラから 4 つのスナップショットを取得するサービスのコードです。とにかく、サービスを開始するとすぐに、「ローカルコンピューターのService1サービスが開始され、その後停止しました。他のサービスまたはプログラムで使用されていない場合、一部のサービスは自動的に停止します。」というメッセージが表示され、サービスが終了します。

  • この情報源の問題は何ですか?
4

1 に答える 1

8

OnExecuteのドキュメントには次のように書かれています。

サービスに関連付けられたスレッドが起動したときに発生します。

OnStart イベント ハンドラで個々のサービス要求を処理するために新しいスレッドを生成しない場合は、ここでサービスを実装します。OnExecute イベント ハンドラーが終了すると、サービス スレッドが終了します。ほとんどの OnExecute イベント ハンドラーには、サービス スレッドの ProcessRequests メソッドを呼び出すループが含まれているため、他のサービス要求がロックアウトされません。

OnExecute はループしません。その関数が終了すると、サービスは停止します。ドキュメントに記載されていることを行う必要があります。ループするか、サービス要求を処理するスレッドを生成します。

サービスでは UI を表示できないことに注意してください。そのため、ShowMessage を呼び出そうとしてもうまくいきません。サービスに適したロギング メカニズムを使用する必要があります。たとえば、ファイルに書き込むもの。

あなたがやろうとしていることは、スケジュールされたタスクとしてスケジュールされた通常のデスクトップ プロセスではるかに簡単になります。サービスはあなたの問題に対する間違った解決策だと思います。

于 2013-04-28T10:20:11.980 に答える