delphi与windows管道操作

上传人:工**** 文档编号:552451230 上传时间:2023-06-02 格式:DOC 页数:20 大小:95.50KB
返回 下载 相关 举报
delphi与windows管道操作_第1页
第1页 / 共20页
delphi与windows管道操作_第2页
第2页 / 共20页
delphi与windows管道操作_第3页
第3页 / 共20页
delphi与windows管道操作_第4页
第4页 / 共20页
delphi与windows管道操作_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《delphi与windows管道操作》由会员分享,可在线阅读,更多相关《delphi与windows管道操作(20页珍藏版)》请在金锄头文库上搜索。

1、什么是管道?参考WIN32汇编编程是这样描述的 Windows 引入了多进程和多线程机制。同时也提供了多个进程之间的通信手段,包括剪贴板、DDE、OLE、管道等,和其他通信手段相比,管道有它自己的限制和特点,管道实际上是一段共享内存区,进程把共享消息放在那里。并通过一些 API 提供信息交换。 管道是两个头的东西,每个头各连接一个进程或者同一个进程的不同代码,按照管道的类别分有两种管道,匿名的和命名的;按照管道的传输方向分也可以分成两种,单向的双向的。根据管道的特点,命名管道通常用在网络环境下不同计算机上运行的进程之间的通信(当然也可以用在同一台机的不同进程中)它可以是单向或双向的;而匿名管道

2、只能用在同一台计算机中,它只能是单向的。匿名管道其实是通过用给了一个指定名字的有名管道来实现的。 使用管道的好处在于:读写它使用的是对文件操作的 api,结果操作管道就和操作文件一样。即使你在不同的计算机之间用命名管道来通信,你也不必了解和自己去实现网络间通信的具体细节。 使用匿名管道的步骤如下:使用 CreatePipe 建立两个管道,得到管道句柄,一个用来输入,一个用来输出 准备执行控制台子进程,首先使用 GetStartupInfo 得到 StartupInfo 使用第一个管道句柄代替 StartupInfo 中的 hStdInput,第二个代替 hStdOutput、hStdError

3、,即标准输入、输出、错误句柄 使用 CreateProcess 执行子进程,这样建立的子进程输入和输出就被定向到管道中 父进程通过 ReadFile 读第二个管道来获得子进程的输出,通过 WriteFile 写第一个管道来将输入写到子进程 父进程可以通过 PeekNamedPipe 来查询子进程有没有输出 子进程结束后,要通过 CloseHandle 来关闭两个管道。 下面是具体的说明和定义:1. 建立匿名管道使用 CreatePipe 原形如下:BOOL CreatePipe(PHANDLE hReadPipe, / address of variable for read handle P

4、HANDLE hWritePipe, / address of variable for write handle LPSECURITY_ATTRIBUTES lpPipeAttributes, / pointer to security attributes DWORD nSize / number of bytes reserved for pipe ); 当管道建立后,结构中指向的 hReadPipe 和 hWritePipe 可用来读写管道,当然由于匿名管道是单向的,你只能使用其中的一个句柄,参数中的 SECURITY_ATTRIBUTES 的结构必须填写,定义如下:typedef s

5、truct_SECURITY_ATTRIBUTESDWORD nLength: /定义以字节为单位的此结构的长度 LPVOID lpSecurityDes criptor; /指向控制这个对象共享的安全描述符,如果为NULL这个对象将被分配一个缺省的安全描述 BOOL bInheritHandle; /当一个新过程被创建时,定义其返回是否是继承的.供系统API函数使用. SECURITY_ATTRIBUTES; 2. 填写创建子进程用的 STARTUPINFO 结构,一般我们可以先用 GetStartupInfo 来填写一个缺省的结构,然后改动我们用得到的地方,它们是:hStdInput -

6、用其中一个管道的 hWritePipe 代替 hStdOutput、hStdError - 用另一个管道的 hReadPipe 代替 dwFlags - 设置为 STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW 表示输入输出句柄及 wShowWindow 字段有效 wShowWindow - 设置为 SW_HIDE,这样子进程执行时不显示窗口。 填写好以后,就可以用 CreateProcess 来执行子进程了。3. 在程序中可以用 PeekNamedPipe 查询子进程有没有输出,原形如下:OOL PeekNamedPipe(HANDLE hNamedP

7、ipe, / handle to pipe to copy from LPVOID lpBuffer, / pointer to data bufferDWORD nBufferSize, / size, in bytes, of data buffer LPDWORD lpBytesRead, / pointer to number of bytes read LPDWORD lpTotalBytesAvail, / pointer to total number of bytes available LPDWORD lpBytesLeftThisMessage / pointer to u

8、nread bytes in this message );我们可以将尝试读取 nBuffersize 大小的数据,然后可以通过返回的 BytesRead 得到管道中有多少数据,如果不等于零,则表示有数据可以读取。4. 用 ReadFile 和 WriteFile 来读写管道,它们的参数是完全一样的,原形如下:ReadFile or WriteFile(HANDLE hFile, / handle of file to read 在这里使用管道句柄LPVOID lpBuffer, / address of buffer that receives data 缓冲区地址DWORD nNumber

9、OfBytesToRead, / number of bytes to read 准备读写的字节数LPDWORD lpNumberOfBytesRead, / address of number of bytes read,实际读到的或写入的字节数LPOVERLAPPED lpOverlapped / address of structure for data 在这里用 NULL);5. 用 CloseHandle 关闭管道一和管道二的 hReadPipe和 hWritePipe 这四个句柄。下面是一个演示DEMO,可以使用MEMO来制作一个控制台,所使用的技术就是管道procedureRun

10、DosInMemo(Que:String;EnMemo:TMemo);constCUANTOBUFFER=2000;varSeguridades:TSecurityAttributes;PaLeer,PaEscribir:THandle;start:TStartUpInfo;ProcessInfo:TProcessInformation;Buffer:Pchar;BytesRead:DWord;CuandoSale:DWord;begin/安全描述可以省略withSeguridadesdobeginnlength:=SizeOf(TSecurityAttributes);binherithan

11、dle:=true;lpsecuritydes criptor:=nil;end;Creamoselpipe.ifCreatepipe(PaLeer,PaEscribir,Seguridades,0)thenbegin /申请缓冲Buffer:=AllocMem(CUANTOBUFFER+1); /创建STARTUPINFOFillChar(Start,Sizeof(Start),#0);start.cb:=SizeOf(start);start.hStdOutput:=PaEscribir;start.hStdInput:=PaLeer;start.dwFlags:=STARTF_USEST

12、DHANDLES+STARTF_USESHOWWINDOW;start.wShowWindow:=SW_HIDE; /执行子进程ifCreateProcess(nil,PChar(Que),Seguridades,Seguridades,true,NORMAL_PRIORITY_CLASS,nil,nil,start,ProcessInfo)thenbeginEsperaaqueterminelaejecucionrepeat /使用信号量技术来避免CPU时间片被抢占CuandoSale:=WaitForSingleObject(ProcessInfo.hProcess,100);Applic

13、ation.ProcessMessages;until(CuandoSaleWAIT_TIMEOUT);LeemoslaPiperepeatBytesRead:=0;Llenamosuntronchodelapipe,igualanuestrobuffer /执行标准输出ReadFile(PaLeer,Buffer0,CUANTOBUFFER,BytesRead,nil);LaconvertimosenunastringterminadaenceroBufferBytesRead:=#0;ConvertimoscaracteresDOSaANSIOemToAnsi(Buffer,Buffer);EnMemo.Text:=EnMemo.text+String(Buffer);until(BytesReadCUANTOBUFFER);end;FreeMem(Buffer); /释放资源

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号