【问题标题】:File re-direction operator ">" doesn't work with CreateProcess() API文件重定向运算符“>”不适用于 CreateProcess() API
【发布时间】:2015-02-07 03:57:27
【问题描述】:

我有一个 SupportApp.EXE,如果我像这样从 Windows CMD 提示手动启动它::

SupportApp.EXE -t 100 > AFile.csv

工作得很好,它会为我生成一个 CSV 文件。

现在我想在 VC++ 代码中自动化同样的事情。 所以,我为此使用 CreateProcess() API。 下面的代码sn-p ::

TCHAR launcher[512];
    _tgetcwd(launcher, _MAX_PATH);
    TCHAR workDir[512];
    _tgetcwd(workDir, _MAX_PATH);
    _tcscat(launcher, "\\App\\SupportApp.exe");
    TCHAR cmdlineoption[512];
    _tcscpy(cmdlineoption, " -t 120 > AFile.csv");
LPTSTR appPath = (LPTSTR)cmdlineoption;


    STARTUPINFO sInfo;
    memset(&sInfo, 0, sizeof(sInfo));
    sInfo.cb = sizeof(sInfo);
    sInfo.dwFlags = STARTF_USESHOWWINDOW;
    sInfo.wShowWindow = SW_SHOWMAXIMIZED;

    PROCESS_INFORMATION pInfo;
    memset(&pInfo, 0, sizeof(pInfo));

    if (!CreateProcess(launcher, appPath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, workDir, &sInfo, &pInfo))
{
... // log error
}
// success

我看到 CreateProcess() API 成功,而且我看到我提供的 -t 120 选项也被这个“SupportApp.exe”采用 但是文件重定向运算符“>”不适用于 CreateProcess() API。

而是将输出定向到 CMD 本身。但我希望将输出发送到 CSV 文件。

谁能帮助我如何重定向我的输出 “SupportApp.exe”从我的内部使用 CreateProcess() API 到一个文件 VC++代码?

更新 2:

审稿人给出的输入已包含在其中,修改后的代码 sn-p 在下面,它采用 STARTUPINFO 结构中的文件 hnadle,如下所示::

正在创建文件,但文件为空且没有来自 createProcess() 的任何内容?

TCHAR launcher[512];
        _tgetcwd(launcher, _MAX_PATH);
        TCHAR workDir[512];
        _tgetcwd(workDir, _MAX_PATH);
        _tcscat(launcher, "\\App\\SupportApp.exe");
        TCHAR cmdlineoption[512];
        _tcscpy(cmdlineoption, " -t 120 > AFile.csv");
    LPTSTR appPath = (LPTSTR)cmdlineoption;


        STARTUPINFO sInfo;
        memset(&sInfo, 0, sizeof(sInfo));
        sInfo.cb = sizeof(sInfo);
        sInfo.dwFlags |= STARTF_USESTDHANDLES; //newly added
        sInfo.wShowWindow = SW_SHOWMAXIMIZED;

        PROCESS_INFORMATION pInfo;
        memset(&pInfo, 0, sizeof(pInfo));

        sInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
        sInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);        

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

处理 hn;

if(INVALID_HANDLE_VALUE != (hn = CreateFile(L"DoneDone.csv", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0))) { sInfo.hStdOutput = =hn; } if (!CreateProcess(launcher, appPath, NULL, NULL, FALSE, 0, NULL, workDir, &sInfo, &pInfo)) { ... // 记录错误 } // 成功

【问题讨论】:

    标签: c++ c visual-c++ file-io createprocess


    【解决方案1】:

    输出重定向是一个 shell 功能,即 shell 在启动子进程之前设置它。

    您没有使用 shell,而是直接进入内核要求它启动一个进程,因此您无法获得该服务。

    您需要自己设置所需的重定向。这是在STARTUPINFOhStdOutput 成员中完成的。当然,请参阅the documentation

    【讨论】:

    • 能否请您提供一个代码示例,说明如何使用 STARTUPINFO 的 hStdOutput 字段实现此重定向?
    【解决方案2】:

    这是因为重定向操作(以及管道操作)是命令提示符程序的一部分,而不是 CreateProcess 调用的一部分。

    但是,您可以完全按照命令提示程序执行重定向时所做的操作,并在STARTUPINFO 结构中设置文件句柄。

    【讨论】:

    • 能否请您提供一个代码示例,说明如何使用 STARTUPINFO 的 hStdOutput 字段实现此重定向?
    • @codeLover 有关如何打开文件的信息,请参阅 this CreateFile reference。只需将返回的句柄分配给结构的hStdOutput。网上搜索一下CreateFileCreateProcess的“重定向”例子很多。
    • 我尝试将 CreateProcess() 与 CreateFile() 一起使用,并将文件的 HANDLE 提供给结构 STARTUPINFO 的“hStdOutput”文件。但是我看到输出没有被重定向到我使用 CreateFile 创建的文件。任何指针为什么会这样?
    • @codeLover 您确实检查了文件是否已正确打开,并且处于正确的模式?此外,更新您的问题以显示新代码和您的新体验。
    • 是的,我确实检查了文件权限,并使用“Update2 部分”中的新代码更新了这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多