荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: Dreamer (我爱萤火虫), 信区: SoftDev
标 题: 【BCB】使用管道
发信站: 荔园晨风BBS站 (Sat May 8 14:20:13 2004), 站内信件
毕设需要用到的技术,贴出来大家分享 :)
http://expert.csdn.net/Expert/topic/3032/3032649.xml?temp=.1442682
主 题: 50分找帮手,可加分!!管道问题?
作 者: fengxia0078 (风侠)
等 级:
信 誉 值: 100
所属论坛: C++ Builder 基础类
问题点数: 50
回复次数: 2
发表时间: 2004-05-04 22:39:51
用ShellExecute(NULL,"open","gamv.exe","GV_data.par",NULL,SW_SHOWNORMAL)
运行之后,dos窗口几乎只显示了一秒。在dos窗口里gamv.exe输出了很多信息,我在Form1
上加了一个Memo1,设置为黑底白字......
请高手们帮助,希望能写完整的代码和说明。谢谢!!
明天早上就给分!
回复人: lzf20lzf(一阵风-我真贱(2004-4-27)) ( ) 信誉:100 2004-05-04 23:32:00
得分:0
http://www.chinabcb.com/bbs/viewtopic.php?t=5113&highlight=%B9%DC%B5%C0
★使用管道技术实例
代码:
bool __fastcall TForm1::RunCmd(AnsiString cmd,TStringList *stringlist)
{
TMemoryStream *memstream=new TMemoryStream();
AnsiString rn="\\r\\n";
PROCESS_INFORMATION proc;
STARTUPINFO start;
SECURITY_ATTRIBUTES sa;
long ret;
unsigned long lngBytesread;
HANDLE hReadPipe,hWritePipe;
char *strBuff=(char *)malloc(256);
if(strBuff==NULL)
{
return false;
}
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=true;
sa.lpSecurityDescriptor=NULL;
ret=CreatePipe(&hReadPipe,&hWritePipe,&sa,0);
if(ret==0)
{
//创建管道失败
return false;
}
memset(&start,0x00,sizeof(STARTUPINFO));
start.cb=sizeof(STARTUPINFO);
start.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
start.hStdOutput=hWritePipe;
start.hStdError=hWritePipe;
bool retc=CreateProcess(NULL,cmd.c_str(),NULL,NULL,true, 0, 0, NULL, &start,
&proc);
if(!retc)
{
return false;
}
CloseHandle(hWritePipe);
unsigned long len;
memstream->Position=0;
while(true)
{
memset(strBuff,0x00,256);
GetFileSize(hReadPipe,&len);
ret = ReadFile(hReadPipe, strBuff, 256, &lngBytesread,NULL);
if(ret==0)
{
break;
}
else
{
memstream->Write(strBuff,lngBytesread);
}
}
CloseHandle(proc.hProcess);
CloseHandle(proc.hThread);
CloseHandle(hReadPipe);
memstream->Position=0;
free(strBuff);
stringlist->LoadFromStream(memstream);
memstream->Clear();
delete memstream;
return true;
}
以上为一个使用管道获取命令行模式的程序的运行结果的函数。
使用代码
TStringList *StrList=new TStringList;
AnsiString strcmd;
RunCmd(strcmd,StrList);
结果保留再StrList中。
试了试,发现上述代码运行时不能显示中间过程,要等到程序完全运行结束才能看到结果,
不太方便(特别是运行比较耗时的命令)。并且会多出一些不必要的空行,和dos窗口下看
到的结果不一样(例如运行ping的命令)。
下面是我改进的代码,把运行的情况直接显示在Memo1中。其实我觉得没有太大的必要使用
TMemoryStream,直接用AnsiString就可以了。
代码:
//---------------------------------------------------------------------------
String __fastcall TForm1::ExecuteApp(String sCmdline)
{
PROCESS_INFORMATION proc = {0};
long ret,k=1;
bool bret;
STARTUPINFO start = {0};
SECURITY_ATTRIBUTES sa = {0};
HANDLE hReadPipe ;
HANDLE hWritePipe;
String sOutput;
String sBuffer;
unsigned long lngBytesRead;
char cBuffer[257];
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle = TRUE;
bret =::CreatePipe(&hReadPipe, &hWritePipe,&sa, 0);
if (!bret)
{
sOutput="CreatePipe failed. Error: " + String(GetLastError());
Memo1->Lines->Add(sOutput);
return sOutput;
}
start.cb = sizeof(STARTUPINFOA);
start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
start.hStdOutput = hWritePipe;
start.hStdError = hWritePipe;
start.wShowWindow = SW_HIDE;
sBuffer = sCmdline;
ret =::CreateProcess(0, sBuffer.c_str(), &sa, &sa, TRUE,
NORMAL_PRIORITY_CLASS, 0, 0, &start, &proc);
if (ret == 0)
{
sOutput="Bad command or filename";
Memo1->Lines->Add(sOutput);
return sOutput;
}
::CloseHandle(hWritePipe);
do
{
memset(cBuffer,'\0',sizeof(cBuffer));
ret = ::ReadFile(hReadPipe, &cBuffer, 256, &lngBytesRead, 0);
sBuffer=StrPas(cBuffer);
sOutput = sOutput + sBuffer;
Memo1->Text=Memo1->Text+sBuffer;
Application->ProcessMessages();
} while (ret != 0 );
::CloseHandle(proc.hProcess);
::CloseHandle(proc.hThread);
::CloseHandle(hReadPipe);
return sOutput;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ExecuteApp("Ping www.chinabcb.com");
}
//---------------------------------------------------------------------------
Top
回复人: lzf20lzf(一阵风-我真贱(2004-4-27)) ( ) 信誉:100 2004-05-04 23:32:00
得分:0
下面是运行结果:
引用:
Pinging www.chinabcb.com [218.22.205.4] with 32 bytes of data:
Reply from 218.22.205.4: bytes=32 time=60ms TTL=115
Reply from 218.22.205.4: bytes=32 time=50ms TTL=115
Reply from 218.22.205.4: bytes=32 time=140ms TTL=115
Reply from 218.22.205.4: bytes=32 time=81ms TTL=115
Ping statistics for 218.22.205.4:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 50ms, Maximum = 140ms, Average = 82ms
以上程序没有使用线程,耗时长的程序界面反应缓慢。
★请问如何将标准输出或错误输出重定向到TMemo或TRichEdit中去?
我的意思是,在一个IDE程序中,调用system函
数时,可以把屏幕的输出在一个TMemo或TRichEdit中显示,
可不可以把cout<<和ceer<<也显示到里面?
可否告诉我那本书或文章有相关的介绍?
这里有源代码(例子):
http://www.chinabcb.com/bbs/viewtopic.php?t=5113&highlight=%B9%DC%B5%C0
BCB的WINTOOLS范例
// Create the Pipe and get r/w handles
HANDLE hReadPipe;
HANDLE hWritePipe;
assert(CreatePipe(&hReadPipe,
&hWritePipe,
lpsa,
2500000));
// initialize STARTUPINFO struct
STARTUPINFO si;
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW |STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
PROCESS_INFORMATION pi;
assert(hWritePipe);
// Run the cmdLine tool
ResultsRE->Lines->Add("Working.....");
Application->ProcessMessages();
if( CreateProcess(NULL,
CmdStrRE->Text.c_str(),
NULL,//security
NULL,// security
TRUE,//inherits handles
0,
0,
0,
&si,
&pi)
){
CloseHandle(pi.hThread);
// read from the pipe and put in richedit
assert(hReadPipe);
DWORD BytesRead; //unsigned long
char dest[4000];
bool RdLoopDone = false;
ResultsRE->Lines->Clear();
FBreak = 1;
if (ExitCode) Screen->Cursor = crDefault;
while (!RdLoopDone) {
memset(dest, 0, 4000);
assert(ReadFile(hReadPipe, &dest, sizeof(dest), &BytesRead, NULL));
ResultsRE->Lines->Add(String(dest));
if (BytesRead < 4000) RdLoopDone = true;
if (FBreak > 150) RdLoopDone = true;
FBreak++;
}
ResultsRE->Lines->Add("FINISHED!");
http://expert.csdn.net/Expert/topic/2887/2887041.xml?temp=.8849298
★SECURITY_ATTRIBUTES saPipe;
// 管道忏属性
saPipe.nLength = sizeof (SECURITY_ATTRIBUTES);
saPipe.lpSecurityDescriptor = NULL;
saPipe.bInheritHandle = TRUE;
if (!CreatePipe(&m_hReadPipe, &m_hWriteFile, &saPipe, 0) // 创建输入管道
||!CreatePipe(&m_hReadFile, &m_hWritePipe, &saPipe, 0) // 创建输出管道
)
{
throw Exception("can't create shell pipe");
}
//
// 连接管道
//
char szCmd[MAX_PATH];
GetStartupInfo(&m_StartInfo);
m_StartInfo.dwFlags = STARTF_USESHOWWINDOW // 不忽略 wShowWindow 成员
| STARTF_USESTDHANDLES; // 不忽略 Std 输入输出错误
m_StartInfo.hStdInput = m_hReadPipe; // 连接输入, 可通过 m_hWriteFile
写
m_StartInfo.hStdOutput = m_hWritePipe; // 连接输出, 可通过 m_hReadFile 读
m_StartInfo.hStdError = m_hWritePipe; // 连接输出, 可通过 m_hReadFile 读
m_StartInfo.wShowWindow = SW_HIDE; // 隐藏控制台窗体
GetSystemDirectory(szCmd, MAX_PATH);
strcat(szCmd, "\\cmd.exe");
// 创建 cmd.exe 进程, 已将输入输出错误指向我们的程序
CreateProcess(
NULL,
szCmd,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&m_StartInfo,
&m_ProcessInfo
);
// 向管道里写入, cmd.exe 执行此命令
if (Key == VK_RETURN)
{
WriteFile(m_hWriteFile, Edit1->Text.c_str(), Edit1->Text.Length(),
&dwBytes, NULL);
WriteFile(m_hWriteFile, "\n\r", 1, &dwBytes, NULL);
}
// 从管道里读取数据
ReadFile(Form1->hReadFile, lpBuff, 0x1000, &dwBytes, NULL);
lpBuff[dwBytes] = 0;
m_pCSMemo->Acquire();
AddPipeInfo(lpBuff);
m_pCSMemo->Release();
http://expert.csdn.net/Expert/topic/2021/2021806.xml?temp=.388241
--
如果你真的爱萤火虫,你就不应该将她困在瓶子里;
如果你真的爱萤火虫,你应该放开她,让她在天空中自由自在地飞!
虽然你会不舍得她,但是最终你就会明白这样你才真正拥有了她!
※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 210.21.224.234]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店