0

我正在尝试监视用户选择的进程。我正在做的是尝试从进程名称中获取文件名,以便在找不到进程时可以再次启动它。现在我不明白我的问题。我在这里收到错误:Dim s As String = ProcessArray(0).MainModule.FileName

我不明白的是它返回的文件名很好。谁能帮我查明问题?

    Dim ProcessArray As Process()
    ProcessArray = Process.GetProcessesByName(procName)
    Dim s As String = ProcessArray(0).MainModule.FileName
    Dim f As Process
    Dim p As Process() = Process.GetProcessesByName(procName)

    For Each f In p
        If p.Length > 0 Then
            For i As Integer = 0 To p.Length - 1
                ProcessID = (p(i).Id)
            Next
        Else
            ProcessID = 0
        End If
        If ProcessID = 0 Then
            BotRunning = False
            Process.Start(s)
            watchdogbool = True
            RunBot(watchdogList, ItemClicked.Text, -1)
        End If
    Next
4

4 回答 4

1

如果未找到该进程,则找到的进程数组将为空。所以,你不能访问它的第一个元素。在您声明时s假设您将始终至少有一个结果。

于 2013-01-02T10:33:37.457 回答
1

正如其他人已经说过的那样,当没有找到给定名称的进程时,就会发生错误。s因此,当错误发生时为什么具有有效值的唯一方法是,如果您在循环内执行代码并s在实际错误发生时具有来自上一次迭代(其中进程仍在运行)的值。

最重要的是您的代码和您想要实现的描述不匹配。基本上,如果您想在程序再也找不到它时再次启动该过程,那么我会期待某种循环。

我猜你想要这样的东西:

Public Sub WatchProcess(procName As String)
    Dim processArray As Process() = Process.GetProcessesByName(procName)
    ' The process must be running when your program starts. If not, throw an exception
    If processArray.Length = 0 Then Throw New ArgumentException("no such process", "procName")

    Dim fileName As String = processArray(0).MainModule.FileName

    While True ' Looking for the process endlessly. Use other conditions proper for you.
        If Process.GetProcessesByName(procName).Length = 0 Then
            ' The process is not running anymore, start it again!
            ' Do all the other stuff you wanna do (set bool flags etc.)
            Process.Start(fileName)
        End If
        Thread.Sleep(5000) ' Wait 5 seconds until the next check
    End While
End Sub

重要的是,这将永远阻塞调用线程。因此,您需要使用多线程,让一个线程调用一个 procName 的方法(如果您想在 UI 中提供反馈或观察多个进程)。

正如您在评论中所说,您可以得到一条Win32Exception说明,您无法使用 32 位进程访问 64 位进程。要解决这个问题,请以与监视进程相同的模式启动您自己的程序(在Project settings => Compile => Advanced Compile Options => Target CPU 下强制使用目标 CPU)。有关这方面的更多信息,请参阅类似的相应其他问题。

于 2013-01-02T12:44:01.843 回答
0

在得到filename检查之前ProcessArray 不是 null 然后继续 else return

于 2013-01-02T10:38:45.200 回答
0

此行不返回任何元素

ProcessArray = Process.GetProcessesByName(procName)

这就是为什么当您访问数组的第一个元素(为空)时,它会给您错误

索引超出数组范围 解决方法 检查对象null

if(ProcessArray !=null)
   Dim s As String = ProcessArray(0).MainModule.FileName
   MessageBox.Show("File name is " & ProcessArray(0).MainModule.FileName)

OR
if(ProcessArray.Length>0)
   Dim s As String = ProcessArray(0).MainModule.FileName
于 2013-01-02T10:39:03.610 回答