本文介绍了CreateProcess和CreatePipe在VC ++中执行进程并以字符串形式返回输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 CreateProcess CreatePipe 从Windows Forms C ++ / CLR应用程序中执行进程在Visual Studio 2010中。



从Windows窗体应用程序中,我想执行一个子进程(控制台应用程序)并以 std的形式返回输出:: string std :: wstring System :: String ^ Windows窗体应用程序。另外,我不希望新创建的子进程产生一个窗口。



控制台应用程序是我自己创建的,因此我也可以控制它的源。 / p>

我看过以下示例,但是我不明白如何修改代码以完成我要执行的操作:









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



有没有比MSDN的200多行代码或kgui的300条更简单的方法了? +代码行?



答案很有帮助,但过于简单。我希望看到一个基本的源示例(最好不涉及数百行复杂代码的示例)。本来可以使用MFC代码,但是我很难适应它的用途(我没有使用MFC)。



以下是我对Code中代码的改编项目:

  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;

处理rPipe,wPipe;

//创建用于写入和读取数据的管道

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;

//在此处创建流程。

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

//现在在此处读取输出管道。

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

我已尝试在Windows Forms应用程序中使用此程序,尽管它可以编译好的,不会造成任何错误,它似乎也不起作用。我不知道为什么。



这是我执行上面代码的方式:

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

它似乎没有做任何事情,只是在第一次执行时给出了一个非常奇怪的3个字符

解决方案

感谢Hans Passant提供的使我明白了这段清晰,简单的代码,正是我所要做的

  ///此名称空间调用对于其余代码使用名称空间工作
是必需的系统::诊断;
使用名称空间System :: Text; ///添加用于编码

Process ^ myprocess = gcnew Process;
Encoding ^编码; ///添加用于编码
Encoding-> GetEncoding(GetOEMCP()); ///添加用于编码

myprocess-> StartInfo-> ; FileName = ping.exe;
myprocess-> StartInfo-> Arguments = 127.0.0.1;
myprocess-> StartInfo-> UseShellExecute = false;

///添加了下一行,以防止打开
新窗口myprocess-> StartInfo-> CreateNoWindow = true;

myprocess-> StartInfo-> RedirectStandardOutput = true;
myprocess-> StartInfo-> StandardOutputEncoding =编码; ///添加用于编码
myprocess-> Start();

String ^输出= gcnew String(myprocess-> StandardOutput-> ReadToEnd());

myprocess-> WaitForExit();

/// OutputBox是我的应用程序中Windows窗体文本框的名称。
OutputBox->文本=输出;

编辑:添加了编码信息。参见上面的代码。


I am trying to use CreateProcess and CreatePipe to execute a process from within a Windows Forms C++/CLR application in Visual Studio 2010.

From within my Windows forms app I want to execute a child process (console app) and return the output as a std::string, std::wstring, or System::String^ within my Windows forms app. Additionally, I do not want the newly created child process to spawn a window.

The console application is of my own creation, so I have control of it's source too.

I have seen the following examples, but I do not understand how to modify the code to accomplish what I am trying to do:

The MSDN code appears to be written as two console apps, one calling the other. The code is confusing to me. I've only been working in C++ for about 4 months, so I still don't understand everything. It appears to reference a text file, which I don't need to do.

Is there a simpler way to do this than MSDN's 200+ lines of code or kgui's 300+ lines of code?

The answer here was helpful, but over simplistic. I was hoping to see a basic source example (one that doesn't involve hundreds of lines of complex code would be preferable). I would have used the MFC code, but I had difficulty adapting it to my purposes (I'm not using MFC).

Following is my adaptation of the code from Code Project:

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;
}

I have tried using this from within my Windows Forms app, and while it compiles ok and doesn't cause any errors, it doesn't seem to work either. I have no idea why.

This is how I executed the above code:

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

It did not appear to do anything, except that on the first execution it give a very strange 3 characters as an output, then on subsequent executions, nothing.

解决方案

Thanks to Hans Passant for the lead that got me to this clear and simple piece of code that does exactly what I was looking for.

/// this namespace call is necessary for the rest of the code to work
using namespace System::Diagnostics;
using namespace System::Text;/// added for encoding

Process^ myprocess = gcnew Process;
Encoding^ Encoding;/// added for encoding
Encoding->GetEncoding(GetOEMCP());/// added for encoding

myprocess->StartInfo->FileName = "ping.exe";
myprocess->StartInfo->Arguments = "127.0.0.1";
myprocess->StartInfo->UseShellExecute = false;

/// added the next line to keep a new window from opening
myprocess->StartInfo->CreateNoWindow = true;

myprocess->StartInfo->RedirectStandardOutput = true;
myprocess->StartInfo->StandardOutputEncoding = Encoding;/// added for encoding
myprocess->Start();

String^ output = gcnew String( myprocess->StandardOutput->ReadToEnd() );

myprocess->WaitForExit();

/// OutputBox is the name of a Windows Forms text box in my app.
OutputBox->Text = output;

EDIT: Added encoding information. See above code.

这篇关于CreateProcess和CreatePipe在VC ++中执行进程并以字符串形式返回输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 15:35