BOOL
CreatePipe(
PHANDLE
hReadPipe,
PHANDLE
hWritePipe,
LPSECURITY_ATTRIBUTES
lpPipeAttributes,
DWORD
nSize
)
这是一个windows
API,和delphi没有关系
第一个参数:接受管道的读句柄的变量
第二个:接受管道写句柄的变量
第三个是指向一个管道属性数据结构的指针,也就是结构体首地址,
在delphi中@是取变量首地址的操作符
第四个是管道缓冲的大小
查MSDN,有更详细的说明
求VB的API(CreatePipe及CreateProcess)的用法 我想参考下您的解决方案 谢谢
通过管道技术就可以读取到DOS窗口的返回。
写过一个单元文件可以取到,代码如下:
unit mylib
interface
uses
Windows, ShellAPI
function GetDosOutput(CommandLine: string): string
implementation
function GetDosOutput(CommandLine: string): string
var
SA: TSecurityAttributes
SI: TStartupInfo
PI: TProcessInformation
StdOutPipeRead, StdOutPipeWrite: THandle
WasOK: Boolean
Buffer: array [0 .. 255] of AnsiChar
BytesRead: Cardinal
Handle: Boolean
begin
Result := ''
with SA do
begin
nLength := SizeOf(SA)
bInheritHandle := True
lpSecurityDescriptor := nil
end
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0)
try
with SI do
begin
FillChar(SI, SizeOf(SI), 0)
cb := SizeOf(SI)
dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES
wShowWindow := SW_HIDE
hStdInput := GetStdHandle(STD_INPUT_HANDLE) // don't redirect stdin
hStdOutput := StdOutPipeWrite
hStdError := StdOutPipeWrite
end
Handle := CreateProcess(nil, PChar('cmd /c ' + CommandLine), nil, nil,
True, 0, nil, nil, SI, PI)
CloseHandle(StdOutPipeWrite)
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil)
if BytesRead > 0 then
begin
Buffer[BytesRead] := #0
Result := Result + Buffer
end
until not WasOK or (BytesRead = 0)
WaitForSingleObject(PI.hProcess, INFINITE)
finally
CloseHandle(PI.hThread)
CloseHandle(PI.hProcess)
end
finally
CloseHandle(StdOutPipeRead)
end
end
end.
测试代码:
procedure TForm1.btn1Click(Sender: TObject)
begin
mmo1.Text:= GetDosOutput('ping www.baidu.com')
end
执行效果:
delphi创建一个进程并返回进程的PID
Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As SECURITY_ATTRIBUTES, lpThreadAttributes As SECURITY_ATTRIBUTES, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Declare Function CreatePipe Lib "kernel32" Alias "CreatePipe" (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
PeekNamedPipe 阻塞
程序设计思路:
首先,利用WIN API函数 Createpipe 建立两个管道(Pipe),然后建立利用CreateProcess函数创建一个控制台程序的进程(这里使用的是Win2000的Dos控制台 cmd.exe),并且在StartUpInfo参数中指定用刚才建立的三个管道替换标准的输入hStdOutput、输出hStdInput以及错误输出设备hStdError。
代码如下:
procedure TForm1.InitConsole
var
Security: TSecurityAttributes
start: TStartUpInfo
begin
with Security do begin
nlength := SizeOf(TSecurityAttributes)
binherithandle := true
lpsecuritydescriptor := nil
end
Createpipe(ReadOut, WriteOut, @Security, 0)
Createpipe(ReadIn, WriteIn, @Security, 0)
with Security do begin
nlength := SizeOf(TSecurityAttributes)
binherithandle := true
lpsecuritydescriptor := nil
end
FillChar(Start, Sizeof(Start), #0)
start.cb := SizeOf(start)
start.hStdOutput := WriteOut
start.hStdInput := ReadIn
start.hStdError := WriteOut
start.dwFlags := STARTF_USESTDHANDLES +
STARTF_USESHOWWINDOW
start.wShowWindow := SW_HIDE
CreateProcess(nil,
PChar('cmd'),
@Security,
@Security,
true,
NORMAL_PRIORITY_CLASS,
nil,
nil,
start,
ProcessInfo)
end
然后利用一个定时器,从对应输出设备的管道中读取控制台返回的信息,并显示。
代码如下:
function TForm1.ReadFromPipe(Pipe: THandle): string
var
Buffer: PChar
BytesRead: DWord
begin
Result := ''
if GetFileSize(Pipe, nil) = 0 then Exit
Buffer := AllocMem(ReadBuffer + 1)
repeat
BytesRead := 0
ReadFile(Pipe, Buffer[0],
ReadBuffer, BytesRead, nil)
if BytesRead >0 then begin
Buffer[BytesRead] := #0
OemToAnsi(Buffer, Buffer)
Result := string(Buffer)
end
until (BytesRead <ReadBuffer)
FreeMem(Buffer)
end
procedure TForm1.Timer1Timer(Sender: TObject)
var
s: string
begin
s := ReadFromPipe(ReadOut)
if s <>'' then begin
Memo1.Lines.Text := Memo1.Lines.Text + s
Memo1.SelStart := Length(Memo1.Lines.Text)
Memo1.SelLength := 0
end
end
在下方的输入框内输入命令之后,则通过向输入设备对应的管道发送命令来实现命令行的输入,代码如下:
procedure TForm1.WriteToPipe(Pipe: THandleValue: string)
var
len: integer
BytesWrite: DWord
Buffer: PChar
begin
len := Length(Value) + 1
Buffer := PChar(Value + #10)
WriteFile(Pipe, Buffer[0], len, BytesWrite, nil)
end
procedure TForm1.Button1Click(Sender: TObject)
begin
if Trim(cbCmd.Text) <>'' then begin
WriteToPipe(WriteIn, cbCmd.Text)
if cbCMD.ItemIndex >-1 then
cbCMD.Items.Delete(cbCMD.ItemIndex)
cbcmd.Items.Insert(0, cbCmd.Text)
cbCmd.Text:=''
end
end
这里要注意的是发送命令行的时候必须添加换行字符#10,才能被Dos控制台接受并执行
PeekNamedPipe(hReadPipe,NULL,NULL,NULL,&tempdword,&nextword)
return tempdword+nextword
以上就是关于delphi中createpipe的四个参数分别是啥意思啊?全部的内容,如果了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!