25

我尝试使用 CreateProcess 运行一个简单的命令,例如hg > test.txt. 我尝试将字符串作为一个整体运行(而不是将其分成应用程序名称及其参数)。为什么CreateProcess(0, "notepad.exe test.txt", ...)有效但CreateProcess(0, "hg > test.txt", ...)无效?

4

5 回答 5

29

下面的代码创建了一个无控制台进程,其中 stdout 和 stderr 重定向到指定的文件。

#include <windows.h>


int _tmain(int argc, _TCHAR* argv[])
{
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;       

    HANDLE h = CreateFile(_T("out.log"),
        FILE_APPEND_DATA,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        &sa,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL );

    PROCESS_INFORMATION pi; 
    STARTUPINFO si;
    BOOL ret = FALSE; 
    DWORD flags = CREATE_NO_WINDOW;

    ZeroMemory( &pi, sizeof(PROCESS_INFORMATION) );
    ZeroMemory( &si, sizeof(STARTUPINFO) );
    si.cb = sizeof(STARTUPINFO); 
    si.dwFlags |= STARTF_USESTDHANDLES;
    si.hStdInput = NULL;
    si.hStdError = h;
    si.hStdOutput = h;

    TCHAR cmd[]= TEXT("Test.exe 30");
    ret = CreateProcess(NULL, cmd, NULL, NULL, TRUE, flags, NULL, NULL, &si, &pi);

    if ( ret ) 
    {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return 0;
    }

    return -1;
}
于 2013-04-27T19:44:57.043 回答
25

您不能在传递给CreateProcess. 要重定向标准输出,您需要为结构中的输出指定文件句柄STARTUPINFO

你也在犯另一个更微妙的错误。第二个参数,lpCommandLine必须指向可写内存,因为会CreateProcess覆盖缓冲区。如果您碰巧使用的是函数的 ANSI 版本,那么您将侥幸逃脱,但对于 Unicode 版本则不行。

此函数的 Unicode 版本CreateProcessW可以修改此字符串的内容。因此,此参数不能是指向只读内存的指针(例如const变量或文字字符串)。如果此参数是一个常量字符串,该函数可能会导致访问冲突。

于 2011-08-10T21:45:59.730 回答
9

微软有一个如何重定向标准输出的例子:http: //msdn.microsoft.com/en-us/library/ms682499 (VS.85).aspx 。

于 2011-08-10T23:34:25.260 回答
7

CreateProcess() 启动进程,它不是命令行 itnerpreter。它不知道“>”是什么,也不会为您进行流重定向。您需要自己打开文件 test.txt 并将其句柄传递给 STARTUPINFO 结构内的 CreateProcess: CreateProcess STARTUPINFO

于 2011-08-10T21:46:30.023 回答
-1

您应该使用参数“/c 命令行”运行进程 cmd.exe。这会将输出重定向到文件或通过 CreateProcess 组织管道。

于 2013-08-21T11:04:24.943 回答