gpt4 book ai didi

c++ - CreateProcess 和 CreatePipe 执行进程并在 VC++ 中以字符串形式返回输出

转载 作者:太空狗 更新时间:2023-10-29 20:29:57 24 4
gpt4 key购买 nike

我正在尝试使用 CreateProcessCreatePipe 从 Visual Studio 2010 中的 Windows 窗体 C++/CLR 应用程序中执行进程。

在我的 Windows 窗体应用程序中,我想执行一个子进程(控制台应用程序)并将输出作为 std::stringstd::wstring 返回,或我的 Windows 窗体应用程序中的 System::String^。此外,我不希望新创建的子进程产生一个窗口。

控制台应用程序是我自己创建的,所以我也可以控制它的源代码。

我看过下面的例子,但我不明白如何修改代码来完成我想做的事情:

MSDN 代码似乎是作为两个控制台应用程序编写的,一个调用另一个。代码让我感到困惑。我只用 C++ 工作了大约 4 个月,所以我仍然不了解所有内容。它似乎引用了一个文本文件,我不需要这样做。

是否有比 MSDN 的 200 多行代码或 kgui 的 300 多行代码更简单的方法?

答案here很有帮助,但过于简单化。我希望看到一个基本的源代码示例(最好不要涉及数百行复杂代码)。我会使用 MFC 代码,但我很难根据我的目的调整它(我没有使用 MFC)。

以下是我改编自代码项目的代码:

string ExecuteExternalFile(string csExeName, string csArguments)
{
string csExecute;
csExecute=csExeName + " " + csArguments;

SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr,sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;

HANDLE rPipe, wPipe;

//Create pipes to write and read data

CreatePipe(&rPipe,&wPipe,&secattr,0);
//

STARTUPINFO sInfo;
ZeroMemory(&sInfo,sizeof(sInfo));
PROCESS_INFORMATION pInfo;
ZeroMemory(&pInfo,sizeof(pInfo));
sInfo.cb=sizeof(sInfo);
sInfo.dwFlags=STARTF_USESTDHANDLES;
sInfo.hStdInput=NULL;
sInfo.hStdOutput=wPipe;
sInfo.hStdError=wPipe;

//Create the process here.

CreateProcess(0,(LPWSTR)csExecute.c_str(),0,0,TRUE,NORMAL_PRIORITY_CLASS|CREATE_NO_WINDOW,0,0,&sInfo,&pInfo);
CloseHandle(wPipe);

//now read the output pipe here.

char buf[100];
DWORD reDword;
string m_csOutput,csTemp;
BOOL res;
do
{
res=::ReadFile(rPipe,buf,100,&reDword,0);
csTemp=buf;
m_csOutput+=csTemp;
}while(res);
return m_csOutput;
}

我已经尝试在我的 Windows 窗体应用程序中使用它,虽然它编译正常并且不会导致任何错误,但它似乎也不起作用。我不知道为什么。

我是这样执行上面的代码的:

std::string ping = ExecuteExternalFile("ping.exe", "127.0.0.1");

它似乎没有做任何事情,除了在第一次执行时它给出了一个非常奇怪的 3 个字符作为输出,然后在后续执行中,什么也没做。

最佳答案

您没有正确使用 ::ReadFile() 函数。

在这里阅读:http://msdn.microsoft.com/en-us/library/ms891445.aspx

基本上,如果函数不返回 TRUE,您希望失败并返回错误,并且您希望继续循环直到它产生零 reDword。

此外,::ReadFile() 不会为您对数据进行零终止,因此您必须自己完成,如下所示:buf[reDword] = '\0' ;(确保你的 buf 是 101 个字符,然后再这样做。)

编辑:因为我被要求提供一些示例代码,所以在这里,虽然我没有经历实际编译它以确保它工作的麻烦,所以请注意语法错误,并且通常将它视为指向应该做的方向:

#define BUFFER_SIZE 100
string csoutput;
for( ;; )
{
char buf[BUFFER_SIZE+1];
DWORD redword;
if( !::ReadFile(rPipe,buf,BUFFER_SIZE,&redword,0) )
{
DWORD error = ::GetLastError();
//throw new Exception( "Error " + error ); //or something similar
}
if( redword == 0 )
break;
buf[redword] = '\0';
string cstemp = buf;
csoutput += cstemp;
}
return csoutput;

关于c++ - CreateProcess 和 CreatePipe 执行进程并在 VC++ 中以字符串形式返回输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8547999/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com