How To Detect Cmd.Exe Is Done Problem

Mr.Kim 1 Reputation point
2021-05-02T06:50:47.88+00:00

hi guy

I have one problem with my code below which i try to write a code to detect the cmd.exe when i click button to start timer.start() and when cmd.exe is done and close the main windows, i need timer.stop() and show message to me but i try to using many condition is not work. please share me how to do with this problem.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnCovert.Click

    Dim p As Process

    Dim active As Boolean = True

    Timer1.Start()

    p = Process.Start("cmd.exe", "/c ffmpeg.exe -i " & FileName2 & " -c:v libx264 " & "Down\" & FileName1 & ".mp4")

  if p.HasExited then

  Timer1.Stop()
 msgbox("Close")

 end if

end sub

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,733 questions
{count} votes

4 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,436 Reputation points
    2021-05-02T12:07:53.543+00:00

    Hello,

    Have you tried Process.WaitForExitAsync ?

    Example (full source) which I realize is not using the same command as you but the principle is the same and this is async without showing a windows

    Public Shared Async Function GetComputerInformationTask() As Task(Of MachineComputerInformation)  
      
        Const fileName = "computerInformation.json"  
      
        If File.Exists(fileName) Then  
            File.Delete(fileName)  
      
        End If  
      
        Dim start = New ProcessStartInfo With {  
                    .FileName = "powershell.exe",  
                    .RedirectStandardOutput = True,  
                    .Arguments = "Get-ComputerInfo | ConvertTo-Json",  
                    .CreateNoWindow = True  
                }  
      
        Using process As Process = Process.Start(start)  
      
      
            Using reader = process.StandardOutput  
      
                process.EnableRaisingEvents = True  
      
                Dim fileContents = Await reader.ReadToEndAsync()  
      
                Await File.WriteAllTextAsync(fileName, fileContents)  
                Await process.WaitForExitAsync()  
      
      
                Dim json = Await File.ReadAllTextAsync(fileName)  
      
      
                Return JsonConvert.DeserializeObject(Of MachineComputerInformation)(json)  
      
            End Using  
        End Using  
    End Function  
    

    Usage

    Private Async Sub ComputerInfoButton_Click(sender As Object, e As EventArgs) Handles ComputerInfoButton.Click  
      
        Dim details = Await Operations.GetComputerInformationTask()  
        PropertyGrid1.SelectedObject = details  
      
    End Sub  
    

    92970-pg.png

    ---
    93090-codedbykpmvp.png

    0 comments No comments

  2. Mr.Kim 1 Reputation point
    2021-05-02T13:44:28.953+00:00

    hi Karen

    i used to use the Process.WaitForExitAsync but seem it not working as what i need because i dont know or estimate with time which FFEMEG will finish convert .mp4 done that is reason why i need using support about it .


  3. Mr.Kim 1 Reputation point
    2021-05-06T03:37:46.37+00:00

    hi Mrs. karenpayneoregon

    Thanks with your help to recommend me using " Process.WaitForExitAsync " but the problem for my coding is using VB.net not C#, because i dont know how to use C# language. i have try to use vb.net as this coding below it still meet some problem, can't move the form while i click button convert processing. i dont know reason why, so if you can help correct this code for me.

    Blockquote

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnCovert.Click
    
        btnCovert.Enabled = False
        Dim FileName1 As String = System.IO.Path.GetFileNameWithoutExtension(OpenFileDialog1.FileName) 'Get only Flie name without extension
        Dim FileName2 As String = OpenFileDialog1.FileName
        Dim programName As String = "ffmpeg.exe"
        System.Diagnostics.Process.Start(Application.StartupPath & "\" & programName)
    
        Dim active As Boolean = True
        Dim ts As TimeSpan
        Dim process As Process
        Dim sw As New Stopwatch
        AMins = 0
        ASecond = 0
        sw.Start()
        process = Process.Start("cmd.exe", "/c ffmpeg.exe -i " & FileName2 & " -c:v libx264 " & "Down\" & FileName1 & ".mp4")
        process.WaitForExit()
        sw.Stop()
        If process.HasExited Then
            OutFileInfor()
        End If
        ts = sw.Elapsed
        ' Format and display the TimeSpan value.
        Dim elapsedTime As String = String.Format("Spend Time: {0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10)
        lbTime.Text = elapsedTime
    
    End Sub
    

  4. Karen Payne MVP 35,436 Reputation points
    2021-05-08T15:17:30.54+00:00

    The reason why your form is not responsive is because process.WaitForExit() prevents this. You need to use Await process.WaitForExitAsync() or Await process.WaitForExitAsync(cts.Token) as mentioned in my former reply. Here is what I'm talking about

    Public Shared Async Function GetComputerInformationTask(cts As CancellationTokenSource) As Task(Of MachineComputerInformation)
    
        Const fileName = "computerInformation.json"
    
        If File.Exists(fileName) Then
            File.Delete(fileName)
    
        End If
    
        Dim start = New ProcessStartInfo With {
                    .FileName = "powershell.exe",
                    .RedirectStandardOutput = True,
                    .Arguments = "Get-ComputerInfo | ConvertTo-Json",
                    .CreateNoWindow = True
                }
    
        Using process As Process = Process.Start(start)
    
    
            Using reader = process.StandardOutput
    
                process.EnableRaisingEvents = True
    
                Dim fileContents = Await reader.ReadToEndAsync()
    
                Await File.WriteAllTextAsync(fileName, fileContents)
    
                StopWatcher.Instance.Start()
    
                Await process.WaitForExitAsync(cts.Token)
    
                StopWatcher.Instance.Stop()
    
                RaiseEvent FinishedEvent(StopWatcher.Instance.ElapsedFormatted)
    
    
                Dim json = Await File.ReadAllTextAsync(fileName)
    
                Return JSonHelper.DeserializeObject(Of MachineComputerInformation)(json)
    
            End Using
        End Using
    End Function
    

    Calling the above

    Private Async Sub ComputerInfoButton_Click(sender As Object, e As EventArgs) Handles ComputerInfoButton.Click
    
        TimeLabel.Text = ""
    
        If PropertyGrid1.SelectedObject IsNot Nothing Then
            PropertyGrid1.SelectedObject = Nothing
        End If
    
        Dim cancellationTokenSource As New CancellationTokenSource(TimeSpan.FromSeconds(2))
    
        Dim details = Await Operations.GetComputerInformationTask(cancellationTokenSource)
    
        PropertyGrid1.SelectedObject = details
        PropertyGrid1.CollapseAllGridItems()
    
    End Sub
    

    Full source

    If you don't following the above flow then your form will remain unresponsive.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.