1
votes

I've a SupportApp.EXE which if I launch manually from windows CMD prommpt like this ::

SupportApp.EXE -t 100 > AFile.csv

works perfcetly fine & it generates a CSV file for me.

Now I want to automate same thing inside a VC++ code. So, I use CreateProcess() API for this. Code snippet below ::

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

I see that CreateProcess() API succeeds and also i see that the -t 120 option I'm giving is also taken by this "SupportApp.exe" BUT the file redirection operator ">" is not working with CreateProcess() API.

Instead the output is directed to CMD itself. But I want output to be sent to a CSV file.

Can anyone please help me in how do I redirect the output of my "SupportApp.exe" to a file using CreateProcess() API from within my VC++ code ?

UPDATE 2:

The inputs given by reviewers are incorporated in this & the modified code snippet is below which takes the file hnadle in STARTUPINFO structure as follows::

The file is getting created but the file is empty & it doesn't have any contents from 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;

HANDLE 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)) { ... // log error } // success

2

2 Answers

3
votes

Output redirection is a shell feature, i.e. the shell sets that up before starting the child.

You're not using a shell, instead going directly to the kernel asking it to start a process, so you don't get that service.

You need to set up the required redirection yourself. This is done in the STARTUPINFO's hStdOutput member. See the documentation, of course.

3
votes

That's because the redirection operations (as well as the pipe operation) is part of the command prompt program, not part of the CreateProcess call.

However, you can do exactly what the command prompt program does when it does redirection, and set the file handles in the STARTUPINFO structure.