Bonjour,
Je voudrais pouvoir récupérer en C (et pas autrement) la variable windows %errorlevel% suite à l'utilisation de system() qui execute un .exe.
Merci d'avance pour vos luminaires![]()
Bonjour,
Je voudrais pouvoir récupérer en C (et pas autrement) la variable windows %errorlevel% suite à l'utilisation de system() qui execute un .exe.
Merci d'avance pour vos luminaires![]()
Bonjour,
Pour récupérer la variable %errorlevel%, tu peux faire un fork, rediriger la sortie standard ou la sortie d'erreur sur l'entrée d'un , faire un execlp puis écrire la valeur de %errorlevel% sur la sortie standard ou la sortie d'erreur.
Sinon tu peux écrire %errorlevel% dans un fichier puis le lire ensuite lorsque l’exécution de ton .exe est fini.
Salut,
Je suis sous windows. Fork c'est pour linux ?
Sous windows, j'ai bien tenté de faire un system("echo %errorlevel% > c:\err.txt");
Il me retourne sans cesse 0. Je suppose que ce n'est pas l'errorlvl du même processus qui lance le system(command); dont je souhaite récupérer le code d"erreur.
Cordialement.
Si je ne dis pas de bêtises, %errorlevel% est la variable qui reçoit le code de retour de la commande qui se termine, à l'intention d'un script batch. Or, « system » est en principe faite pour renvoyer ce code de retour (ou -1 en cas d'échec). Donc, tu écris :
Code c : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 int x; x = system("commande");
… et ça devrait suffire.
C'est ce que j'ai fais mais ça me renvoie la valeur 10 en permanence.
J'execute unrar, or les exit codes de unrar vont de 0..9 puis 256.
Quand j’exécute la commande dans la cmd directement, il me donne bien le bon exit code.
En revanche, si je fais int r = system(command); // Avec command chaine de caractères contenant la commande unrar.
La j'obtiens 10 au lieu de 0 ou 3 quand je le fais dans la CMD directement.
Bonjour,
La faq est bien fournie, aussi, cette question te répondra.
Have fun!
Merci pour ta réponse,
Cependant je ne discerne pas la différence avec system.
Je ne vois pas comment récupérer l'errorlevel qui correspond à l'exit code le l'exe unrar.
Si dans la CMD si je tape :
unrar x c:\arch.rar -ppassword
echo %errorlevel%
Si tout se passe bien le resultat est 0 sinon c'est 3.
J'ai un paquet d'archive à tester. Soit elle a un mot de passe, soit elle n'en a pas. Si oui c'est le même password donc c'est bon.
Si j'utilise system, que je récupère le retour de la fonction system, il m'affiche 10 systématiquement. Si après la commande system je fais un system("echo %errorlevel%); il m'affiche 0 en permanence.
Idem pour le lien que tu m'a donné.
Il doit bien y avoir un moyen de récupérer l'exit code de winrar qui sont 0..9 ou 255 suite à un appel system ou autre. J'ai l'impression de me faire couper l'herbe sous le pied -.-.
Je pourrais le faire en traitant le texte en sortie, l'enregistrer dans un fichier, lire l'information et décider mais cela prends du temps en plus et je voudrais bien éviter cette façon de faire un peu sale.
Merci pour votre aide.
Peux-tu nous montrer ici la commande exacte que tu tapes dans ton programme C et directement dans la ligne de commande ? Parce qu'à moins qu'il y ait des choses spécifiques à Windows de ce côté-là, « 10 » ne tombe pas du ciel. Il semblerait que ta commande renvoie bien cette valeur pour une raison où une autre.
Il se peut notamment que ce soit dû au fait que « unrar » te pose parfois des questions à l'écran, chose qu'il ne peux pas faire si tu le lances depuis system.
J'aimerai bien que ça soit cela, mais quand je la tape dans la CMD, il ne me demande rien, il affiche directement dans la cmd le texte correspondant à l'errorlevel.
et -y répond automatiquement par oui à une question s'il y a.
Code : Sélectionner tout - Visualiser dans une fenêtre à part system("C:\\PROGRA~1\\winrar\\unrar.exe x c:\\arch.txt -y -ppassword");
J'ai testé avec :
La bonne nouvelle c'est que je reçois bien l'errorlevel du retour d'unrar à savoir 7 ici, ce qui correspond à wrong command line options.
Code : Sélectionner tout - Visualiser dans une fenêtre à part CreateProcess("c:\\PROGRA~1\\winrar\\unrar.exe","x c:\\a.rar -idq -idp -idd -p00100", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
Or la grosse blaque est que cette commande passe très bien sous DOS.
La seule explication est que le champ pour les commands line de CreateProcess est mal renseigné.
J'ai trouvé des exemples sur le net avec des commandes unix par contre du style ls -li | grep quelquechose.
Je pensais que mettre les paramètres de la même manière serait bon.
Visiblement pas.
Any Clue?
Nan mais j'y crois pas.
Si j'enlève le paramètre c- pour désactiver les commentaires, j'ai le bon errorlevel.
Si je fais la même dans la CMD avec c- ça marche pourtant...
![]()
Merci pour votre aide c'est bon
J'ai enlevé le paramètre qui m'ennuie et cela marche.
Résultat des courses system fonctionne parfaitement bien comme cela l'a été signalé =). Ma faute à MOI
Je signale que chez moi en tout cas
est 30% plus rapide que
Code : Sélectionner tout - Visualiser dans une fenêtre à part CreateProcess("c:\\PROGRA~1\\winrar\\unrar.exe","c:\\PROGRA~1\\winrar\\unrar.exe t c:\\a.rar -inul -y -pPASSWORD", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
Sur une heure de travail à la base c'est intéressant
Code : Sélectionner tout - Visualiser dans une fenêtre à part system("c:\\PROGRA~1\\winrar\\unrar.exe t c:\\a.rar -inul -y -pPASSWORD");
D'ailleurs est-ce qu'il y a moyen de faire mieux en terme de temps de traitement encore à partir de ce code ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <windows.h> int main() { char command[1000]; unsigned int *LIST_SIZE = NULL; char**list = get_list("C:\\list.txt", LIST_SIZE) double t0=GetTickCount(); //Initialisation du timer float p; //Pourcentage d'avancement //Variables nécessaires à CreateProcess STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); DWORD code; for (i=0 ;i<LIST_SIZE ;i++) { sprintf(command,"c:\\PROGRA~1\\winrar\\unrar.exe t c:\\path\%s -inul -y -pPASSWORD",list[i] ); CreateProcess("c:\\PROGRA~1\\winrar\\unrar.exe",command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); // executer le processus WaitForSingleObject(pi.hProcess, INFINITE); // Attendre la fin du processus GetExitCodeProcess(pi.hProcess, &code); //Récupérer l'exit code de l'exe winrar if( code != 0 ) // Si exit code != 0 ; archive avec mot de passe perror("winrar : "); if ( i%100 == 0) printf("\n p=%.2f%% ; cps=%.0f",100*p, 1000.0*i/(GetTickCount()-t0)); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } free(LIST_SIZE); dealloc_2D_char_ptr(list, LIST_SIZE); return 0; }
Bravo pour avoir résolu ton problème tout seul au final !
C'est normal : « system() » est officiellement faite pour passer une commande au système et la voir traitée par lui. Ça veut dire que system() lance le « shell » officiel du système sur lequel tu tournes en lui indiquant la commande à lancer, pour qu'il l'interprète.
CreateProcess(), tout comme exec--() sous Unix, servent à lancer directement un fichier binaire exécutable. Ça marchera donc bien avec les exécutables en langage machine, ce sera un tout petit peu plus subtil avec les fichiers interprétés (Perl, Python, etc.) parce que le programme à lancer est en fait l'interpréteur, mais le système est en général capable de retomber sur ses pattes. Par contre, tout le reste est exclu : commandes internes, codes spéciaux (par exemple, le « & » de mise en arrière plan), et notamment les commandes chaînées avec des pipes « | ».
En tous cas une fois de plus j'ai découverts de nouveaux trucks et je me suis rendu compte une fois de plus que c'était moi le bug hihi.
Si vous connaissez un moyen de rendre le code encore plus rapide, je suis preneur !
Je pensais à l'utilisation de thread pour diviser la boucle et rendre l'execution 'paralleles'. Mais je ne sais pas dans quels cas l'utilisation de threads peut être rentable, quelle architecture...
J'ai utilsé 3 threads (core i7), j'ai divisé le temps par ~4-- :p
Partager