Vb.net 如何创建一个可以等待多个进程退出的函数?

Vb.net 如何创建一个可以等待多个进程退出的函数?,vb.net,process,multiple-processes,Vb.net,Process,Multiple Processes,我正在创建一个windows服务,它将为我要监视的特定进程写入所有开始时间和退出时间。问题是,当我试图监视进程等待退出时,我不知道如何等待多个进程退出。下面是我编写流程开始时间的代码 Try Using regkey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE\MonitoringApplication\Login", Registry

我正在创建一个windows服务,它将为我要监视的特定进程写入所有开始时间和退出时间。问题是,当我试图监视进程等待退出时,我不知道如何等待多个进程退出。下面是我编写流程开始时间的代码

Try
    Using regkey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64).OpenSubKey("SOFTWARE\MonitoringApplication\Login", RegistryKeyPermissionCheck.Default)
        childrenID = regkey.GetValue("Login User").ToString
    End Using
    If childrenID.Equals("admin") Then
    Else
        Dim connection As New SqlConnection("Server=DESKTOP-FTJ3EOA\SQLEXPRESS;Initial Catalog=MonitorDB;User ID = admin; Password = admin")
        Dim command As New SqlCommand("SELECT  App.ApplicationName FROM App INNER JOIN ChildrenApplication ON App.ApplicationID = ChildrenApplication.ApplicationID WHERE ChildrenID = @a", connection)
        command.Parameters.Add("@a", SqlDbType.VarChar).Value = childrenID
        Dim adapter As New SqlDataAdapter(command)
        Dim table As New DataTable()
        adapter.Fill(table)

        Using sw As StreamWriter = New StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\MonitoringApplication.txt", True)

            For Each row As DataRow In table.Rows
                p = Process.GetProcessesByName(row.Item(0))
                Using myprocess = New Process
                    If p.Count > 0 Then
                        myprocess.StartInfo.FileName = row.Item(0)
                        myprocess.EnableRaisingEvents = True
                        sw.WriteLine(row.Item(0) + "running")

                    End If
                End Using
            Next row
        End Using

        Const SLEEP_AMOUNT As Integer = 100
        Do While Not eventHandled
            elapsedTime += SLEEP_AMOUNT
            If elapsedTime > 30000 Then
                Exit Do
            End If
            Thread.Sleep(SLEEP_AMOUNT)
        Loop
    End If
Catch ex As Exception
    Using sw As StreamWriter = New StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\MonitoringApplication.txt", True)
        sw.WriteLine(ex)
    End Using
End Try

Private Sub myProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles myProcess.Exited
    eventHandled = True
    Using sw As StreamWriter = New StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\MonitoringApplication.txt", True)
        sw.WriteLine("Exited")
    End Using
End Sub
有没有办法监视要退出的多个进程?提前感谢。

您现在使用它来检索正在运行的进程数组(如果有的话)。
您可以使用返回的进程数组并订阅每个进程的事件来记录数组中任何进程的退出时间

设置是引发
Exited
事件所必需的,但您还需要使用
AddHandler
以及方法或Lambda的地址订阅事件:

AddHandler [Process].Exited, AddressOf [Handler]
' or 
AddHandler [Process].Exited, Sub() [Lambda]
此方法接受进程名和文件路径,在引发
Exited
事件时,将在其中存储进程名及其退出时间

如果您当前的循环:

For Each row As DataRow In table.Rows
    '(...)
Next
您可以插入对此方法的调用:

For Each row As DataRow In table.Rows
    SubscribeProcExit(row.Item(0), Path.Combine(Application.StartupPath, "MonitoringApplication.txt"))
Next
如果日志文件未退出,则将创建该日志文件,并在每次有一个进程退出时添加新行,记录
Process.ProcessName
Process.ExitTime

请注意,行。项(0)必须包含进程的友好名称。例如,
notepad.exe
必须作为
“notepad”
引用

Private Sub SubscribeProcExit(processName As String, fileName As String)
    Dim processes As Process() = Process.GetProcessesByName(processName)
    If processes.Length = 0 Then Return
    For Each p As Process In processes
        p.EnableRaisingEvents = True
        AddHandler p.Exited,
            Sub()
                Using sw As StreamWriter = File.AppendText(fileName)
                    sw.WriteLine($"Process: {p?.ProcessName}, Exit Time: {p?.ExitTime}")
                    p?.Dispose()
                End Using
            End Sub
    Next
End Sub
您现在使用来检索正在运行的进程数组(如果有)。
您可以使用返回的进程数组并订阅每个进程的事件来记录数组中任何进程的退出时间

设置是引发
Exited
事件所必需的,但您还需要使用
AddHandler
以及方法或Lambda的地址订阅事件:

AddHandler [Process].Exited, AddressOf [Handler]
' or 
AddHandler [Process].Exited, Sub() [Lambda]
此方法接受进程名和文件路径,在引发
Exited
事件时,将在其中存储进程名及其退出时间

如果您当前的循环:

For Each row As DataRow In table.Rows
    '(...)
Next
您可以插入对此方法的调用:

For Each row As DataRow In table.Rows
    SubscribeProcExit(row.Item(0), Path.Combine(Application.StartupPath, "MonitoringApplication.txt"))
Next
如果日志文件未退出,则将创建该日志文件,并在每次有一个进程退出时添加新行,记录
Process.ProcessName
Process.ExitTime

请注意,行。项(0)必须包含进程的友好名称。例如,
notepad.exe
必须作为
“notepad”
引用

Private Sub SubscribeProcExit(processName As String, fileName As String)
    Dim processes As Process() = Process.GetProcessesByName(processName)
    If processes.Length = 0 Then Return
    For Each p As Process In processes
        p.EnableRaisingEvents = True
        AddHandler p.Exited,
            Sub()
                Using sw As StreamWriter = File.AppendText(fileName)
                    sw.WriteLine($"Process: {p?.ProcessName}, Exit Time: {p?.ExitTime}")
                    p?.Dispose()
                End Using
            End Sub
    Next
End Sub

是的。设置
EnableRaisingEvents=true
,订阅退出的
事件。引发事件时,事件的
对象
是即将退出的进程。将
对象
强制转换为要处理的对象。然后
Close()
Dispose()
如果不为空。@Jimi嗨,Jimi,我已经实现了EnableRaisingEvents,但我不确定我的编码方式是否正确。您没有订阅退出的
事件。我来举个例子,这样你就可以更清楚地了解如何进行。设置
EnableRaisingEvents=true
,订阅退出的
事件。引发事件时,事件的
对象
是即将退出的进程。将
对象
强制转换为要处理的对象。然后
Close()
Dispose()
如果不为空。@Jimi嗨,Jimi,我已经实现了EnableRaisingEvents,但我不确定我的编码方式是否正确。您没有订阅退出的
事件。我会举个例子,这样你就可以更清楚地了解如何继续。谢谢你的回答,吉米!现在我知道了如何使用EnableRaisingEvent。非常感谢你的回答,吉米!现在我知道了如何使用EnableRaisingEvent。多谢各位