La Capture de la Sortie de a Engendré des Processus de la chaîne
De fond:
Je suis en train de travailler sur un programme qui doit être en mesure de saisir les stdout
, stderr
et les valeurs de retour d'un programme. Idéalement, je voudrais saisir ces dans une chaîne que je stocker à l'intérieur de mon objet qui contient les détails du processus. Actuellement j'ai un code qui fonctionne par enregistrer la sortie dans un fichier à l'aide de certains (à mon avis) archaïque C descripteur de fichier de la magie. De tout temps que je veux en sortie les résultats, j'ouvre ce fichier et je l'ai imprimer le contenu.
Parfois (quand je m'y frayer est gauche en cours d'exécution) de la prochaine exécution de mon exécutable se décomposer, car il est impossible d'ouvrir le fichier pour l'écriture.
Énoncé Du Problème:
Je suis à la recherche d'un moyen de sauver la sortie de stdout
d'un processus créé dans windows pour une chaîne de caractères et la stderr
à l'autre dans un endroit plus sûr, plus moderne de la mode. De cette façon, je pouvais imprimer le contenu de tout temps j'ai envie de sortir le résultat de chaque processus créé.
Mon laid code:
principal bloc-
int stdoutold = _dup(_fileno(stdout)); //make a copy of stdout
int stderrold = _dup(_fileno(stdout)); //make a copy of stderr
FILE *f;
if(!fopen_s(&f, "name_of_my_file", "w")){ //make sure I can write to the file
_dup2(_fileno(f), _fileno(stdout)); //make stdout point to f
_dup2(_fileno(f), _fileno(stderr)); //make stderr point to f
fork("command_I_want_to_run", &pi); //run my fake fork (see below)
}
else{
...//error handling
}
_close(_fileno(stdout)); //close tainted stdout
_close(_fileno(stderr)); //close tainted stderr
_close(_fileno(f)); //close f
_dup2(stdoutold, _fileno(stdout)); //fix stdout
_dup2(stderrold, _fileno(stderr)); //fix stderr
fourche- (vous pouvez considérer cela comme juste CreateProcess, mais juste au cas où quelqu'un a besoin de voir ce qui se passe ici)
int fork(std::string s, PROCESS_INFORMATION* pi){
char infoBuf[INFO_BUFFER_SIZE];
int bufCharCount =
ExpandEnvironmentStrings(s.c_str(), infoBuf, INFO_BUFFER_SIZE );
...
STARTUPINFO si;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( pi, sizeof(*pi) );
LPSTR str = const_cast<char *>(infoBuf);
if(!CreateProcess(NULL,
str,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
pi)
){
int err = GetLastError();
printf("CreateProcess failed (%d).\n", err);
CloseHandle((*pi).hProcess);
CloseHandle((*pi).hThread);
return err;
}
return 0;
}
Notes:
- Je suis avec VS 2010
- Je veux rester à l'aide de plusieurs processus, threads, car j'ai besoin de ce que j'ai exécuté pour avoir la liberté de ses propres processus
Edit:
Une note: j'ai aussi essayer d'attendre la fin du processus de droit après l'appel de la fonction qui exécute le code donné, si les résultats de stdout
et stderr
sont disponibles pour moi à l'époque.
- Connexes: lancer un exe/processus avec stdin, stdout et stderr?. Aussi, voir minuscule-processus-de la bibliothèque qui est très pratique.
Vous devez vous connecter pour publier un commentaire.
Eddy Luten de réponse m'a conduit dans une bonne direction, mais la documentation MSDN (alors qu'élaborée) a eu quelques problèmes. Principalement, vous devez vous assurer que vous fermez toutes les poignées vous ne l'utilisez pas. Aussi, il a juste le code qu'il attend que l'utilisateur à comprendre.
Donc à la place, voici mon mur de code j'espère que les gens il suffit de comprendre 😀
Vous aurez à utiliser des tuyaux à capturer le contenu de votre processus de flux stdout. Il y a un complexe exemple sur MSDN sur la façon d'accomplir ceci:
MSDN: la Création d'un Processus Enfant avec Redirigé Entrée et de Sortie
Shawn Blakesley code est bon de retravailler de Microsoft exemple de code, mais il a un peu un problème quand il est massive stdout et stderr entrelacés des flux qui sont hors de l'ordre. Et quelques poignées de fuite (qui est OK pour l'exemple de code). Ayant thread d'arrière-plan et PeekNamedPipe() appelle assure que le code se comportent de plus en plus semblables à POSIX appel système: