索引超出数组的范围

问题描述:

我正在尝试监视用户选择的进程。我正在做的是试图从进程名称中获取文件名,以便在找不到进程时可以重新启动进程。现在我不明白我的问题。我在这里得到错误: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 
+0

只要方法返回一个数组,您需要测试以确保它在使用前是有效的。在这种情况下:'如果ProcessArray.Length> 0 ...' –

+0

这没有意义。我补充说,它显然没有运行该代码,因为它是空的,但我设置了一个消息框与值弹出并显示文件名。我不明白这里发生了什么事。 – user1632018

+0

显示你的整个方法,显然有一些我们无法看到的事情。 –

正如其他人所说的那样,当没有发现给定名称的进程时,错误就会发生。因此,当错误发生时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位进程。为了解决这个问题,在与被监视进程相同的模式下启动你自己的程序(强制目标CPU在项目设置=>编译=>高级编译选项=>目标CPU)。有关更多信息,请参阅like this one

+0

对不起,我应该提到我把代码放入一个定时器,每5秒执行一次。我忘了把它粘贴进去。我真的很感激你帮助我的时间。现在我正在使用您的代码。 – user1632018

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

之前获得filename检查ProcessArray不为空,然后继续否则返回

此行不返回任何元素

ProcessArray = Process.GetProcessesByName(procName)

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

Index out of bounds of array Solution Check the object for 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 
+0

嗨Syed。所以我补充说它显然没有执行代码。因为它没有任何价值,但是我在显示S的值之后创建了一个消息框,并且它有文件名。我不明白怎么可能。 – user1632018

+0

尝试使用其他应用程序后,出现此错误:32位进程无法访问64位进程的模块。 – user1632018

+0

就是你想要的。我编辑了代码 –