0

I am trying to monitor a process that the user has chosen. What I am doing is trying to get the filename from the process name so when the process is not found it can launch it again. Now I don't understand my problem. I am getting the error here: Dim s As String = ProcessArray(0).MainModule.FileName.

The thing I do not understand is that it is returning the filename fine. Can anyone help me pinpoint the issue?

    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
jww
  • 97,681
  • 90
  • 411
  • 885
user1632018
  • 2,485
  • 10
  • 52
  • 87
  • Anytime a method returns an array you need to test to make sure that it is valid before using it. In this case: `If ProcessArray.Length > 0 ...` – Mark Hall Jan 02 '13 at 10:36
  • This does not make sense. I added that in and it obviously isn't running the code because it is null but I set a messagebox to popup with the value and it is showing the filename. I don't understand what is going on here. – user1632018 Jan 02 '13 at 10:54
  • Show your entire method, there obviously is something going on that we are not able to see. – Mark Hall Jan 02 '13 at 15:09

4 Answers4

1

If the process is not found, the array of the processes found would be empty. So, you can't access its first element. At the declaration of s you're assuming that you'll always have at least one result.

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
1

The error happens, as the others already said, when there was no process of the given name found. So the only way why s has a valid value when the error occurs is, if you execute your code inside a loop and s have a value from a previous iteration (in which the process still run) when the actual error happens.

Most important is that your code and your description what you want to achieve don't match. Basically if you want to start the process again when your program cannot found it anymore, then I would expect some kind of loop.

I guess you want something like this:

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

Important is, that this will block the calling thread forever. So you need to work with multi threading, having one thread calling the method for one procName (if you want to give feedback in an UI or watch multiple processes).

As you said in a comment, you can get a Win32Exception stating that you cannot access a 64 bit process with a 32 bit process. To solve that, start your own program in the same mode as the watched process (force a target CPU under Project settings => Compile => Advanced Compile Options => Target CPU). For more info about that see corresponding other questions like this one.

Community
  • 1
  • 1
Desty
  • 2,684
  • 21
  • 28
  • Sorry I should have mentioned I put the code into a timer to execute every 5 seconds. I forgot to paste that in. I really appreciate the length you went to help me out. I am using your code now instead. – user1632018 Jan 02 '13 at 17:56
0

Before getting the filename check is ProcessArray is not null then proceed else return

Rohit Vyas
  • 1,949
  • 3
  • 19
  • 28
0

This line is not Returning any element

ProcessArray = Process.GetProcessesByName(procName)

That's why when you access the first element of the array(Which is empty) then it will give you the error

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
syed mohsin
  • 2,948
  • 2
  • 23
  • 47
  • Hi Syed. So I added that it an it obviously isnt executing the code..because it has no value, BUT I created a messagebox right after displaying the value of S and it has the filename in it. I do not understand how it is possible. – user1632018 Jan 02 '13 at 11:01
  • After trying with another application I get this error:A 32 bit processes cannot access modules of a 64 bit process. – user1632018 Jan 02 '13 at 11:02