迈
迈克老狼
Unregistered / Unconfirmed
GUEST, unregistred user!
这是两个程序利用标准输入、输出重定向的问题,主程序启动后,点击界面上的读取按钮,
没有问题,把客户端程序的字符都读出来了,但是第二次点的时候,即客户程序没有发送字符的时候,则出现死机现象,调试一下,是死在 if (!ReadFile(hChildStdoutRdDup, chBuf,4096, &dwRead, NULL) || dwRead == 0) return;
这一句,就是客户程序没有数据时边死在此,希望有经验的朋友指点一下,谢谢。。。
主程序启动客户程序,主程序中的project2.exe,就是客户程序的名字,客户程序是一个控制台程序代码如下:
int main(int argc, char* argv[])
{
for (int i=0;i<100;i++)
{
printf("123"
fflush(stdout);
}
getchar();
}
主程序如下:
头文件:
//---------------------------------------------------------------------------
#ifndef MainFrmH
#define MainFrmH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TfrmMain : public TForm
{
__published: // IDE-managed Components
TPageControl *pgcMain;
TTabSheet *tshMain;
TMemo *moMsg;
TButton *btnRead;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall btnReadClick(TObject *Sender);
private:
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hSaveStdin, hSaveStdout;
DWORD dwProcessId;
BOOL CreateChildProcess(DWORD& dwProcessId);
bool CreateConsoleRedirect();
void WriteToPipe( LPCTSTR line );
public: // User declarations
__fastcall TfrmMain(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TfrmMain *frmMain;
//---------------------------------------------------------------------------
#endif
Cpp文件:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainFrm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
bool TfrmMain::CreateConsoleRedirect()
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// &Ouml;&Oslash;&para;¨&Iuml;ò×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;...
// ±&pound;&acute;&aelig;&micro;±&Ccedil;°±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;&micro;&Auml;&frac34;&auml;±ú
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) )
{
ShowMessage("Stdout pipe creation failed"
return FALSE;
}
// &Eacute;è&Ouml;&Atilde;&Ograve;&raquo;&cedil;&ouml;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Ecirc;&sup1;&Ouml;&reg;&sup3;&Eacute;&Icirc;&ordf;±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;
if( !SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr) )
{
ShowMessage("Redirecting STDOUT failed"
return FALSE;
}
// &acute;&acute;&frac12;¨&sup2;&raquo;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;&micro;&Auml;&para;&Aacute;&frac34;&auml;±ú&sup2;&cent;&sup1;&Oslash;±&Otilde;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;&micro;&Auml;&para;&Aacute;&frac34;&auml;±ú
fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup ,
0, FALSE,
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
ShowMessage("DuplicateHandle failed"
return FALSE;
}
CloseHandle( hChildStdoutRd );
// &Ouml;&Oslash;&para;¨&Iuml;ò×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;...
// ±&pound;&acute;&aelig;&micro;±&Ccedil;°±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&micro;&Auml;&frac34;&auml;±ú
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
//&Icirc;&ordf;×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&acute;&acute;&frac12;¨&Ograve;&raquo;&cedil;&ouml;&sup1;&Uuml;&micro;&Agrave;
if( !CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) )
{
ShowMessage("Stdin pipe creation failed"
return FALSE;
}
// &Eacute;è&Ouml;&Atilde;&Ograve;&raquo;&cedil;&ouml;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Ecirc;&sup1;&Ouml;&reg;&sup3;&Eacute;&Icirc;&ordf;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;
if( !SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd) )
{
ShowMessage("Redirecting Stdin failed"
return FALSE;
}
// &cedil;&acute;&Ouml;&AElig;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Otilde;&acirc;&Ntilde;ù&Euml;ü&frac34;&Iacute;&sup2;&raquo;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup,
0, FALSE, // not inherited
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
ShowMessage("DuplicateHandle failed"
return FALSE;
}
CloseHandle(hChildStdinWr);
// &acute;&acute;&frac12;¨×&Oacute;&frac12;&oslash;&sup3;&Igrave;
if( !CreateChildProcess(dwProcessId))
{
ShowMessage("CreateChildProcess failed"
return FALSE;
}
// ×&Oacute;&frac12;&oslash;&sup3;&Igrave;&acute;&acute;&frac12;¨&Iacute;ê±&Iuml;&pound;&not;&Ouml;&Oslash;&Ouml;&Atilde;&Iuml;&micro;&Iacute;&sup3;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&Ecirc;&auml;&sup3;&ouml;
if( !SetStdHandle(STD_INPUT_HANDLE, hSaveStdin) )
{
ShowMessage("Re-redirecting Stdin failed"
return FALSE;
}
if( !SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout) )
{
ShowMessage("Re-redirecting Stdout failed"
return FALSE;
}
return true;
}
BOOL TfrmMain::CreateChildProcess(DWORD& dwProcessId)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
// Set up members of STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESTDHANDLES;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdError = hChildStdoutWr;
TCHAR shellCmd[_MAX_PATH];
strcpy(shellCmd,"project2.exe"
// Create the child process.
BOOL ret = CreateProcess( NULL,
shellCmd, // applicatin name
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
DETACHED_PROCESS, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if( ret )
dwProcessId = piProcInfo.dwProcessId;
return ret;
}
void TfrmMain::WriteToPipe( LPCTSTR line )
{
DWORD dwWritten;
if (!WriteFile( hChildStdinWrDup, line, strlen(line)*sizeof(TCHAR),
&dwWritten, NULL ))
{
ShowMessage("&ETH;&acute;&Egrave;&euml;&Ecirc;§°&Uuml;"
}
}
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
CreateConsoleRedirect();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseHandle( hChildStdinRd);
CloseHandle( hChildStdoutWr);
CloseHandle( hChildStdinWrDup );
CloseHandle( hChildStdoutRdDup );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnReadClick(TObject *Sender)
{
char chBuf[4096];
AnsiString TempStr;
DWORD dwRead;
if (!ReadFile(hChildStdoutRdDup, chBuf,4096, &dwRead, NULL) || dwRead == 0) return;
TempStr=Trim(AnsiString(chBuf));
moMsg->Lines->Add(TempStr);
}
//---------------------------------------------------------------------------
没有问题,把客户端程序的字符都读出来了,但是第二次点的时候,即客户程序没有发送字符的时候,则出现死机现象,调试一下,是死在 if (!ReadFile(hChildStdoutRdDup, chBuf,4096, &dwRead, NULL) || dwRead == 0) return;
这一句,就是客户程序没有数据时边死在此,希望有经验的朋友指点一下,谢谢。。。
主程序启动客户程序,主程序中的project2.exe,就是客户程序的名字,客户程序是一个控制台程序代码如下:
int main(int argc, char* argv[])
{
for (int i=0;i<100;i++)
{
printf("123"
fflush(stdout);
}
getchar();
}
主程序如下:
头文件:
//---------------------------------------------------------------------------
#ifndef MainFrmH
#define MainFrmH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TfrmMain : public TForm
{
__published: // IDE-managed Components
TPageControl *pgcMain;
TTabSheet *tshMain;
TMemo *moMsg;
TButton *btnRead;
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall btnReadClick(TObject *Sender);
private:
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hSaveStdin, hSaveStdout;
DWORD dwProcessId;
BOOL CreateChildProcess(DWORD& dwProcessId);
bool CreateConsoleRedirect();
void WriteToPipe( LPCTSTR line );
public: // User declarations
__fastcall TfrmMain(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TfrmMain *frmMain;
//---------------------------------------------------------------------------
#endif
Cpp文件:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "MainFrm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain;
//---------------------------------------------------------------------------
bool TfrmMain::CreateConsoleRedirect()
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// &Ouml;&Oslash;&para;¨&Iuml;ò×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;...
// ±&pound;&acute;&aelig;&micro;±&Ccedil;°±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;&micro;&Auml;&frac34;&auml;±ú
hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( !CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0) )
{
ShowMessage("Stdout pipe creation failed"
return FALSE;
}
// &Eacute;è&Ouml;&Atilde;&Ograve;&raquo;&cedil;&ouml;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Ecirc;&sup1;&Ouml;&reg;&sup3;&Eacute;&Icirc;&ordf;±ê×&frac14;&Ecirc;&auml;&sup3;&ouml;
if( !SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr) )
{
ShowMessage("Redirecting STDOUT failed"
return FALSE;
}
// &acute;&acute;&frac12;¨&sup2;&raquo;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;&micro;&Auml;&para;&Aacute;&frac34;&auml;±ú&sup2;&cent;&sup1;&Oslash;±&Otilde;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;&micro;&Auml;&para;&Aacute;&frac34;&auml;±ú
fSuccess = DuplicateHandle( GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup ,
0, FALSE,
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
ShowMessage("DuplicateHandle failed"
return FALSE;
}
CloseHandle( hChildStdoutRd );
// &Ouml;&Oslash;&para;¨&Iuml;ò×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;...
// ±&pound;&acute;&aelig;&micro;±&Ccedil;°±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&micro;&Auml;&frac34;&auml;±ú
hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
//&Icirc;&ordf;×&Oacute;&frac12;&oslash;&sup3;&Igrave;&micro;&Auml;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&acute;&acute;&frac12;¨&Ograve;&raquo;&cedil;&ouml;&sup1;&Uuml;&micro;&Agrave;
if( !CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0) )
{
ShowMessage("Stdin pipe creation failed"
return FALSE;
}
// &Eacute;è&Ouml;&Atilde;&Ograve;&raquo;&cedil;&ouml;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Ecirc;&sup1;&Ouml;&reg;&sup3;&Eacute;&Icirc;&ordf;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;
if( !SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd) )
{
ShowMessage("Redirecting Stdin failed"
return FALSE;
}
// &cedil;&acute;&Ouml;&AElig;&ETH;&acute;&frac34;&auml;±ú&micro;&frac12;&sup1;&Uuml;&micro;&Agrave;&pound;&not;&Otilde;&acirc;&Ntilde;ù&Euml;ü&frac34;&Iacute;&sup2;&raquo;&iquest;&Eacute;&frac14;&Igrave;&sup3;&ETH;
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup,
0, FALSE, // not inherited
DUPLICATE_SAME_ACCESS );
if( !fSuccess )
{
ShowMessage("DuplicateHandle failed"
return FALSE;
}
CloseHandle(hChildStdinWr);
// &acute;&acute;&frac12;¨×&Oacute;&frac12;&oslash;&sup3;&Igrave;
if( !CreateChildProcess(dwProcessId))
{
ShowMessage("CreateChildProcess failed"
return FALSE;
}
// ×&Oacute;&frac12;&oslash;&sup3;&Igrave;&acute;&acute;&frac12;¨&Iacute;ê±&Iuml;&pound;&not;&Ouml;&Oslash;&Ouml;&Atilde;&Iuml;&micro;&Iacute;&sup3;±ê×&frac14;&Ecirc;&auml;&Egrave;&euml;&Ecirc;&auml;&sup3;&ouml;
if( !SetStdHandle(STD_INPUT_HANDLE, hSaveStdin) )
{
ShowMessage("Re-redirecting Stdin failed"
return FALSE;
}
if( !SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout) )
{
ShowMessage("Re-redirecting Stdout failed"
return FALSE;
}
return true;
}
BOOL TfrmMain::CreateChildProcess(DWORD& dwProcessId)
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
// Set up members of STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESTDHANDLES;
siStartInfo.hStdInput = hChildStdinRd;
siStartInfo.hStdOutput = hChildStdoutWr;
siStartInfo.hStdError = hChildStdoutWr;
TCHAR shellCmd[_MAX_PATH];
strcpy(shellCmd,"project2.exe"
// Create the child process.
BOOL ret = CreateProcess( NULL,
shellCmd, // applicatin name
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
DETACHED_PROCESS, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if( ret )
dwProcessId = piProcInfo.dwProcessId;
return ret;
}
void TfrmMain::WriteToPipe( LPCTSTR line )
{
DWORD dwWritten;
if (!WriteFile( hChildStdinWrDup, line, strlen(line)*sizeof(TCHAR),
&dwWritten, NULL ))
{
ShowMessage("&ETH;&acute;&Egrave;&euml;&Ecirc;§°&Uuml;"
}
}
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
CreateConsoleRedirect();
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action)
{
CloseHandle( hChildStdinRd);
CloseHandle( hChildStdoutWr);
CloseHandle( hChildStdinWrDup );
CloseHandle( hChildStdoutRdDup );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnReadClick(TObject *Sender)
{
char chBuf[4096];
AnsiString TempStr;
DWORD dwRead;
if (!ReadFile(hChildStdoutRdDup, chBuf,4096, &dwRead, NULL) || dwRead == 0) return;
TempStr=Trim(AnsiString(chBuf));
moMsg->Lines->Add(TempStr);
}
//---------------------------------------------------------------------------