2011-05-30 38 views
1

我想在Windows外壳执行命令。我想要收到结果。我试图搜索win32控制台功能。但是,我没有看到任何字符返回功能。有人能帮我吗?我正在Qt中做这件事。所以如果解决方案在Qt中就没有问题。C++ - Windows的 - 如何(写入&&读取)命令外壳

注:有没有办法像linux一样写入端口?

编辑: 在这种情况下可以使用QProcess吗?

+0

标题说“如何写”,但问题的主体说:“我魔杖接收结果”。你想读取或写入产生的过程? – 2011-05-30 13:25:12

+0

@Eric我需要两个。我编辑了这个问题 – prabhakaran 2011-05-31 07:26:24

回答

2

您应该创建另一个进程,执行cmd,并通过管道访问其stdin-stdout。 看here例如

+0

你可以给我一个存根: – prabhakaran 2011-05-30 07:34:11

+0

http://msdn.microsoft.com/en-us/library/ms682499%28v=VS.85%29.aspx - 这正是你需要的 - 在这里stdin和stdout被重定向。我之前的例子只是调用CreateProcess ... – Raiv 2011-05-30 07:51:54

1

我认为你正在寻找管道运行。见MSDN。从MSDN

代码父进程:

#include <windows.h> 
#include <tchar.h> 
#include <stdio.h> 
#include <strsafe.h> 

#define BUFSIZE 4096 

HANDLE g_hChildStd_IN_Rd = NULL; 
HANDLE g_hChildStd_IN_Wr = NULL; 
HANDLE g_hChildStd_OUT_Rd = NULL; 
HANDLE g_hChildStd_OUT_Wr = NULL; 

HANDLE g_hInputFile = NULL; 

void CreateChildProcess(void); 
void WriteToPipe(void); 
void ReadFromPipe(void); 
void ErrorExit(PTSTR); 

int _tmain(int argc, TCHAR *argv[]) 
{ 
    SECURITY_ATTRIBUTES saAttr; 

    printf("\n->Start of parent execution.\n"); 

// Set the bInheritHandle flag so pipe handles are inherited. 

    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

// Create a pipe for the child process's STDOUT. 

    if (! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) 
     ErrorExit(TEXT("StdoutRd CreatePipe")); 

// Ensure the read handle to the pipe for STDOUT is not inherited. 

    if (! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) 
     ErrorExit(TEXT("Stdout SetHandleInformation")); 

// Create a pipe for the child process's STDIN. 

    if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
     ErrorExit(TEXT("Stdin CreatePipe")); 

// Ensure the write handle to the pipe for STDIN is not inherited. 

    if (! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) 
     ErrorExit(TEXT("Stdin SetHandleInformation")); 

// Create the child process. 

    CreateChildProcess(); 

// Get a handle to an input file for the parent. 
// This example assumes a plain text file and uses string output to verify data flow. 

    if (argc == 1) 
     ErrorExit(TEXT("Please specify an input file.\n")); 

    g_hInputFile = CreateFile(
     argv[1], 
     GENERIC_READ, 
     0, 
     NULL, 
     OPEN_EXISTING, 
     FILE_ATTRIBUTE_READONLY, 
     NULL); 

    if (g_hInputFile == INVALID_HANDLE_VALUE) 
     ErrorExit(TEXT("CreateFile")); 

// Write to the pipe that is the standard input for a child process. 
// Data is written to the pipe's buffers, so it is not necessary to wait 
// until the child process is running before writing data. 

    WriteToPipe(); 
    printf("\n->Contents of %s written to child STDIN pipe.\n", argv[1]); 

// Read from pipe that is the standard output for child process. 

    printf("\n->Contents of child process STDOUT:\n\n", argv[1]); 
    ReadFromPipe(); 

    printf("\n->End of parent execution.\n"); 

// The remaining open handles are cleaned up when this process terminates. 
// To avoid resource leaks in a larger application, close handles explicitly. 

    return 0; 
} 

void CreateChildProcess() 
// Create a child process that uses the previously created pipes for STDIN and STDOUT. 
{ 
    TCHAR szCmdline[]=TEXT("child"); 
    PROCESS_INFORMATION piProcInfo; 
    STARTUPINFO siStartInfo; 
    BOOL bSuccess = FALSE; 

// Set up members of the PROCESS_INFORMATION structure. 

    ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION)); 

// Set up members of the STARTUPINFO structure. 
// This structure specifies the STDIN and STDOUT handles for redirection. 

    ZeroMemory(&siStartInfo, sizeof(STARTUPINFO)); 
    siStartInfo.cb = sizeof(STARTUPINFO); 
    siStartInfo.hStdError = g_hChildStd_OUT_Wr; 
    siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; 
    siStartInfo.hStdInput = g_hChildStd_IN_Rd; 
    siStartInfo.dwFlags |= STARTF_USESTDHANDLES; 

// Create the child process. 

    bSuccess = CreateProcess(NULL, 
     szCmdline,  // command line 
     NULL,   // process security attributes 
     NULL,   // primary thread security attributes 
     TRUE,   // handles are inherited 
     0,    // creation flags 
     NULL,   // use parent's environment 
     NULL,   // use parent's current directory 
     &siStartInfo, // STARTUPINFO pointer 
     &piProcInfo); // receives PROCESS_INFORMATION 

    // If an error occurs, exit the application. 
    if (! bSuccess) 
     ErrorExit(TEXT("CreateProcess")); 
    else 
    { 
     // Close handles to the child process and its primary thread. 
     // Some applications might keep these handles to monitor the status 
     // of the child process, for example. 

     CloseHandle(piProcInfo.hProcess); 
     CloseHandle(piProcInfo.hThread); 
    } 
} 

void WriteToPipe(void) 

// Read from a file and write its contents to the pipe for the child's STDIN. 
// Stop when there is no more data. 
{ 
    DWORD dwRead, dwWritten; 
    CHAR chBuf[BUFSIZE]; 
    BOOL bSuccess = FALSE; 

    for (;;) 
    { 
     bSuccess = ReadFile(g_hInputFile, chBuf, BUFSIZE, &dwRead, NULL); 
     if (! bSuccess || dwRead == 0) break; 

     bSuccess = WriteFile(g_hChildStd_IN_Wr, chBuf, dwRead, &dwWritten, NULL); 
     if (! bSuccess) break; 
    } 

// Close the pipe handle so the child process stops reading. 

    if (! CloseHandle(g_hChildStd_IN_Wr)) 
     ErrorExit(TEXT("StdInWr CloseHandle")); 
} 

void ReadFromPipe(void) 

// Read output from the child process's pipe for STDOUT 
// and write to the parent process's pipe for STDOUT. 
// Stop when there is no more data. 
{ 
    DWORD dwRead, dwWritten; 
    CHAR chBuf[BUFSIZE]; 
    BOOL bSuccess = FALSE; 
    HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 

// Close the write end of the pipe before reading from the 
// read end of the pipe, to control child process execution. 
// The pipe is assumed to have enough buffer space to hold the 
// data the child process has already written to it. 

    if (!CloseHandle(g_hChildStd_OUT_Wr)) 
     ErrorExit(TEXT("StdOutWr CloseHandle")); 

    for (;;) 
    { 
     bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL); 
     if(! bSuccess || dwRead == 0) break; 

     bSuccess = WriteFile(hParentStdOut, chBuf, 
          dwRead, &dwWritten, NULL); 
     if (! bSuccess) break; 
    } 
} 

void ErrorExit(PTSTR lpszFunction) 

// Format a readable error message, display a message box, 
// and exit from the application. 
{ 
    LPVOID lpMsgBuf; 
    LPVOID lpDisplayBuf; 
    DWORD dw = GetLastError(); 

    FormatMessage(
     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM | 
     FORMAT_MESSAGE_IGNORE_INSERTS, 
     NULL, 
     dw, 
     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
     (LPTSTR) &lpMsgBuf, 
     0, NULL); 

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
     (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
     LocalSize(lpDisplayBuf)/sizeof(TCHAR), 
     TEXT("%s failed with error %d: %s"), 
     lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf); 
    LocalFree(lpDisplayBuf); 
    ExitProcess(1); 
} 
0

您可以使用QProcess中。它有两种方法:标准输出为readAllStandardOutput,标准错误为readAllStandardError。但你不能使用startDetached。