Delphi 简单命名管道在两个进程间通讯

 

服务器端代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  WM_MYMSG=WM_USER+1024;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
  private
    { Private declarations }
  public
    constructor Create(AOwner: TComponent); override;
    procedure display(var msg:TMessage);message WM_MYMSG;
    { Public declarations }
  end;

var
  Form1: TForm1;


implementation

var
  pipeHandle:HWND;
  byteRead:DWORD;
  buffer:array[0..255] of char;
  threadId:Cardinal;
  threadHandle:HWND;

{$R *.dfm}

{ TForm1 }

function fun(p:Pointer):DWORD;stdcall;
begin
  if ConnectNamedPipe(pipeHandle,nil)=FALSE then
  begin
    ShowMessage(format('ConnectNamedPipe failed with error %d',[GetLastError()]));
    Application.Destroy;
  end;

  //注意,下面的 ReadFile中,其buffer只能用字符数组
  //无论是string,或者pchar,都会让客户端程序报 233错误-管道的另一端上无任何进程。
  //在msdn中 ReadFile中的buffer是个LPVOID,delphi中则是一个var(引用)参数
  //这个问题目前暂时无解决办法,是一个值得深入研究的话题。

  if ReadFile(pipeHandle,buffer,sizeof(buffer),byteRead,nil)=FALSE then
  begin
    ShowMessage(format('ReadFile failed with error %d',[GetLastError()]));
    Application.Destroy;
  end;

  SendMessage(integer(p),WM_MYMSG,1,1);

  if DisconnectNamedPipe(pipeHandle)=FALSE then
  begin
    ShowMessage(format('DisconnectNamedPipe failed with error %d',[GetLastError()]));
    Application.Destroy;
  end;

  CloseHandle(pipeHandle);
  Result:=0;

end;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  pipeHandle:= CreateNamedPipe('\\.\Pipe\Jim',PIPE_ACCESS_DUPLEX,
    PIPE_TYPE_BYTE or PIPE_READMODE_BYTE,1,0,0,1000,nil);
  if pipeHandle=INVALID_HANDLE_VALUE then
  begin
    ShowMessage(format('CreateNamePipe failed with error %d',[GetLastError()]));
    Application.Destroy;
  end;
  memo1.Clear;
  memo1.Lines.Add('Server is now running');

  threadHandle:=createThread(nil,0,@fun,Ptr(form1.Handle),0,threadId);


end;


procedure TForm1.display(var msg: TMessage);
begin
  memo1.Text:=buffer;
end;

end.

客户端代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    constructor Create(AOwner: TComponent); override;

    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

var
  pipeHandle:HWND;
  bytesWrite:DWORD;
  pipeNameStr:string;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin

  if WaitNamedPipe(pchar(pipeNameStr),NMPWAIT_WAIT_FOREVER)=FALSE then
  begin
    ShowMessage(format('WaitNamedPipe faile with error %d',[GetLastError()]));
    exit;
  end;

  pipeHandle:= CreateFile(pchar(pipeNameStr),GENERIC_READ or GENERIC_WRITE,
    FILE_SHARE_WRITE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

  if pipeHandle=INVALID_HANDLE_VALUE then
  begin
    ShowMessage(format('CreateFile faile with error %d',[GetLastError()]));
    exit;
  end;

  if WriteFile(pipeHandle,pchar(memo1.text)^,length(memo1.text),bytesWrite,nil)=
    FALSE then
  begin
    ShowMessage(format('WriteFile faile with error %d',[GetLastError()]));
    exit;
  end;

  ShowMessage(format('write %d Bytes',[bytesWrite]));
  CloseHandle(pipeHandle);
end;

constructor TForm1.Create(AOwner: TComponent);
begin
  inherited;
  memo1.Clear;
  memo1.Text:='猪悟能到此一游,通过命名管道!hello';
  pipeNameStr:='\\.\Pipe\Jim';
end;

end.

 

posted @ 2014-10-10 21:58  Max Woods  阅读(1901)  评论(0编辑  收藏  举报