1,183
社区成员
发帖
与我相关
我的任务
分享
procedure TForm1.RunDosInMemo(const DosApp:string;Amemo:TMemo);
const
ReadBuffer=2400; //设置ReadBuffer的大小
var
Security:TSecurityAttributes;
ReadPipe,WritePipe:THandle;
start:TStartUpInfo;
ProcessInfo:TProcessInformation;
Buffer:PChar;
BytesRead:DWord;
Buf:string;
begin
with Security do
begin
nlength:=sizeof(TSecurityAttributes);
binherithandle:=true;
lpsecuritydescriptor:=nil;
end;
{创建一个命名管道来捕获Console的输出}
if CreatePipe(ReadPipe,WritePipe,@Security,0) then
begin
Buffer:=AllocMem(ReadBuffer+1);
FillChar(Start,Sizeof(Start),#0);
{设置Console程序的启动属性}
with Start do
begin
cb:=sizeof(start);
start.lpReserved:=nil;
lpDesktop:=nil;
lpTitle:=nil;
dwX:=0;
dwY:=0;
dwXSize:=0;
dwYSize:=0;
dwXCountChars:=0;
dwYCountChars:=0;
dwFillAttribute:=0;
hStdOutput:=WritePipe; //将输出定向到建立的WritePipe上
hStdInput:=ReadPipe; //将输入定向到建立的ReadPipe上
hStdError:=WritePipe; //将错误输出定向到建立的WritePipe上
dwFlags:=STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
wshowwindow:=SW_HIDE; //设置窗口为hide
end;
try
{创建一个子进程,运行Console}
if CreateProcess(nil,PChar(DosApp),@Security,@Security,true,
NORMAL_PRIORITY_CLASS,
nil,nil,start,ProcessInfo)then
begin
Application.ProcessMessages;
{等待进程运行结束}
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
{关闭程序...开始没有关掉它,如果没有输出的话,程序死掉了。}
closeHandle(WritePipe);
buf:='';
{读取Console的输出}
repeat
bytesRead:=0;
ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil);
Buffer[BytesRead]:=#0;
OemToAnsi(Buffer,Buffer);
Buf:=Buf+String(Buffer);
Application.ProcessMessages;
until(bytesRead<ReadBuffer);
//sendDebug(Buf);
{按照换行符进行切割,并在Memo中显示出来}
while pos(#10,buf)>0 do
begin
AMemo.Lines.Add(Copy(Buf,1,Pos(#10,buf)-1));
Delete(Buf,1,Pos(#10,buf));
Application.ProcessMessages;
end;
end;
finally
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
RunDosInMemo('ping 192.168.1.1 -t',Amemo);
end;
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "proc1.h"
#include "proct.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
#define DisplayError ShowMessage
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
HANDLE hd,hi;
bool run =true;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
SECURITY_ATTRIBUTES sa;
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
HANDLE hInputWriteTmp,hInputRead,hInputWrite;
HANDLE hErrorWrite;
sa.nLength= sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
// Create the child output pipe.
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
DisplayError("CreatePipe");
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
GetCurrentProcess(),&hErrorWrite,0,
TRUE,DUPLICATE_SAME_ACCESS))
DisplayError("DuplicateHandle");
// Create the child input pipe.
if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
DisplayError("CreatePipe");
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
GetCurrentProcess(),
&hOutputRead, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
GetCurrentProcess(),
&hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS))
DisplayError("DupliateHandle");
// Close inheritable copies of the handles you do not want to be
// inherited.
if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = hOutputWrite;
si.hStdInput = hInputRead;
si.hStdError = hErrorWrite;
si.wShowWindow = SW_HIDE;
if (!CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,
CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
DisplayError("CreateProcess");
if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");
hi=hInputWrite;
hd=hOutputRead;
proct *p;
p=new proct(false);
while(run)
Application->ProcessMessages();
TerminateProcess(pi.hProcess,0);
delete p;
if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
CloseHandle(pi.hProcess);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
DWORD nn=0;
String m=Edit1->Text;
m+="\n";
if(!WriteFile(hi,m.c_str(),m.Length(),&nn,NULL))
ShowMessage("Write Error"+String(nn));
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "proct.h"
#include "proc1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall proct::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall proct::proct(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
extern HANDLE hd;
extern bool run;
void __fastcall proct::Execute()
{
//---- Place thread code here ----
CHAR lpBuffer[1];
DWORD nBytesRead;
char c;
String x="";
while(TRUE)
{
nBytesRead=0;
if (!ReadFile(hd,lpBuffer,sizeof(lpBuffer),
&nBytesRead,NULL) || !nBytesRead)
{
if (GetLastError() == ERROR_BROKEN_PIPE)
break; // pipe done - normal exit path.
else
ShowMessage("ReadFile"); // Something bad happened.
}
c=lpBuffer[0];
if (c=='\n')
{
Form1->Memo1->Lines->Add(x);
x="";
}
else
{
x+=c;
Form1->Memo1->Lines->Strings[Form1->Memo1->Lines->Count-1]=x;
}
}
run=false;
}
//---------------------------------------------------------------------------