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

Scripts/Batch Discussion :

Gestion des évènements en PoSH v2 et récupération des traces [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut Gestion des évènements en PoSH v2 et récupération des traces
    Bonjour à tous,
    Sur les conseils de Laurent Dardenne je poste ici ma question.

    En PoSH v1, j'utilisais l'add-on PSEventing pour gérer les appels de process externes et récupérer les traces de sortie. Ca marchait nickel.

    Maintenant, je suis obligé de passer à PoSH v2, qui introduit la gestion des évènements, bonne nouvelle, donc plus besoin de PSEventing.

    J'ai au beaucoup de mal à trouver de la documentation sur la question, et finalement, et finalement, le créateur de PSEventing a modifié mon code pour qu'il fonctionne en PoSH v2, le voici :

    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
    48
    49
    50
    51
    function Launch-Process([System.Diagnostics.Process]$process, [string]$log, [int]$timeout = 0)
    {
     #Connect-Event process ErrorDataReceived,OutputDataReceived
     Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived > $null
     Register-ObjectEvent -InputObject $process -EventName OutputDataReceived > $null
      
     $process.Start() 
     $process.BeginErrorReadLine()
     $process.BeginOutputReadLine() 
     
     $ret = $null
     if($timeout -eq 0)
     {
     $process.WaitForExit()
     $ret = $true
     }
     else
     {
     if(-not($process.WaitForExit($timeout)))
     {
      Log-Message $log WARNING ("The process is not completed, after the specified timeout: " + $timeout)
      $ret = $false
     }
     else
     {
      $ret = $true
     }
     }
     
     #$events = @(Read-Event)
     $events = @(Wait-Event)
    
     foreach($event in $events)
     {
     if(-not [string]::IsNullOrEmpty($event.Args.data))
     {
      if($event.Name -eq "OutputDataReceived")
      {
      #Log-Message $log Info $event.Args.data
      Log-Message $log Info $event.SourceEventArgs.data
      }
      else
      {
      #Log-Message $log ERROR $event.Args.data
      Log-Message $log ERROR $event.SourceEventArgs.data
      }
     }
     }
     $process.Close()
     $ret
    }
    Déjà, y a des trucs que je ne comprends pas, comme les " > $null" à la fin des appels à Register-ObjectEvent.

    Ensuite, ce code ne fonctionne pas, mon objet events (normalement rempli par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     $events = @(Wait-Event)
    est vide.

    Une idée ?

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par romut Voir le message
    a modifié mon code
    L'objectif étant la redirection des sorties d'un process.
    Citation Envoyé par romut Voir le message
    Déjà, y a des trucs que je ne comprends pas, comme les " > $null" à la fin des appels à Register-ObjectEvent.
    Cela évite d'afficher l'objet PSJob, on peut aussi utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    [void](Register-ObjectEvent ...)
    Citation Envoyé par romut Voir le message
    Ensuite, ce code ne fonctionne pas,
    Si, c'est la lecture des events générés qu'il faut revoir. J'ai associé du code via le paramètre -Action du cmdlet Register-ObjectEvent.

    J'utilise cmd.exe pour la démo :
    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
    $global:log = "C:\Temp\test.log"
     
    # Process object creation
    $process = New-Object -TypeName System.Diagnostics.Process
    $process.StartInfo.CreateNoWindow = $false
    $process.StartInfo.RedirectStandardError = $true
    $process.StartInfo.RedirectStandardOutput = $true
    $process.StartInfo.UseShellExecute = $false
    $process.StartInfo.FileName = "c:\windows\System32\CMD.EXE"
    $process.StartInfo.WorkingDirectory = "C:\temp\"
    $process.StartInfo.Arguments = '/k'
     
    Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived  -action {
     $message = "ERR: $($EventArgs.data)"  
     Write-Host $message
     $message | Out-File $global:log -Encoding ASCII -Append
    }
    Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -action {
     $message = "Out : $($EventArgs.data)" 
     Write-Host $message
     $message | Out-File $global:log -Encoding ASCII -Append
    }
     
    $process.Start() 
    $process.BeginErrorReadLine()
    $process.BeginOutputReadLine()  
     
    $process.WaitForExit()
     #saisir DIR puis exit
    $process.Close()
    Type $global:log
    Dans le code des events, il reste à revoir la gestion de lignes vides.
    Et enfin supprimer les abonnements et les job des events.

  3. #3
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    Trop fort, je vais bien arriver à me débrouiller avec ça maintenant.

    Merci pour ce gros coup de main, vraiment, ça me simplifie vraiment l'existence.

  4. #4
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    J'ai modifié ton code comme suit :

    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
    function Log-Trace([string]$Level, [system.Diagnostics.DataReceivedEventArgs]$Trace)
    {
        if($Trace -ne $null)
        {
            if(-not [string]::IsNullOrEmpty($Trace.data))
            {
                Write-Host "$Level $($Trace.data)"
            }
        }
    }
    
    # Process object creation
    $process = New-Object -TypeName System.Diagnostics.Process
    $process.StartInfo.CreateNoWindow = $false
    $process.StartInfo.RedirectStandardError = $true
    $process.StartInfo.RedirectStandardOutput = $true
    $process.StartInfo.UseShellExecute = $false
    $process.StartInfo.FileName = "7z.EXE"
    $process.StartInfo.WorkingDirectory = ""
    $process.StartInfo.Arguments = ""
     
    Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived  -action {
    Log-Trace "ERROR" $EventArgs
    }
    Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -action {
    Log-Trace "Info" $EventArgs
    }
     
    $process.Start() 
    $process.BeginErrorReadLine()
    $process.BeginOutputReadLine()  
     
    $process.WaitForExit()
    $process.Close()
    Ca marche pas trop mal, mais comme avec le code précédent que tu as donné, j'ai des fois des traces "WARNING: Operation is not valid due to the current state of the object.", saurais tu comment éviter ça ?

    En même temps, elle ne seront pas enregistrées dans mon log, c'est donc pas trop un souci, mais je m'inquiète de la "propreté" de mon script...

    Merci.

  5. #5
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    Salut,
    J'ai finalement un gros souci avec cette solution.

    En fait, mon script fait partie d'un ensemble de scripts PoSH qui constitue notre plateforme de builds & tests. La société dans laquelle je travaille est un éditeur de logiciels.

    Pour la GConf, nous utilisons CVS, c'est un choix historique sur lequel malheureusement je n'ai que très peu de prise, ça tiendrait qu'à moi....

    Bref, mes scripts marchent très bien sur la première version de la plateforme, en PoSH v1 32 bits + PSEventing.

    Pour satisfaire certains de nos besoins, nous devons évoluer, la plateforme passe donc d'un XP 32bits vers un 7 64 bits, donc PoSH v2 64 + la gestion des évènements fournie par PoSH.

    Et là, récupérer les traces de CVS ne fonctionne pas bien du tout. Ca se lance, ça s'exécute correctement, je récupère les erreurs sans problème, mais impossible de récupérer les traces standard de CVS avec cette solution. Ca fonctionne très bien avec les autres logiciels bizarrement, mais pas avec CVS.

    Ca fait 3 jours que je suis dessus, à faire des tests dans tous les sens et...rien à faire, impossible de récupérer les messages sortant de CVS sur "output".

    T'aurais une idée des fois ? Je soupçonne un petit bug dans PoSH v2...

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par romut
    j'ai des fois des traces "WARNING: Operation is not valid due to the current state of the object.", saurais tu comment éviter ça ?
    Il faut déjà comprendre le pourquoi de ce comportement, de mon coté je ne n'utilise pas 7zip.
    Citation Envoyé par romut
    En fait
    Faits méconnus à l'origine, ma réponse initiale est liée au contexte présenté.
    Citation Envoyé par romut
    T'aurais une idée des fois ?
    Pour ce pb avec CVS, si possible, teste-le en installant PS v2 32 bits sur ton OS 64 bits.
    Ensuite si cela fonctionne tu peux remonter le pb dans le forum parent, qui est peut être plus approprié pour celui-ci.
    Quant à mettre en cause PS c'est possible, mais comme le dit Jeffrey Snover ici :
    We regularly run > 1 million tests,
    Si c'est le cas, via MS-Connect, tu leur en offrira un de plus
    Site sur lequel tu peux également rechercher si un pb similaire est référencé.

  7. #7
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Laurent Dardenne Voir le message
    Faits méconnus à l'origine, ma réponse initiale est liée au contexte présenté.
    J'allais pas raconter ma vie d'entrée de jeu

    Bon je me suis livré à un petit test que tu devrais pouvoir exécuter aussi si le coeur t'en dit.

    Voic le 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
    $thelog = "d:/zelog.log"
    Set-Content $thelog -Value $null
    
    $process = New-Object -TypeName System.Diagnostics.Process
    $process.StartInfo.CreateNoWindow = $true
    $process.StartInfo.RedirectStandardOutput = $true
    $process.StartInfo.RedirectStandardError = $true
    $process.StartInfo.UseShellExecute = $false
    $process.StartInfo.FileName = "ping.exe"
    $process.StartInfo.Arguments = "www.google.com"
    
    Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived  -action {
        if(-not [string]::IsNullOrEmpty($EventArgs.data))
        {
            "ERROR $($EventArgs.data)" | Tee-Object -Variable message | out-file $thelog -encoding ASCII -append
        }
    }
    
    Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -action {
        if(-not [string]::IsNullOrEmpty($EventArgs.data))
        {
            "Info $($EventArgs.data)" | Tee-Object -Variable message | out-file $thelog -encoding ASCII -append
        }
    }
    
    $process.Start() 
    $process.BeginErrorReadLine()
    $process.BeginOutputReadLine() 
    $process.WaitForExit()
    J'ai testé ce bout de code sur :
    XP 32 + PoSH v2 32
    W7 32 + PoSH v2 32
    W7 64 + PoSH v2 32
    W7 64 + PoSH v2 64

    Et j'ai comportement cohérent sur les 4, mais n'ayant aucun message d'erreur, pas facile de diagnostiquer. (J'ai plus de PoSH v1 dispo).

    XP 32 + PoSH v2 32
    - Console : KO
    - PowerGUI : OK
    - PoSH ISE : OK

    W7 32 + PoSH v2 32
    - Console : KO
    - PowerGUI : OK
    - PoSH ISE : OK

    W7 64 + PoSH v2
    - PowerGUI : OK
    - PoSH ISE 32 : OK
    - PoSH ISE 64 : OK
    - Console 32 : KO
    - Console 64 : KO

    Comportement cohérent, ça marche jamais en console. Aucune erreur, mais le fichier de sortie est vide et la console aussi.

    A noter que les WARNING mentionné dans un post précédents ne sont affichés que par PowerGUI, jamais par les autres (console ou ISE).

    Donc là, je sèche.

    Anecdote marrante sur Windows 7 64 bits, dans Windows\System32, on trouve PoSH 64 bits et dans Windows\SysWOW64, on troue PoSH 32 bits...comprenne qui pourra

    Laurent, si t'as une idée, je suis preneur, sinon je me tourne vers les forums US.

  8. #8
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par romut Voir le message
    j'ai comportement cohérent sur les 4, mais n'ayant aucun message d'erreur
    Lequel t'attends-tu à avoir ?
    De mon coté :
    XP 32 sp3 Fr + PoSH v2 Fr 32
    - Console : OK
    - PoSH ISE : OK
    Le fichier de log est bien complété, le texte est identique à celui affiché dans la console si on ne redirige pas les I/O.

    Pour CVS, il se peut que la méthode d'affichage se fasse sur la vidéo et pas sur la sortie standard (stdin/stderr), à vérifier.

  9. #9
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    C'est dingue, ça marche chez toi sans rien changer

    Je m'attends à avoir un truc qui fonctionne, chez moi la sortie écran donne ça :

    Id Name State HasMoreData Location Command
    -- ---- ----- ----------- -------- -------
    19 3f47b11d-b15... NotStarted False ...
    20 2e08c905-df3... NotStarted False ...
    True
    Rien de plus, et le fichier de log est bien sur totalement vide. Je vais regarder si le souci ne vient pas des profils qui ne seraient pas exécutés sur mes machines, à part ça, je n'ai absolument aucune idée d'où peut provenir le problème.

    EDIT: Bon apparemment y a plus de notion de profil en PoSH v2, alors je vais aller voir les forums US.

  10. #10
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par romut Voir le message
    ça marche chez toi sans rien changer
    J'ai changé le nom du fichier de log et j'ai les droits d'admin sur le poste.
    Citation Envoyé par romut Voir le message
    Bon apparemment y a plus de notion de profil en PoSH v2
    Si si.

  11. #11
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    J'ai aussi les droits admin sur toutes les machines sur lesquelles j'ai testé.

    J'ai supprimé un bloc action et me suis concentré sur la sortie standard. Dans le bloc action je mets juste ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Write-Host "Event $($EventArgs.data)"
    Et ça marche, dès que j'ajoute un Tee-Object, un Out-File ou autre chose pour stocker ça, j'ai plus rien.

    Vraiment étrange.

    Bon pour moi, c'est WE, je reprendrai donc ça lundi à tête reposée.

  12. #12
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    Hello,
    Bon je résume, car j'avance pas d'un poil. Si mon bloc action est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Write-Host "Event $($EventArgs.data)"
    Ca marche, console et IDE, aucun problème. Seulement ce que je veux c'est logger les traces.

    Alors si mon bloc action est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    out-file $thelog -InputObject "$($EventArgs.data)" -encoding ASCII -append
    Ben ça marche bien dans un IDE comme PowerGUI ou PoSH ISE et pas du tout en console, le log reste totalement vide.

    J'ai bien vérifié mes machines, je n'ai aucun profil présent (info sur les profils de PoSH v2). En même temps, PoSH v2 a été installé de la même manière sur mes 3 machines de test. J'ai du mal à croire que ça vienne de là et si oui, je n'ai aucun moyen de savoir ce que contienne les profils d'origine.

  13. #13
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Salut,
    Citation Envoyé par romut Voir le message
    Bon je résume, car j'avance pas d'un poil.
    C'est un bon résumé .
    La variable $thelog doit être déclarée dans la portée du scriptblock -Action ou déclarée comme globale.
    $EventArgs est déclaré dans la portée du scriptblock, vérifie si ton scriptblock génére une erreur (voir mon tuto sur les events, page 26).

  14. #14
    Futur Membre du Club
    Inscrit en
    Mars 2009
    Messages
    32
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 32
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par Laurent Dardenne Voir le message
    Salut,
    La variable $thelog doit être déclarée dans la portée du scriptblock
    C'est ça

    Bon tu le mérites :

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 21/07/2014, 12h12
  2. Réponses: 0
    Dernier message: 14/08/2012, 15h52
  3. Problème avec la gestion des événements
    Par CynO dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/10/2005, 10h07
  4. [JTable] gestion des événements
    Par soulhouf dans le forum Composants
    Réponses: 4
    Dernier message: 19/08/2005, 13h21
  5. Gestion des évènements lors d'un clique sur une image.
    Par yoghisan dans le forum Débuter
    Réponses: 7
    Dernier message: 23/06/2005, 19h04

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