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

VB.NET Discussion :

appel de processus bloquant et application qui gèle


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par défaut appel de processus bloquant et application qui gèle
    Bonjour,

    Me voilà confronté à une problématique.
    Je réalise un convertisseur wav mp3, ou plutôt une interface graphique conviviale paramétrable qui tire les ficelles sur un programme externe, ici il s'agit de lame.exe .
    Je désire convertir plusieurs fichiers audio, et de manière séquentielle, ce qui veut dire appeler N fois le programme externe. Et c'est là que votre aide m'est précieuse
    J'effectue mon appel à l'aide de la commande shell en primitive bloquante afin que le traitement s'effectue bien séquentiellement et pour éviter d'avoir N fenêtres de commande qui s'ouvrent d'un coup!

    Seulement je crois que cette solution d'appel bloquant empêche à mon application principale de recevoir et traiter les messages de l'OS du style réduire la fenêtre, ou simplement annuler la conversion.

    Connaissez vous une solution plus adéquate pour réaliser cette fonctionnalité?
    J'ai pensé au threads, mais au final l'application principale devra tout de même "attendre" que la conversion du premier fichier soit terminée avant d'enchainer sur le second.

    Voici un extrait du code afin d'éclaircir un peu:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        ' shell execute
        Private Sub shellExecute(ByVal cmd As String, ByVal isBlocking As Boolean, ByVal PromptOption As Short)
            ' shell command execute
            Try
                Shell(cmd, PromptOption, isBlocking, -1)
                'Shell(cmd, AppWinStyle.MinimizedNoFocus, True, -1)
            Catch ex As Exception
     
            End Try
        End Sub


    Et la fonction qui s'éxécute lorsque je clique sur le bouton de lancement de conversion...

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    ' when you click the convert now button!
        Private Sub ConvertButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConvertButton.Click
            Dim count, progress As Integer
            Dim currentFile As String
            Dim InputFilePrefix, TmpFileFullPath, OutFileFullPath, FileOutPath, tmpCmd As String
            Dim FileOutType As String = ".error"    ' will be set according to your settings!
            Dim FileSubNames(3) As String
     
     
            ' first, we check if there's any input file to convert
            If (ListView1.Items.Count = 0) Then
                MessageBox.Show("there's no input file to convert!")
                Return
            Else
                ' set Progress 'maximum' step attribute based on input file number
                ToolStripProgressBar1.Maximum = ListView1.Items.Count
            End If
     
            ' so, there's something to convert
     
     
     
     
            ToolStripProgressBar1.Value = 0
            ' now we need to get all files in ListView1 (if non empty!)
            For count = 0 To ListView1.Items.Count - 1
                currentFile = ListView1.Items(count).SubItems(0).Text()
     
                ' set the bubbleMsg text value
                progress = count / (ListView1.Items.Count - 1) * 100
                bubbleMsg = "job progression: " + progress.ToString
     
                ' prompt for job in progress
                ListView1.Items.Item(count).SubItems.Add("...")
                Application.DoEvents()  ' equals yield() in C (enfin, si j'ai bien compris)
     
                ' Get Input file Basename
                FileSubNames = currentFile.Split(".")
                InputFilePrefix = FileSubNames(0)
     
     
                ' get the output Directory
                If (useCustomOutputDirectory = False) Then
                    FileOutPath = Path(count)
                Else
                    FileOutPath = DialogGeneralSettings.Label_outputDir.Text
                End If
     
     
                ' define what outputFiles type we want (.mp3 or .wav) depending on Options/<type> convertion checked subItem
                If (MP3ConversionToolStripMenuItem.Checked = True) Then
     
                    TmpFileFullPath = FileOutPath + "\" + InputFilePrefix + ".tmp"
                    OutFileFullPath = FileOutPath + "\" + InputFilePrefix + ".mp3"
     
                    ' first wav to mp3 conversion
                    tmpCmd = "lame.exe -h """ + Path(count) + "\" + currentFile + """ """ + TmpFileFullPath + """"
                    ToolStripStatusLabel1.Text = "converting " + currentFile + " to MP3 fileType"
                    Application.DoEvents()
                    shellExecute(tmpCmd, True, showJobStyle)
                    ' then bitrate adjustment
                    tmpCmd = "lame.exe --mp3input -b" + kbps.ToString + " """ + TmpFileFullPath + """ """ + OutFileFullPath + """"
                    ToolStripStatusLabel1.Text = "adjusting " + currentFile + " bitrate to " + kbps.ToString + " Kbps"
                    Application.DoEvents()
                    shellExecute(tmpCmd, True, showJobStyle)
                    ' cleaning intermediate file
                    IO.File.Delete(TmpFileFullPath)
     
                ElseIf (WaveConversionToolStripMenuItem.Checked = True) Then
     
                    OutFileFullPath = FileOutPath + "\" + InputFilePrefix + ".wav"
     
                    'the only one shell command
                    tmpCmd = "lame.exe --decode """ + Path(count) + "\" + currentFile + """ """ + OutFileFullPath + """"
                    ToolStripStatusLabel1.Text = "converting " + currentFile + " to WAV fileType"
                    Application.DoEvents()
     
     
                    ' C'est ici que j'ai besoin de votre aide
                    '
                    '
                    shellExecute(tmpCmd, True, showJobStyle)
                    '
                    '
                    '
     
     
     
     
                Else
                    MessageBox.Show("No file output type defined, please ensure in 'Options' that either 'MP3 conversion' or 'Wav conversion' is checked")
                    Return
                End If
     
                System.Threading.Thread.Sleep(500)  ' sleep 500ms for fun!
     
                ' show end conversion status
                If (IO.File.Exists(OutFileFullPath)) Then
                    ListView1.Items.Item(count).SubItems(1).Text = "ok!"
                Else
                    ListView1.Items.Item(count).SubItems(1).Text = "Error!"
                End If
     
                ' prompt job evolution
                ToolStripProgressBar1.Increment(1)
                'ListView1.Update()
                Application.DoEvents()  ' equals yield() in C
            Next
     
     
     
            ' ---- here job is done! ----
     
            If (EndJobSoundPlay = True) Then
                If (EndJobSoundFullPath.Contains("\") = True) Then
                    My.Computer.Audio.Play(EndJobSoundFullPath)
                Else
                    My.Computer.Audio.Play(getAppPath + "\" + EndJobSoundFullPath)
                End If
            End If
     
            ToolStripStatusLabel1.Text = "Job done!"
     
            If (NotifyIcon1.Visible = True) Then
                NotifyIcon1.BalloonTipText = "Job Done :)"
                NotifyIcon1.ShowBalloonTip(3000)
            End If
     
            Application.DoEvents()
     
        End Sub

    Merci par avance pour votre aide

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    Par défaut
    tu peux instancier un process, t'abonner à l'évènement qui dit qu'il est fini, faire process.Start en non bloquant et quand l'event est déclenché tu passes au suivant
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 47
    Par défaut
    Super ça marche!

    Je poste le code mis à jour...

    J'ai supprimé la fonction shellExecute, puis ajouté à la place son équivalent à la sauce .net

    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
     
        Private Sub processExecute(ByVal processPath As String, ByVal args As String, ByVal method As String, ByVal Blocking As Boolean, ByVal Prompt As Boolean)
            eventHandled = False
     
            Try
     
                myProcess.StartInfo.FileName = processPath
                myProcess.StartInfo.Arguments = args
                myProcess.StartInfo.Verb = method               ' Open for process executing
                myProcess.StartInfo.UseShellExecute = Prompt    ' prompt or not shell window
                myProcess.StartInfo.CreateNoWindow = True
                myProcess.EnableRaisingEvents = True
                myProcess.Start()
     
            Catch ex As Exception
                MsgBox("Exception occured:" & _
                    vbCrLf & ex.Message)
                Return
            End Try
     
            ' wait asynchronously (if required in function arg)....
            If (Blocking = True) Then
                Do While Not eventHandled
                    Thread.Sleep(200)
                    Application.DoEvents()
                Loop
            End If
     
        End Sub
    Et comme il faut capter l'évènement "fin de processus" pour positionner le booléen 'eventHandled' et sortir de la première fonction, voici le corps de la seconde fonction ajoutée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
        ' External process terminated CALLBACK
        Private Sub myProcess_Exited(ByVal sender As Object, _
                ByVal e As System.EventArgs) Handles myProcess.Exited
     
            eventHandled = True
            Console.WriteLine("Exit time:    {0}" & vbCrLf & _
                "Exit code:    {1}" & vbCrLf, _
                myProcess.ExitTime, myProcess.ExitCode)
        End Sub

    En passant, voici la fonction qui subsiste avec quelques modifications

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    ' when you click the convert now button!
        Private Sub ConvertButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ConvertButton.Click
            Dim count, progress As Integer
            Dim currentFile As String
            Dim InputFilePrefix, TmpFileFullPath, OutFileFullPath, FileOutPath, CmdLineArgs As String
            Dim FileOutType As String = ".error"    ' will be set according to your settings!
            Dim FileSubNames(3) As String
     
     
     
            ' first, we check if there's any input file to convert
            If (ListView1.Items.Count = 0) Then
                MessageBox.Show("there's no input file to convert!")
                Return
            Else
                ' set Progress 'maximum' step attribute based on input file number
                ToolStripProgressBar1.Maximum = ListView1.Items.Count
            End If
     
            ' so, there's something to convert
     
     
     
     
            ToolStripProgressBar1.Value = 0
            ' now we need to get all files in ListView1 (if non empty!)
            For count = 0 To ListView1.Items.Count - 1
                currentFile = ListView1.Items(count).SubItems(0).Text()
     
                ' set the bubbleMsg text value
                progress = count / (ListView1.Items.Count) * 100
                bubbleMsg = "job progression: " + progress.ToString
     
                ' prompt for job in progress
                ListView1.Items.Item(count).SubItems.Add("...")
                Application.DoEvents()  ' equals yield() in C
     
                ' Get Input file Basename
                FileSubNames = currentFile.Split(".")
                InputFilePrefix = FileSubNames(0)
     
     
                ' get the output Directory
                If (useCustomOutputDirectory = False) Then
                    FileOutPath = Path(count)
                Else
                    FileOutPath = DialogGeneralSettings.Label_outputDir.Text
                End If
     
     
                ' define what outputFiles type we want (.mp3 or .wav) depending on Options/<type> convertion checked subItem
                If (MP3ConversionToolStripMenuItem.Checked = True) Then
     
                    TmpFileFullPath = FileOutPath + "\" + InputFilePrefix + ".tmp"
                    OutFileFullPath = FileOutPath + "\" + InputFilePrefix + ".mp3"
     
                    ' first wav to mp3 conversion
                    CmdLineArgs = "-h """ + Path(count) + "\" + currentFile + """ """ + TmpFileFullPath + """"
                    ToolStripStatusLabel1.Text = "converting " + currentFile + " to MP3 fileType"
                    processExecute(getAppPath & "\" & "lame.exe", CmdLineArgs, "Open", True, showJob)
     
                    ' then bitrate adjustment
                    CmdLineArgs = "--mp3input -b" + kbps.ToString + " """ + TmpFileFullPath + """ """ + OutFileFullPath + """"
                    ToolStripStatusLabel1.Text = "adjusting " + currentFile + " bitrate to " + kbps.ToString + " Kbps"
                    processExecute(getAppPath & "\" & "lame.exe", CmdLineArgs, "Open", True, showJob)
     
                    ' cleaning intermediate file
                    IO.File.Delete(TmpFileFullPath)
     
                ElseIf (WaveConversionToolStripMenuItem.Checked = True) Then
     
                    OutFileFullPath = FileOutPath + "\" + InputFilePrefix + ".wav"
     
                    'the only one shell command
                    CmdLineArgs = "--decode """ + Path(count) + "\" + currentFile + """ """ + OutFileFullPath + """"
                    ToolStripStatusLabel1.Text = "converting " + currentFile + " to WAV fileType"
                    processExecute(getAppPath & "\" & "lame.exe", CmdLineArgs, "Open", True, showJob)
     
                Else
                    MessageBox.Show("file output type undefined, please ensure in 'Options' that either 'MP3 conversion' or 'Wav conversion' is checked")
                    Return
                End If
     
                System.Threading.Thread.Sleep(500)  ' sleep 500ms for fun!
     
                ' show end conversion status
                If (IO.File.Exists(OutFileFullPath)) Then
                    ListView1.Items.Item(count).SubItems(1).Text = "ok!"
                Else
                    ListView1.Items.Item(count).SubItems(1).Text = "Error!"
                End If
     
                ' prompt job evolution
                ToolStripProgressBar1.Increment(1)
                Application.DoEvents()  ' equals yield() in C
            Next
     
     
     
            ' ---- here job is done! ----
     
            If (EndJobSoundPlay = True) Then
                If (EndJobSoundFullPath.Contains("\") = True) Then
                    My.Computer.Audio.Play(EndJobSoundFullPath)
                Else
                    My.Computer.Audio.Play(getAppPath + "\" + EndJobSoundFullPath)
                End If
            End If
     
            ToolStripStatusLabel1.Text = "Job done!"
     
            If (NotifyIcon1.Visible = True) Then
                NotifyIcon1.BalloonTipText = "Job Done :)"
                NotifyIcon1.ShowBalloonTip(3000)
            End If
     
            Application.DoEvents()
     
        End Sub
    Voilà, du coup je peux utiliser tous les contrôles de mon formulaire, et particulèrement le bouton 'Annuler la conversion' pour quitter mon application sans avoir à faire CTRL ALT SUPP

    Merci encore Pol63 pour les pistes

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

Discussions similaires

  1. Processus bloquant un fichier
    Par KORTA dans le forum Windows XP
    Réponses: 8
    Dernier message: 04/09/2012, 12h55
  2. application qui gèle le clavier pour PDA
    Par cotede2 dans le forum Java ME
    Réponses: 0
    Dernier message: 22/04/2009, 16h56
  3. [Mailslot] application qui gèle
    Par Georgio dans le forum Delphi
    Réponses: 2
    Dernier message: 31/07/2006, 08h49
  4. application qui connecte sur une page web
    Par spoolz dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 14/04/2004, 09h47
  5. Déterminer l'application qui a le Focus
    Par JakeGrafton dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 22/02/2004, 12h52

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