Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 3 sur 3
  1. #1
    Invité de passage
    Inscrit en
    avril 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : avril 2008
    Messages : 14
    Points : 0
    Points
    0

    Par défaut Lancement process et redirection stdout en live

    Bonjour à tous,

    Je bute sur un problème actuellement concernant le lancement d'un process externe via VB.net et le monitoring en direct de la sortie de l'application.

    J'essaie de lancer une application console (gdal_translate.exe) via mon application, et je voudrais avoir la progression du traitement qui est assez long en temps réel, sous forme de barre de progression.

    J'ai cherché un peu partout, j'ai trouvé des tutoriels ou exemples de codes mais aucun ne fait ce que je veux.

    Le problème vient du fait que la sortie de l'application est un peu spéciale: au lieu d'écrire une ligne à chaque étape, elle crée une ligne qui affiche le pourcentage, et qui s'incrémente:
    0...10...20...30..

    L'application ajoute des points puis les pourcentages à chaque dizaine, jusqu'à arrivé à 100.

    La redirection en temps réel est donc compliqué car il n'y a pas de nouvelle ligne créée à chaque étape.
    Comment faire ?

  2. #2
    Inactif
    Homme Profil pro François
    Chef de projet NTIC
    Inscrit en
    janvier 2007
    Messages
    6 608
    Détails du profil
    Informations personnelles :
    Nom : Homme François
    Âge : 53
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : janvier 2007
    Messages : 6 608
    Points : 12 114
    Points
    12 114

    Par défaut

    Bonjour

    Citation Envoyé par jullebarge Voir le message
    Comment faire ?

    Je dirais que vues les particularités que tu décrits, c'est délicat .
    En effet, il est très facile de rediriger la sortie séquentielle console du proces exécuté (en mettant à true la propriété RedirectStandardOutput de la classe process et en lisant le stream StandardOutput) mais ici, le programme utilise probablement l'émulation terminale native VT100 (ou VT220 ?)de la console windows.

    Il faut donc a priori écrire un parser de séquence VT100 pour restituer juste l'information fournie à partir de la lecture du stream.

    Ne connaissant pas ce programme, je te donne ces infos sous toutes réserves.
    (si c'est un très vieux programme en 16 bits -ce qui est devenu rare, quand même - , il est même possible qu'il adresse la mémoire graphique de la console directement et là, il n'y a pas de solution, tout simplement).

    EDIT : à la réflexion, je ne suis même pas sur que la console actuelle expose l'émulation VT100 - c'était le cas en MSDOS, mais je ne sais pas si c'est toujours le cas.

  3. #3
    Invité de passage
    Inscrit en
    avril 2008
    Messages
    14
    Détails du profil
    Informations forums :
    Inscription : avril 2008
    Messages : 14
    Points : 0
    Points
    0

    Par défaut

    Merci pour ces éléments de réponse, même si je ne vois pas du tout ce qu'est "l'émulation terminale native VT100" et comment écrire un parser.

    Pour info, l'application que j'utilise est décrite ici:
    http://www.gdal.org/gdal_translate.html

    et utilise la librairie Gdal, open source.

    En fouillant le code source de Gdal, j'ai troué la fonction qui est chargée d'afficher la progression du traitement, en voici le code (C++):

    Code C++ :
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    /************************************************************************/
    /*                          GDALTermProgress()                          */
    /************************************************************************/
     
    /**
     * \brief Simple progress report to terminal.
     *
     * This progress reporter prints simple progress report to the
     * terminal window.  The progress report generally looks something like
     * this:
     
    \verbatim
    0...10...20...30...40...50...60...70...80...90...100 - done.
    \endverbatim
     
     * Every 2.5% of progress another number or period is emitted.  Note that
     * GDALTermProgress() uses internal static data to keep track of the last
     * percentage reported and will get confused if two terminal based progress
     * reportings are active at the same time.
     *
     * The GDALTermProgress() function maintains an internal memory of the 
     * last percentage complete reported in a static variable, and this makes
     * it unsuitable to have multiple GDALTermProgress()'s active eithin a 
     * single thread or across multiple threads.
     *
     * @param dfComplete completion ratio from 0.0 to 1.0.
     * @param pszMessage optional message.
     * @param pProgressArg ignored callback data argument. 
     *
     * @return Always returns TRUE indicating the process should continue.
     */
     
    int CPL_STDCALL GDALTermProgress( double dfComplete, const char *pszMessage, 
                          void * pProgressArg )
     
    {
        static int nLastTick = -1;
        int nThisTick = (int) (dfComplete * 40.0);
     
        (void) pProgressArg;
     
        nThisTick = MIN(40,MAX(0,nThisTick));
     
        // Have we started a new progress run?  
        if( nThisTick < nLastTick && nLastTick >= 39 )
            nLastTick = -1;
     
        if( nThisTick <= nLastTick )
            return TRUE;
     
        while( nThisTick > nLastTick )
        {
            nLastTick++;
            if( nLastTick % 4 == 0 )
                fprintf( stdout, "%d", (nLastTick / 4) * 10 );
            else
                fprintf( stdout, "." );
        }
     
        if( nThisTick == 40 )
            fprintf( stdout, " - done.\n" );
        else
            fflush( stdout );
     
        return TRUE;
    }

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •