3

重複の可能性:
プロセス間通信で使用される Windows メッセージの代替を探しています
プロセス間通信

タイプ ライブラリを公開する Delphi 7 アプリを実行しています。TLB が公開する関数の 1 つに ProcessFile(fileName: string) があります。その関数が呼び出されたときに、実行中の Windows サービス (Delphi 7 アプリケーションでもある) に、このイベントが呼び出されたこととファイル名が何であるかが通知されるようにしたいと考えています。

これを行う方法についての考えは大歓迎です。レジストリとtxtファイルを使用して変更されたコールバックを介してこれを実行しようとしましたが、いずれにしても、このProcessFileメソッドは1秒間に何度も呼び出される可能性があるため、処理されるファイルを失うことがあります。

ありがとう!

4

1 に答える 1

7

パイプはその仕事に最適です。サービス側でパイプ リーダー スレッドを実装し、クライアント側で ProcessFile メソッドのパイプを介して対応する文字列データを送信できます。

パイプの使用例をチェックする迅速でシンプルなエラーなし:

パイプサーバー

var
  Form1: TForm1;
  t: TReadpipe;

  h: THandle;
  msg: string;

const BufSize=512;

implementation

{$R *.dfm}

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  chandle: THandle;
begin
  t.Terminate;

  chandle := CreateFile('\\.\pipe\myNamedPipe', GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, 0);
  CloseHandle(chandle);

  t.WaitFor;
  t.Free;
  CloseHandle(h);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  t := Treadpipe.Create(false);
end;

{ TReadPipe }

procedure TReadPipe.Execute;
var
  buf: array [0 .. BufSize-1] of char;
  read: cardinal;
begin
  while not Terminated do
  begin
    h := CreateNamedPipe('\\.\pipe\myNamedPipe', PIPE_ACCESS_DUPLEX,
      PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_WAIT,
      PIPE_UNLIMITED_INSTANCES, BufSize, BufSize, 0, nil);

    ConnectNamedPipe(h, nil);

    if Terminated then
      break;

    msg := '';

    repeat
      FillChar(buf, BufSize, #0);
      ReadFile(h, buf[0], BufSize, read, nil);

      msg := msg + Copy(buf, 0, read);
    until GetLastError <> ERROR_MORE_DATA;

    if msg <> '' then
      Synchronize(
        procedure
        begin
          form1.Memo1.Lines.Add(msg)
        end);
  end;

  DisconnectNamedPipe(h);
end;

パイプクライアント

var
  Form1: TForm1;
  i: Integer = 0;
  pipe: THandle;

const
  BufSize = 512;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  buf: array [0 .. BufSize - 1] of char;
  written: Cardinal;
  str: pchar;
begin
  pipe := CreateFile('\\.\pipe\myNamedPipe', GENERIC_WRITE, 0, nil,
    OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, 0);

  if pipe = INVALID_HANDLE_VALUE then
    Halt;

  inc(i);
  str := pchar('someStr' + inttostr(i));
  fillchar(buf, BufSize, #0);
  move(str[0], buf[0], Length(str) * Sizeof(char));
  WriteFile(pipe, buf[0], Length(str) * Sizeof(char), written, nil);

  CloseHandle(pipe);
end;

また、パイプは FIFO として機能することも覚えておいてください。

于 2012-11-20T10:08:38.120 に答える