Précédent   Forum du club des développeurs et IT Pro > C et C++ > C > Débuter
Débuter Forum d'entraide pour débuter en langage C. Avant de poster -> FAQ C
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 18/12/2012, 07h37   #1
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
Par défaut Récupérer variable %errorlevel%

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
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 07h57   #2
Neckara
Rédacteur
 
Avatar de Neckara
 
Homme Denis
Étudiant
Inscription : décembre 2011
Messages : 2 612
Détails du profil
Informations personnelles :
Nom : Homme Denis
Localisation : France, Loire (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : décembre 2011
Messages : 2 612
Points : 7 162
Points : 7 162
Envoyer un message via MSN à Neckara Envoyer un message via Skype™ à Neckara
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.
__________________
Recherche devs C++ motivés et sérieux pour Last Dungeon.

Chaîne Youtube : Vidéos

Ma page DVP : http://neckara.developpez.com/
Neckara est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 08h37   #3
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
Citation:
Envoyé par Neckara Voir le message
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.
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 13h35   #4
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 089
Points : 11 089
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 :
1
2
3
    int x;
 
    x = system("commande");

… et ça devrait suffire.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 14h05   #5
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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.
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 15h06   #6
leternel
Expert Confirmé
 
Homme Pierre
Ingénieur développement logiciels
Inscription : juin 2007
Messages : 1 218
Détails du profil
Informations personnelles :
Nom : Homme Pierre
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : juin 2007
Messages : 1 218
Points : 2 585
Points : 2 585
Bonjour,
La faq est bien fournie, aussi, cette question te répondra.

Have fun!
__________________
Mes principes de bases du codeur qui veut pouvoir dormir:
  • Une variable de moins est une source d'erreur en moins.
  • Un pointeur de moins est une montagne d'erreurs en moins.
  • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
  • La plus sotte des questions est celle qu'on ne pose pas.
leternel est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 16h05   #7
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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.
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 16h09   #8
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 089
Points : 11 089
Citation:
Envoyé par darkwall_37 Voir le message
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.
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.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 16h22   #9
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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.

Code :
system("C:\\PROGRA~1\\winrar\\unrar.exe x c:\\arch.txt -y -ppassword");
et -y répond automatiquement par oui à une question s'il y a.
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 16h28   #10
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
Citation:
Envoyé par leternel Voir le message
Bonjour,
La faq est bien fournie, aussi, cette question te répondra.

Have fun!
Oups, y'avait d'autres trucks juste au dessus.
getenv j'avais déjà testé, ça me renvoit (null)... pour errorlevel -.-".

Je vais regarder le reste aussi. Merci =)
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 16h56   #11
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
J'ai testé avec :

Code :
CreateProcess("c:\\PROGRA~1\\winrar\\unrar.exe","x c:\\a.rar -idq -idp -idd -p00100", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
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.

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 ?
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 17h10   #12
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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...
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/12/2012, 17h51   #13
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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

Code :
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);
est 30% plus rapide que

Code :
system("c:\\PROGRA~1\\winrar\\unrar.exe t c:\\a.rar -inul -y -pPASSWORD");
Sur une heure de travail à la base c'est intéressant

D'ailleurs est-ce qu'il y a moyen de faire mieux en terme de temps de traitement encore à partir de ce code ?

Code :
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;
}
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 19h56   #14
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 089
Points : 11 089
Bravo pour avoir résolu ton problème tout seul au final !

Citation:
Envoyé par darkwall_37 Voir le message
[code]CreateProcess est 30% plus rapide que system
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 « | ».
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 18/12/2012, 20h01   #15
darkwall_37
Membre éclairé
 
Homme Alex V
Etudiant administrateur systèmes et réseaux
Inscription : octobre 2007
Messages : 609
Détails du profil
Informations personnelles :
Nom : Homme Alex V
Âge : 24
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Etudiant administrateur systèmes et réseaux

Informations forums :
Inscription : octobre 2007
Messages : 609
Points : 378
Points : 378
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
darkwall_37 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 16h18.


 
 
 
 
Partenaires

Hébergement Web