web-dev-qa-db-fra.com

Comment rediriger la sortie vers un fichier avec CreateProcess?

J'ai essayé d'utiliser CreateProcess pour exécuter une commande simple comme hg > test.txt. J'ai essayé d'exécuter la chaîne dans son ensemble (par opposition à la séparer en un nom d'application et ses paramètres). Pourquoi CreateProcess(0, "notepad.exe test.txt", ...) fonctionne mais CreateProcess(0, "hg > test.txt", ...) ne fonctionne pas?

25
Paul Manta

Vous ne pouvez pas utiliser la redirection stdout dans la ligne de commande passée à CreateProcess . Pour rediriger stdout, vous devez spécifier un descripteur de fichier pour la sortie dans la structure STARTUPINFO .

Vous faites également une autre erreur, plus subtile. Le deuxième paramètre, lpCommandLine doit pointer vers la mémoire inscriptible car CreateProcess écrase le tampon. Si vous utilisez la version ANSI de la fonction, vous vous en sortirez, mais pas pour la version Unicode.

La version Unicode de cette fonction, CreateProcessW , peut modifier le contenu de cette chaîne. Par conséquent, ce paramètre ne peut pas être un pointeur vers la mémoire morte (comme une variable const ou une chaîne littérale). Si ce paramètre est une chaîne constante, la fonction peut provoquer une violation d'accès.

23
David Heffernan

Le code ci-dessous crée un processus sans console avec stdout et stderr redirigés vers le fichier spécifié.

#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;
}
24
Lukas Koblovsky

Microsoft a un exemple comment rediriger la sortie standard: http://msdn.Microsoft.com/en-us/library/ms682499 (VS.85) .aspx .

8
Tamas Demjen

CreateProcess () lance des processus, ce n'est pas un itnerpreter de ligne de commande. Il ne sait pas ce qu'est ">" et ne fera pas la redirection de flux pour vous. Vous devez ouvrir le fichier test.txt vous-même et lui passer le handle vers CreateProcess dans la structure STARTUPINFO: CreateProcess STARTUPINFO

7
MK.