50分找帮手,可加分!!管道问题?

fengxia0078 2004-05-04 10:43:57
用ShellExecute(NULL,"open","gamv.exe","GV_data.par",NULL,SW_SHOWNORMAL)
运行之后,dos窗口几乎只显示了一秒。在dos窗口里gamv.exe输出了很多信息,我在Form1上加了一个Memo1,设置为黑底白字......
请高手们帮助,希望能写完整的代码和说明。谢谢!!
明天早上就给分!
...全文
195 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzf20lzf 2004-05-06
  • 打赏
  • 举报
回复
其他不明白了
lzf20lzf 2004-05-06
  • 打赏
  • 举报
回复
Memo1->SelStart=Memo1->Lines->Text.Length();
//Memo1->SelLength=0;
Memo1->SetFocus();
boy4hero 2004-05-06
  • 打赏
  • 举报
回复
我太菜了,看不懂
lzf20lzf 2004-05-06
  • 打赏
  • 举报
回复
滚动条在最下面
Memo1->Perform(EM_SCROLLCARET,0,0);
comefirst 2004-05-06
  • 打赏
  • 举报
回复
看不明白,这是作什么用的?
shine168 2004-05-05
  • 打赏
  • 举报
回复
帮你up
fengxia0078 2004-05-05
  • 打赏
  • 举报
回复
###高手们继续呀??!!!!!!!!!!!!!!**********
lzf20lzf 2004-05-05
  • 打赏
  • 举报
回复
Memo1->ScrollBars=ssHorizontal 或 ssBoth 或 ssVertical
fengxia0078 2004-05-05
  • 打赏
  • 举报
回复
一阵风:我用了你的ExecuteApp代码ExecuteApp(“*.exe *.par”)可以实现,
但是,这只是写入本窗口(一个子窗口)的Memo1,我想写入主窗口,如何??
我的这个主窗口下有39个子窗口对应不同的*.exe,
如何能调用不同的子窗口但是都写入主窗口的Memo1,另:怎样在Memo1上加一个移动条,并且
光标在最后一个字上(你的代码实现后,光标在最上面)???
lzf20lzf 2004-05-04
  • 打赏
  • 举报
回复
下面是运行结果:

引用:
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


lzf20lzf 2004-05-04
  • 打赏
  • 举报
回复
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");
}
//---------------------------------------------------------------------------





13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧