Looping through processes

elektrobank

Member
Joined
Aug 11, 2008
Messages
19
Programming Experience
10+
Can I do this in VB.NET?
VB.NET:
foreach (Process process in
    System.Diagnostics.Process.GetProcesses().Where(        process =>
        {
            bool hasException = false;
            try { IntPtr x = process.Handle; }
            catch { hasException = true; }
            return !hasException;
        })
    )
{
        // ...
}
I'm trying to loop through processes, but keep getting an access denied error when it comes across services. I found this code which is supposed to fix that, can it be done in VB though?

Thanks!
 
Your profile says .NET 3.0 but you're using LINQ, which requires at least .NET 3.5. You should update your profile if it's inaccurate or specify your version in the thread title if it's different to your profile.

Yes, you can do exactly the same thing in VB as you're doing in that C# code. The syntax will be a bit different though and you also need to be using VB 2010 to be able to write multi-line lambdas. If you're not using VB 2010 then you'll need to write a conventional method. Here's the VB 2010 equivalent:
VB.NET:
For Each process As Process In Process.GetProcesses().Where(Function(p)
                                                                Dim hasException = False

                                                                Try
                                                                    Dim x As IntPtr = p.Handle
                                                                Catch
                                                                    hasException = True
                                                                End Try

                                                                Return Not hasException
                                                            End Function)
    '...
Next
 
You don't understand what the code does (it Try-Catch access to each looped process.Handle), or are you asking about extension methods, anonymous methods in general? Code exactly like that is valid in VB 2010 (as replied minutes ago). In VB 2008 you have to write a named function and .Where(AddressOf that) since multiline full-body anon's wasn't there yet, which is something I'd do anyway if taking that approach. Which I wouldn't considering the ugly code. Here it makes more sense to just try-catch the handle during the loop and continue to next when not accessible. Or what say you about these three equivalent codes:
  • VB.NET:
    For Each p As Process In Process.GetProcesses().Where(Function(pcs)
                                                              Dim hasException As Boolean = False
                                                              Try
                                                                  Dim x As IntPtr = pcs.Handle
                                                              Catch
                                                                  hasException = True
                                                              End Try
                                                              Return Not hasException
                                                          End Function)
        '...
    Next
  • no hocus pocus:
    VB.NET:
    For Each p As Process In Process.GetProcesses
        Try
            Dim x As IntPtr = p.Handle
        Catch
            Continue For
        End Try
        '...
    Next
  • Where(AddressOf named function):
    VB.NET:
    For Each p As Process In Process.GetProcesses.Where(AddressOf Accessible)
        '...
    Next


    latter uses the named function:
    VB.NET:
    Function Accessible(ByVal p As Process) As Boolean
        Dim hasException As Boolean = False
        Try
            Dim x As IntPtr = p.Handle
        Catch
            HasException = True
        End Try
        Return Not HasException
    End Function
About the C# translation, this translator does translate that accurately, though you have to use different parameter names for the loop iterator and the anonymous method parameter. Convert C# to VB.NET - A free code conversion tool - developer Fusion
 
Another alternative, that is also more in line with this latest MSDN Flash article (Don't Misuse Lambdas | //TODO: - Chris Marinos' Blog), is to assign the multiline lambda to a variable and use that in the expression, it is most similar to option C above with the named function.
VB.NET:
Dim accessible = Function(pcs As Process)
                     Dim hasException As Boolean = False
                     Try
                         Dim x As IntPtr = pcs.Handle
                     Catch
                         hasException = True
                     End Try
                     Return Not hasException
                 End Function

For Each p As Process In Process.GetProcesses().Where(accessible)
    '...            
Next
 
I set it to .NET 3.5 and added the code as you have written, but am getting an error saying "'Where' is not a member of 'System.Array'"
Any ideas?

Your profile says .NET 3.0 but you're using LINQ, which requires at least .NET 3.5. You should update your profile if it's inaccurate or specify your version in the thread title if it's different to your profile.

Yes, you can do exactly the same thing in VB as you're doing in that C# code. The syntax will be a bit different though and you also need to be using VB 2010 to be able to write multi-line lambdas. If you're not using VB 2010 then you'll need to write a conventional method. Here's the VB 2010 equivalent:
VB.NET:
For Each process As Process In Process.GetProcesses().Where(Function(p)
                                                                Dim hasException = False

                                                                Try
                                                                    Dim x As IntPtr = p.Handle
                                                                Catch
                                                                    hasException = True
                                                                End Try

                                                                Return Not hasException
                                                            End Function)
    '...
Next
 
I set it to .NET 3.5 and added the code as you have written, but am getting an error
As explained you can't use that code in VB 2008.
 
I'm using 2010
Your profile says you're using VS 2005/2008, and you haven't stated otherwise until now, so it was a reasonable objection. That said, copying that code to a VB 2010 project set to compile to .Net 3.5 serves no problem for me.
Are you sure you have System.Core assembly referenced and System.Linq namespace imported? By default this is included in projects created by VB 2010. Where method is an Enumerable extension, that also applies to arrays.
 
Where is an extension method. It is a member of the Enumerable class and it extends the IEnumerable(Of T) interface, meaning it can be called on any object that implements IEnumerable(Of T), which arrays do. Like any class, to use Enumerable you must reference the assembly it's a member of. To call an extension method, you must also import the namespace it's type is a member of. The MSDN documentation for every type and method can tell you what assembly and namespace it's in. Check that for Enumerable.Where and make sure you have referenced the assembly and imported the namespace.
 
Back
Top