IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez .NET Discussion :

[C#] Comment décoder le Diagnostics.Process.StandardOutput [FAQ]


Sujet :

Contribuez .NET

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut [C#] Comment décoder le Diagnostics.Process.StandardOutput
    Salut à tous,

    J'utilise la classe System.Diagnostics.Process pour lancer des commande DOS et récupérer le résultat pour en faire un traitement. J'ai des petits soucis parfois avec des caractère qui sont un peu mal décodé. Par exemple, pour la commande DIR, voilà ce que je récupère dans System.Diagnostics.Process.StandardOutput

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Le volume dans le lecteur D s'appelle DATA
     Le num‚ro de s‚rie du volume est 801B-4CC2
     
     R‚pertoire de D:\Programmes
     
    17/06/2005  20:16    <REP>          .
    17/06/2005  20:16    <REP>          ..
    22/09/1998  15:46             1ÿ942 environ.ksh
    22/09/1998  15:46             1ÿ323 profile.ksh
     
                   2 fichier(s)            3ÿ265 octets
                  35 R‚p(s)     955ÿ125ÿ760 octets libres
    Autant dire qu'il y a comme un soucis avec certains caractères. Y a-t-il un traitement à faire sur le StreamReader pour récupérer une sortie Unicode ? Si quelqu'un a une idée, je suis preneur.
    Merci pour votre aide.

    CrashMan

  2. #2
    Expert confirmé
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Par défaut
    oui le flux doit avoir un encodage de lecture équivalent à l'encodage d'ecriture
    essayes d'utiliser le constructeur qui permet de surcharger un encodage par exemple System.Text.Encoding.Default je crois (il y en a d'autres...)

  3. #3
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    En effet, dans le constructeur, utilises System.Text.Encoding.Default comme 2ème paramètre

  4. #4
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut
    Merci pour votre aide, mais je ne vois pas comment changer l'encodage du flux de sortie. Moi je lis directement la property StandardOutput de System.Diagnostics.Process après avoir fait le Run. Je n'ai pas trouvé de constructeurs de Diagnostics.Process qui prennent des Arguments. Et la property Diagnostics.Process.StandardOutput.CurrentEncoding n'est qu'en lecture seule. Je dois pas être très doué, mais je ne vois pas comment exploiter vos infos. Vous pouvez préciser, avec un exemple si possible ?
    Merci

    CrashMan

  5. #5
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Montre nous le code que tu utilises

  6. #6
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut
    Voilà un extrait de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    System.Diagnostics.Process runCmd = new System.Diagnostics.Process();
    runCmd.StartInfo.FileName = @"C:\WINDOWS\system32\cmd.exe";
    runCmd.StartInfo.Arguments="dir";
    runCmd.StartInfo.RedirectStandardOutput = true;
    runCmd.Start(); 
    string output = runCmd.StandardOutput.ReadToEnd();
    CrashMan

  7. #7
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Arf oui, la c'est vrai que ca va etre dur, on peut rien passé au constructeur

  8. #8
    Expert confirmé
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Par défaut
    sauf peut-être si tu récupère le resultat de runcmd dans un streamreader qui lui posséde le constructeur voulu
    après je ne sais pas où tu veux l'afficher

  9. #9
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut
    Merci pour les remarques, mais ça ne marche toujours pas. J'ai essayé le truc suivant :

    System.IO.StreamReader TraceCmdReader = new System.IO.StreamReader(runCmd.StandardOutput.BaseStream,System.Text.Encoding.Default);
    J'ai essayé avec les encodages ASII, Unicode, UTF7 et UTF8. Les résultats sont différents, mais toujours aussi décevant. Vous n'avez pas une autre idée en magasin ?

    CrashMan

  10. #10
    Expert confirmé
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Par défaut
    Excuses si tu as déjà répondu à la question mais que renvoie en test la propriété
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    runCmd.StandardOutput.CurrentEncoding;
    merci

  11. #11
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    Les sorties consoles DOS sont en OEM-defined character set

    pour les transformer en ANSI : Api win32 OemToChar ou OemToCharBuff

  12. #12
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut
    Génial Abelman, ça marche nikel. Par contre j'ai encore 2 petites questions :

    1- Est ce qu'il y a un autre moyen de faire ça sans invoquer une DLL native win32 ? J'aurais aimé rester 100% C# dans une optique de porter le code sur UNIX avec Mono (à moins que le problème de l'encodage OEM ne se rencontre que sous DOS !!!)

    2- J'ai réussi en Invoquant la méthode OemToCharBuff:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    uint Taille = 5000;
    StringBuilder strBuilder = new StringBuilder((int)Taille);
    bool res = OemToCharBuff(runCmd.StandardOutput.ReadToEnd(),strBuilder,Taille);
    Je n'ai pas réussit a utiliser OemToChar:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    StringBuilder strBuilder = new StringBuilder();
    bool res = OemToChar(runCmd.StandardOutput.ReadToEnd(),strBuilder);
    J'ai l'exception System.ExecutionEngineException à l'exécution. Pour ma culture générale et parceque ça m'ennuie d'avoir à définir la taille de ma StringBuilder, quelqu'un saurait -il pourquoi ça cloche ?
    Encore mille merci pour votre aide.

    CrashMan.

  13. #13
    Expert confirmé
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 64
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Par défaut
    dixit MSDN
    Notes
    Les erreurs de moteur d'exécution sont des erreurs irrécupérables qui ne doivent jamais se produire. Ces erreurs se produisent essentiellement lorsque le moteur d'exécution est endommagé ou lorsque des données manquent. Le système peut lever cette exception à tout moment. Lorsque cela est possible, le système lève une exception qui fournit davantage d'informations que l'exception ExecutionEngineException.

    Les applications ne doivent pas lever ExecutionEngineException.

    ExecutionEngineException utilise le HRESULT COR_E_EXECUTIONENGINE dont la valeur est 0x80131506.

    Pour obtenir la liste des valeurs initiales des propriétés d'une instance de ExecutionEngineException, consultez les constructeurs ExecutionEngineException.

  14. #14
    Rédacteur
    Avatar de abelman
    Inscrit en
    Février 2003
    Messages
    1 106
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 1 106
    Par défaut
    Citation Envoyé par CrashMan
    1- Est ce qu'il y a un autre moyen de faire ça sans invoquer une DLL native win32 ? J'aurais aimé rester 100% C# dans une optique de porter le code sur UNIX avec Mono (à moins que le problème de l'encodage OEM ne se rencontre que sous DOS !!!)
    Je ne sais pas ... Je programme pas sous Unix. J'avais cherché à l'epoque à le faire 100% .NET mais je n'y étais pas arrivé. Je dirais donc que l'on ne peut pas

    Citation Envoyé par CrashMan
    Pour ma culture générale et parceque ça m'ennuie d'avoir à définir la taille de ma StringBuilder, quelqu'un saurait -il pourquoi ça cloche ?
    Encore mille merci pour votre aide.
    CrashMan.
    Tu peux utiliser OemToChar mais il faut que ton StringBuilder soit au moins de la taille de la chaine que tu souhaites convertir. Tu as une exception car le buffer de ton stringbuilder n'est tout simplement pas assez grand.

  15. #15
    Nouveau membre du Club
    Inscrit en
    Avril 2004
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 6
    Par défaut
    Effectivement, j'aurais pu y penser. En tout cas merci beaucoup à tout les deux. J'aurais jamais trouvé tout seul. Ce Forum est vraiment très efficace.
    Merci

    CrashMan

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Ouverture de document via System.Diagnostics.Process
    Par Spoonnny dans le forum Windows Forms
    Réponses: 4
    Dernier message: 09/01/2008, 18h24
  2. System.Diagnostics.Process.GetProcesses Accès refusé
    Par Courgette17 dans le forum VB.NET
    Réponses: 6
    Dernier message: 03/07/2007, 10h11
  3. Réponses: 2
    Dernier message: 31/05/2007, 13h37
  4. Comment détecter une erreur dans un process
    Par chuckboy dans le forum MFC
    Réponses: 3
    Dernier message: 25/10/2005, 10h40
  5. Réponses: 2
    Dernier message: 30/01/2004, 14h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo