0

I have been trying to find a solution to why the ExitTool I am using is not properly closing out after I close the main application. What is happening is that when I close my application, the ExifTool stays running in the background and I have to manually kill it.

enter image description here


Here is the code snippet of the process startup.

Public Shared Sub ExecuteExifTool()
    If ExifToolStarted Then Exit Sub
    ExifToolStarted = True
    Dim NowString As String = Date.Now.ToString("yyyyMMddHHmmss")
    If Not IO.Directory.Exists(".\Runtime") Then IO.Directory.CreateDirectory(".\Runtime")
    Dim GetDirectory As New IO.DirectoryInfo(".\Runtime")
    If GetDirectory.GetFiles.Count > 0 Then
        For Each i As IO.FileInfo In GetDirectory.GetFiles
            If i.FullName.Contains("exif.Yv") AndAlso i.FullName.Contains("-cL") AndAlso i.FullName.Contains(".exe") Then : Try : i.Delete() : Catch : End Try : End If
        Next
    End If
    HostName = ".\Runtime\exif.Yv" & NowString.Substring(0, 8) & "-cL" & NowString.Substring(8, 6) & ".exe"
    IO.File.Copy(".\exiftool.exe", HostName)
    Using ExifToolProcess As New Process
        With ExifToolProcess
            .StartInfo.RedirectStandardInput = True
            .StartInfo.FileName = HostName
            .StartInfo.UseShellExecute = False
            .StartInfo.Arguments = "-stay_open" & " True -@ " & "-"
            .StartInfo.RedirectStandardOutput = True
            .StartInfo.RedirectStandardError = True
            .StartInfo.CreateNoWindow = True
            .StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            .Start()
            .BeginOutputReadLine()
            .BeginErrorReadLine()
        End With
    End Using
End Sub

The latest attempt to solve this issue was to try and launch another executable application; which essentially, is another Windows.Forms.Form that waits for the main application to close and then it will attempt to kill the process immediately afterwards, then dispose of itself. Here is the snippet.

Public Class KillProcess

    Private _ProcessName As String
    Public Property ProcessName As String
        Get
            Return _ProcessName
        End Get
        Set(value As String)
            _ProcessName = value
        End Set
    End Property

    Private _MainApp As Form
    Public Property MainApplication As Form
        Get
            Return _MainApp
        End Get
        Set(value As Form)
            _MainApp = value
        End Set
    End Property

    Private Sub KillProcess_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CleanupProcess()
    End Sub

    Public Sub CleanupProcess()
        While Not MainApplication.IsDisposed
            Dim FilesToDelete As New List(Of String)
            Dim ProcessesToKill As New List(Of Process)
            For Each p As Process In Process.GetProcesses
                If p.ProcessName = ProcessName Then
                    FilesToDelete.Add(p.MainModule.FileName)
                    ProcessesToKill.Add(p)
                End If
            Next
            For Each p As Process In ProcessesToKill
                Try
                    p.Kill()
                    p.WaitForExit(10000)
                    p.Close()
                Catch winException As System.ComponentModel.Win32Exception
                Catch invalidException As InvalidOperationException
                End Try
            Next
        End While
        Me.Dispose()
    End Sub
End Class

And here is the code snippet of the startup.

Public Sub CleanupTask()
    Dim Handler As New Custodian.KillProcess With {.ProcessName = ExifToolHooker.HostName, .MainApplication = Me}
    Windows.Forms.Application.Run(Handler)
End Sub

Private Sub CloseApplication(sender As Object, e As FormClosingEventArgs) Handles Me.Closing
    Dim TaskHandler As Thread = New Thread(AddressOf CleanupTask)
    TaskHandler.SetApartmentState(ApartmentState.STA)
    TaskHandler.Start()
    ...
End Sub
İsmail Y.
  • 3,579
  • 5
  • 21
  • 29
John89
  • 45
  • 1
  • 7
  • 1
    A possible problem is redirecting the standard output end error streams but not reading from them. If you don't need the program output, set `RedirectStandardInput`, `RedirectStandardOutput` and `RedirectStandardError` to false. If you need the output, put the relevant code in your question. – Steeeve Aug 17 '21 at 15:55
  • As @Steeeve mentioned, it's not clear what you're actually doing there. It appears you're trying to handle asynchronously the Process output, but you have `Using ExifToolProcess As New Process` and nowhere you're adding the required event handlers. -- See the example shown here (VB.Net): [Process.Start() an executable and return a DialogResult to the caller](https://stackoverflow.com/a/68789279/7444103) and [How do I get output from a command to appear in a control on a Form in real-time?](https://stackoverflow.com/a/51682585/7444103) -- Assuming you want to read the output of that Process. – Jimi Aug 17 '21 at 16:01
  • Steeeve & Jimi thank you both. I looked into redirecting from standard output more to make sure I didn't misunderstand/misinterpret what does. It turns out that I didn't need it at all and I was able I modified the code and now everything is working perfectly. – John89 Aug 17 '21 at 17:38

0 Answers0