invoke error when close form with process running

61 Views Asked by At

I create a simple tool for my job to copy files, use robocopy by cmd. I have two forms. the first is a GUI and the second is a embedded cmd to run command.

Everything works fine if I let the process go to the end, but if I close the form (Form2) to cancel the process, it gives me this error.

error image

Translated:

System.ObjectDisposedException:
'A deleted object cannot be accessed.
Object name: 'Form2'.'

my code form2:

Public Class Form2

    Private psi As ProcessStartInfo
    Private cmd As Process
    Private Delegate Sub InvokeWithString(text As String)

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
        TextBox1.Text = ""
        psi = New ProcessStartInfo("cmd.exe")

        Dim systemencoding As Text.Encoding =
            System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)

        With psi
            .UseShellExecute = False  ' Required for redirection
            .RedirectStandardError = True
            .RedirectStandardOutput = True
            .RedirectStandardInput = True
            .CreateNoWindow = True
            .StandardOutputEncoding = systemencoding  ' Use OEM encoding for console applications
            .StandardErrorEncoding = systemencoding
        End With

        ' EnableraisingEvents is required for Exited event
        cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}

        AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
        AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
        AddHandler cmd.Exited, AddressOf CMD_Exited

        cmd.Start()
        ' Start async reading of the redirected streams
        ' Without these calls the events won't fire
        cmd.BeginOutputReadLine()
        cmd.BeginErrorReadLine()

        cmd.StandardInput.WriteLine("@echo off")
        cmd.StandardInput.WriteLine(Form1.robocopy)
    End Sub

    Private Sub CMD_Exited(sender As Object, e As EventArgs)
        'Me.Close()
    End Sub

    ' This sub gets called in a different thread so invokation is required
    Private Sub Async_Data_Received(sender As Object, e As DataReceivedEventArgs)
        Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
    End Sub

    Private Sub Sync_Output(text As String)
        TextBox1.AppendText(text & Environment.NewLine)
        TextBox1.ScrollToCaret()
    End Sub

End Class

Can help me how to cancel everything when close form?

0

There are 0 best solutions below