服务器断代码
procedure TForm1.btnProcessCreateClick(Sender: TObject);
var
start: TStartupInfoA;
begin
//1:创建管道
CreatePipe;
ZeroMemory(@Start,Sizeof(Start));
start.cb := SizeOf(start);
start.hStdOutput := 0;
start.hStdInput := 0;
start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow := SW_NORMAL; //要显示子线程的窗体
//2:创建子程序
if CreateProcessA(nil, //不能使用CreateProcess CreateProcess调用的是CreateProcessW WideChar类型
'Client.exe 10.1.1.198', //如果要给进程传参数,建议将进程和参数都通过第二次参数传递进去
nil,
nil,
False,
NORMAL_PRIORITY_CLASS,
nil,
nil,
start,
processInfo) = False then
begin
ShowMessage('线程创建失败');
end;
//3:连接管道
ConnectPipe;
end;
procedure TForm1.ConnectPipe;
var
handle: THandle;
ovlap: TOverlapped;
begin
//3:连接管道
//创建管道的人工重置事件
handle := CreateEvent(nil, True, False, nil); //第二个参数需要为True
if handle = INVALID_HANDLE_VALUE then
begin
ShowMessage('Create Event Failed');
end;
ZeroMemory(@ovlap, sizeof(ovlap));
ovlap.hEvent := handle;
//等待客户端的连接请求
ConnectNamedPipe(FPipeHanle, @ovlap); //第二个参数不能为空,必须指向一个TOverlapped
if WaitForSingleObject(handle, INFINITE) = WAIT_FAILED then
begin
ShowMessage('ConnectNamedPipe failed');
Exit;
end;
end;
procedure TForm1.CreatePipe;
begin
if FPipeHanle <> INVALID_HANDLE_VALUE then
begin
CloseHandle(FPipeHanle);
end;
//1:创建管道
FPipeHanle := CreateNamedPipe('\\.\Pipe\UpgradeBcs', //管道名必须为 \\.\Pipe\pipename
PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED, //FILE_FLAG_OVERLAPPED 重叠操作, 读写不阻塞
0, 1, 1024, 1024, 0, nil);
if FPipeHanle = INVALID_HANDLE_VALUE then
begin
ShowMessage(format('CreateNamePipe failed with error %d',[GetLastError()]));
Exit;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FPipeHanle := INVALID_HANDLE_VALUE;
end;
procedure TForm1.tmr1Timer(Sender: TObject);
var
buf: array [0..99] of Byte;
size: Cardinal;
begin
if FPipeHanle <> INVALID_HANDLE_VALUE then
Exit;
if ReadFile(FPipeHanle, buf, 4, size, nil) = True then
begin
scrlbr1.Position := buf[0];
end;
end;
客户端代码,客户端用控制台来显示
SetConsoleTitle('客户端窗口');
Writeln(ParamStr(1)); //打印传给此进程的参数
//1:连接管道
if WaitNamedPipe('\\.\Pipe\UpgradeBcs', 10000) = False then //注意管道名要和服务器端一致
begin
Writeln('wait pipe failed');
Exit;
end;
//2:打开命名管道
PipeHandle := CreateFile('\\.\Pipe\UpgradeBcs', GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if PipeHandle = INVALID_HANDLE_VALUE then
begin
Writeln('Open pipe failed');
Exit;
end;
WriteLn('Open pipe successful');
while (SendNum < 100) do
begin
WriteLn(IntToStr(SendNum));
//3:往管道里面写数据
WriteFile(PipeHandle, SendNum, 4, WrSize, nil);
Inc(SendNum);
Sleep(10);
end;