Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
1427 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  redirection de sortie CreateProcessW

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

redirection de sortie CreateProcessW

n°2147526
zownierd
Posté le 29-06-2012 à 09:21:32  profilanswer
 

Plop !
 
J'ai un petit problème en ce moment, je fais tourner un programme qui fait appel à la fonction CreateProcess pour lancer des programmes en ligne de commande externes. Pour récupérer la sortie de ces programmes, jusqu'à présent je lançais "CMD /C commande.exe >> c:\logs.txt", de cette façon, je peut récupérer les sorties des programmes ... sauf que cette sortie n'inclut pas tout ce qu'on voit quand on lance la commande dans le cmd de windows ... J'ai besoin d'accéder au flux d'erreurs stdErr ... Sur Java, j'avais juste besoin de faire à un moment un truc comme process.redirectErrorStream(true).
J'ai cherché sur c++ et je suis tombé sur ça entres autres, et j'ai essayé de faire un mix de tout, ou même d'en mettre le minimum, mais ça ne marche désespérément pas x)
 

Code :
  1. ;
  2.     STARTUPINFO siStartupInfo;
  3.     PROCESS_INFORMATION piProcessInfo;
  4.     memset(&siStartupInfo, 0, sizeof(siStartupInfo));
  5.     memset(&piProcessInfo, 0, sizeof(piProcessInfo));
  6.     SECURITY_ATTRIBUTES sa;
  7.     sa.bInheritHandle = true;
  8.     HANDLE h = CreateFile(TEXT("c:\\temp\\logs.txt" ),
  9.                           GENERIC_WRITE|GENERIC_READ,
  10.                           FILE_SHARE_READ,
  11.                           &sa,
  12.                           CREATE_ALWAYS,
  13.                           FILE_ATTRIBUTE_NORMAL,
  14.                           NULL);
  15.     siStartupInfo.cb = sizeof(siStartupInfo);
  16.     if(h != INVALID_HANDLE_VALUE)
  17.     {
  18.         SetFilePointer(h, 0L, NULL, FILE_END);
  19.         siStartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  20.         siStartupInfo.hStdOutput = h;
  21.         siStartupInfo.hStdError = h;
  22.     }
  23.     if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
  24.                        pwszParam, 0, 0, true,
  25.                        /*CREATE_DEFAULT_ERROR_MODE*/CREATE_NO_WINDOW, 0, 0,
  26.                        &siStartupInfo, &piProcessInfo) != false)


 
 
avec un "cout", j'ai remarqué que le programme n'entrait même pas dans  "if(h != INVALID_HANDLE_VALUE)", donc il y a au moins un bug avant ça.
J'ai du surement mal initialiser mon HANDLE, mais je vois pas trop comment ... :(
Je mix des choses qui me paraissent logiques mais au fond je comprends pas assez pour résoudre les bugs s'il y en a qui surviennent x) Des DWORD, des HANDLE, des STARTUPINFO, ... charabia tout ça!
 
merci d'avance :)


Message édité par gilou le 29-06-2012 à 11:42:30
mood
Publicité
Posté le 29-06-2012 à 09:21:32  profilanswer
 

n°2147547
gilou
Modérateur
Modzilla
Posté le 29-06-2012 à 11:52:04  profilanswer
 

Pour tes deux premiers memset, perso, je ferais memset(&siStartupInfo, 0, sizeof(STARTUPINFO)) et memset(&piProcessInfo, 0, sizeof(PROCESS_INFORMATION)) mais c'est peut être juste une question de goûts.
 
A tout hasard, tu a essayé de faire un remplissage a zéro aussi pour le sécurity attribute?
 
    SECURITY_ATTRIBUTES sa;
    memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = true;
 
A+,


Message édité par gilou le 29-06-2012 à 11:54:30

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2147549
breizhbugs
Posté le 29-06-2012 à 11:53:51  profilanswer
 

D'après http://msdn.microsoft.com/en-us/li [...] 85%29.aspx et la doc, tu as mal initialise ton SECURITY_ATTRIBUTES:
SECURITY_ATTRIBUTES sa;  
sa.nLength = sizeof(SECURITY_ATTRIBUTES);  
sa.bInheritHandle = TRUE;  
sa.lpSecurityDescriptor = NULL;  
 
 
Ensuite tu dis que si il ne rentre pas dans le if ligne 20, c'est que h doit avoir une autre valeur: il te suffit donc de lire la doc de createfile() et de traiter tous les cas d'erreur (utilise la fonction ErrorExit() du lien ci dessus pour voir un descriptif de l'erreur)
 
edit: grilled!


Message édité par breizhbugs le 29-06-2012 à 11:54:18

---------------
Seul Google le sait...
n°2147551
gilou
Modérateur
Modzilla
Posté le 29-06-2012 à 11:56:00  profilanswer
 

A moitié grilled, le temps que j'ajoute une ligne d'initialisation manquante ( sa.nLength = sizeof(SECURITY_ATTRIBUTES); )  tu avais posté ;)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2147586
zownierd
Posté le 29-06-2012 à 14:55:15  profilanswer
 

Merci pour la correction :) Ça marche mieux mais il y a encore un petit truc que je n'arrive pas à cerner :/ je sais pas si vous auriez une idée ^^ :
quand le programme lancé est : "psexec \\monpc ipconfig", le programme reste bloqué sur WaitForSingleObject( , ), le processus semble ne pas se finir...
alors que quand je fais "psexec \\monpc echo && ipconfig" tout se passe bien !
(je précise que ça ne vient pas de psexec a priori, ces commandes marchent très bien dans l’interpréteur de Windows).

 

Étant donné que ça ne vient pas forcément du code, je peux m'arranger pour ajouter simplement "echo && " au début de chaque commande au pire :/

 
Code :
  1. ;
  2.     STARTUPINFO siStartupInfo;
  3.     PROCESS_INFORMATION piProcessInfo;
  4.     memset(&siStartupInfo, 0, sizeof(STARTUPINFO));
  5.     memset(&piProcessInfo, 0, sizeof(PROCESS_INFORMATION));
  6.     SECURITY_ATTRIBUTES sa;
  7.     memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
  8.     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  9.     sa.bInheritHandle = true;
  10.     sa.lpSecurityDescriptor = NULL;
  11.     HANDLE h = CreateFile(L"c:\\temp\\logs.radm",
  12.                           GENERIC_WRITE|GENERIC_READ,
  13.                           FILE_SHARE_READ|FILE_SHARE_WRITE,
  14.                           &sa,
  15.                           CREATE_NEW,
  16.                           FILE_ATTRIBUTE_NORMAL,
  17.                           NULL);
  18.     SetFilePointer(h, 0L, NULL, FILE_END);
  19.     siStartupInfo.cb = sizeof(STARTUPINFO);
  20.     siStartupInfo.dwFlags |= STARTF_USESTDHANDLES;
  21.     siStartupInfo.hStdOutput = h;
  22.     siStartupInfo.hStdError = h;
  23.    
  24.     if (CreateProcessW(const_cast<LPCWSTR>(FullPathToExe.c_str()),
  25.                        pwszParam,
  26.                        0,
  27.                        0,
  28.                        true,
  29.                        /*CREATE_NO_WINDOW*/CREATE_NEW_CONSOLE,
  30.                        0,
  31.                        0,
  32.                        &siStartupInfo,
  33.                        &piProcessInfo
  34.                       )
  35.         ) dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, (SecondsToWait * 1000));
  36.     else iReturnVal = GetLastError();
  37.     delete[]pwszParam;
  38.     pwszParam = 0;
  39.     CloseHandle(piProcessInfo.hProcess);
  40.     CloseHandle(piProcessInfo.hThread);
  41.     if(h != INVALID_HANDLE_VALUE) CloseHandle(h);
 

Merci quand même si vous avez quelque intuition passagère :D


Message édité par zownierd le 29-06-2012 à 14:56:59
n°2147590
breizhbugs
Posté le 29-06-2012 à 15:46:56  profilanswer
 

Est ce que \\monpc est bien l'ordinateur local? Si oui pourquoi le précises- tu?
Pour le reste, pas d'idée...


---------------
Seul Google le sait...
n°2147599
zownierd
Posté le 29-06-2012 à 16:54:24  profilanswer
 

en fait je viens de réaliser que en écrivant :
psexec \\monpc.corp.lan echo && ipconfig  
... ça marche ... mais la commande ipconfig est exécutée sur mon pc a moi et non a distance x) en fait ça marche pas mieux avec le echo && :( (c'était un peu zarb après tout ^^)
 
donc ainsi aucune commande ne passe mais j'ai quand même quelques résultats dans mon fichier de log :
 

Code :
  1. PsExec v1.98 - Execute processes remotely
  2. Copyright (C) 2001-2010 Mark Russinovich
  3. Sysinternals - www.sysinternals.com
  4. Le volume dans le lecteur C s'appelle Windows


 
alors que la commande donne ça
 
 

Code :
  1. C:\Users\dpiffre>psexec \\monPC.corp.lan  CMD /C "dir"
  2. PsExec v1.98 - Execute processes remotely
  3. Copyright (C) 2001-2010 Mark Russinovich
  4. Sysinternals - www.sysinternals.com
  5. Starting CMD on hektor17...ice on hektor17...
  6. Le volume dans le lecteur C s'appelle Windows
  7. Le numéro de série du volume est E48B-2034
  8. Répertoire de C:\Windows\system32
  9. 26/06/2012  14:44    <REP>          .
  10. 26/06/2012  14:44    <REP>          ..
  11. 12/04/2011  03:32    <REP>          040C


 
La commande bloque à mi-chemin je ne sais pas trop pourquoi mais ca semble lié à PSExec :( (psinfos marche très bien :/)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  redirection de sortie CreateProcessW

 

Sujets relatifs
Redirection stdout sur un FILEErreur redirection
Laisser l'adresse de redirection dans l'url du site cibleAllocation fichier en entrée / sortie
[pyalsaaudio] Choisir le canal de sortie audioSortie standard et démon
redirection user_agentChanger la redirection d'un lien sur Wordpress
htacces, redirection, dossier et surtout un petit coup de mainredirection .htaccess
Plus de sujets relatifs à : redirection de sortie CreateProcessW


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR