locked
Launching an application from WPF Window using Process Class RRS feed

  • Question

  • I am using the Process to class to launch a program (notepad, for example) and wait for it to exit from a WPF window.  

    When I drag notepad over my WPF window, the WPF Window does not repaint and its distorted.

    What is the correct way to force a refresh, so that I never see parts of Notepad in my WPF window?

    I've tried various options and timers but nothing seems to work consistly?

    • Moved by CoolDadTx Wednesday, April 8, 2009 1:52 PM Not related to IDE
    Wednesday, April 8, 2009 4:18 AM

Answers

  • You don't want to call Process.Start from the UI thread and wait.  The UI thread will not update your UI while the thread is busy.  Register a callback with the Process class.

    XAML
     
    <StackPanel>
        <Button x:Name='ShowNotepad'
                Click='Button_Click' Content='Show Notepad'/>
      </StackPanel>
    C# code

    private void Button_Click(object sender, RoutedEventArgs e) {
    	ProcessStartInfo startInfo = new ProcessStartInfo();
    	startInfo.FileName = "Notepad.exe";
    	Process process = Process.Start(startInfo);
    	process.EnableRaisingEvents = true;
    	process.Exited += ProcessDone;
    }
    public void ProcessDone(Object s, EventArgs e) {
    	MessageBox.Show("Done");
    	// note you will have to marshal back to UI thread
    	// to access any UI elements
    	Dispatcher.Invoke(new Action<string>(UpdateUI), "Finished");
    }
    public void UpdateUI(string message) {
    	this.Title = message;
    }
    or VB code

    Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    	Dim startInfo As New ProcessStartInfo()
    	startInfo.FileName = "Notepad.exe"
    	Dim process As Process = Process.Start(startInfo)
    	process.EnableRaisingEvents = True
    	AddHandler process.Exited, AddressOf ProcessDone
    End Sub
    Public Sub ProcessDone(ByVal s As Object, ByVal e As EventArgs)
    	MessageBox.Show("Done")
    	' note you will have to marshal back to UI thread
    	' to access any UI elements
    	Dispatcher.Invoke(New Action(Of String)(AddressOf UpdateUI), "Finished")
    End Sub
    Public Sub UpdateUI(ByVal message As String)
    	Me.Title = message
    End Sub


    Walt | http://wpfwonderland.wordpress.com
    Thursday, April 9, 2009 8:23 AM
  • Thank you for taking the time to answer this.
    This does resolve my refresh issue.

    Next I'll consider
    - the best way to disable controls( I may want to prevent the user from doing anything and suspend the WPF UI and wait until the call back). I don't want the user to be able to click the button while the launched program is still running.
    - StandardOutput - to determine how the launched application terminated( ie: if the pressed OK or Cancel )
    • Marked as answer by Kathy Vitale Friday, April 10, 2009 7:55 PM
    Friday, April 10, 2009 7:54 PM

All replies

  • You don't want to call Process.Start from the UI thread and wait.  The UI thread will not update your UI while the thread is busy.  Register a callback with the Process class.

    XAML
     
    <StackPanel>
        <Button x:Name='ShowNotepad'
                Click='Button_Click' Content='Show Notepad'/>
      </StackPanel>
    C# code

    private void Button_Click(object sender, RoutedEventArgs e) {
    	ProcessStartInfo startInfo = new ProcessStartInfo();
    	startInfo.FileName = "Notepad.exe";
    	Process process = Process.Start(startInfo);
    	process.EnableRaisingEvents = true;
    	process.Exited += ProcessDone;
    }
    public void ProcessDone(Object s, EventArgs e) {
    	MessageBox.Show("Done");
    	// note you will have to marshal back to UI thread
    	// to access any UI elements
    	Dispatcher.Invoke(new Action<string>(UpdateUI), "Finished");
    }
    public void UpdateUI(string message) {
    	this.Title = message;
    }
    or VB code

    Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    	Dim startInfo As New ProcessStartInfo()
    	startInfo.FileName = "Notepad.exe"
    	Dim process As Process = Process.Start(startInfo)
    	process.EnableRaisingEvents = True
    	AddHandler process.Exited, AddressOf ProcessDone
    End Sub
    Public Sub ProcessDone(ByVal s As Object, ByVal e As EventArgs)
    	MessageBox.Show("Done")
    	' note you will have to marshal back to UI thread
    	' to access any UI elements
    	Dispatcher.Invoke(New Action(Of String)(AddressOf UpdateUI), "Finished")
    End Sub
    Public Sub UpdateUI(ByVal message As String)
    	Me.Title = message
    End Sub


    Walt | http://wpfwonderland.wordpress.com
    Thursday, April 9, 2009 8:23 AM
  • Thank you for taking the time to answer this.
    This does resolve my refresh issue.

    Next I'll consider
    - the best way to disable controls( I may want to prevent the user from doing anything and suspend the WPF UI and wait until the call back). I don't want the user to be able to click the button while the launched program is still running.
    - StandardOutput - to determine how the launched application terminated( ie: if the pressed OK or Cancel )
    • Marked as answer by Kathy Vitale Friday, April 10, 2009 7:55 PM
    Friday, April 10, 2009 7:54 PM