Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Set timeout for WMI query

Posted on 2010-08-31
Medium Priority
Last Modified: 2013-11-27
I have some code that pings a system. If it's online, it checks what OS is on it. However, some systems randomly have problems with the WMI and will lock up my code. I need a way of setting some sort of at timeout so that it will skip to the next step if it sits for more than 10 seconds.
If PingComputer(strcomputer) = True Then
                Dim ooss As Object
                Dim oos
                Dim sos As String
                Dim OSTXT = ""

                    ooss = GetObject("winmgmts:\\" & strcomputer).InstancesOf("Win32_OperatingSystem")

                    For Each oos In ooss

                        sos = oos.Name
                        Dim sp
                        Dim pos As Integer
                        Dim trimnull
                        pos = InStr(sos, "|")

                        If pos Then
                            trimnull = Microsoft.VisualBasic.Left(sos, pos - 1)
                            sp = oos.ServicePackMajorVersion
                            OSTXT = trimnull & " SP " & sp
                        End If


                Catch ex As Exception
                End Try
            End If

Open in new window

Question by:jcamping
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2

Expert Comment

ID: 33570534
WMI depends on DCOM, and there's some registry setting you can use to control the timeout for DCOM calls, but I don't remember it off the top of my head.  Perhaps someone else does.  In the meantime, I'm searching around for it...

Author Comment

ID: 33581933
From what I can tell, the DCOM setting you are referring to would have to be set on every machine. I'm just looking for a way to programmatically time out a piece of code after a designated amount of time. It seems like this would be something that would be possible. Is it?
LVL 41

Expert Comment

ID: 33586702
Oddly enough, there isn't a good way to set the DCOM timeout...   WMI *does* have a "dead man switch" to terminate a call if it takes too long.  But that doesn't come into play until after the connection is sucessfully made.
If you're interested in some cool WMI examples, take a look at the downloadable source code at: http://www.emmet-gray.com/Articles/WMI_Intro.htm
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

ID: 33592449
OK, so if there is no way to kill the code, is there a way to check to see if WMI is functioning before trying to connect to it?
LVL 41

Expert Comment

ID: 33593049
Nope, not really...  that's a catch 22... you need WMI to be able to determine if WMI is running OK !
I generally do a "ping" first, and then attempt to do a WMI connection.   If it times out, it times out... and I move on to the next one in the list..   For example, during lunch today, I polled about 400 PCs via WMI.  Yeah, sure... some of them didn't answer a ping or didn't respond to a WMI query, but I've only had a lockup about two times in about 10 years of doing this.
LVL 41

Expert Comment

ID: 33593054
... oops, I hit submit too quickly
So, let's concentrate on what's going on that can cause a lockup.  Have you been able to isolate a "test case" where a PC is the cause of the lockup?

Accepted Solution

apresence earned 2000 total points
ID: 33593899
I apologize, I had a major brain lapse when I first looked at your question.  Whenever I see something relating to WMI, I automatically assume VBScript, but I can see now you are working with VB.NET.  That makes things a lot easier...

Create a thread that does the WMI stuff, and wait for it to complete within a certain timeout value. If the timeout is reached, terminate the thread.

Drop the attached code into a module or class, and replace the contents between the Try and Catch statements of DoWMIStuff with the WMI code provided in your question. You can put your output variable in oargs.stroutput, or create additional output variables in the WMIStuffArgs class.

If you're running this test on multiple computers, you can even create several threads at a time so that you can go through your whole list of computers faster.

NOTE: This is NOT the best way to do this if you're trying to create a high-performance application.  A better way is to use the APM (Asynchronous Programming Model) feature of .NET.  But, using this method is a bit more complicated and I'm not sure if it will fit well in the program you are writing/using.

Output of testing the code (uncomment the appropriate line to test):
MAIN   Starting worker thread
THREAD Started with argument: remote_computer
MAIN   Worker thread terminated with exception: System.Exception: foo at ThreadTimeout_VB.Module1.DoWMIStuff(Object state) in C:\LocalWork\Dev\ThreadTimeout_VB\ThreadTimeout_VB\Module1.vb:line 21
MAIN   Application completed

MAIN   Starting worker thread
THREAD Started with argument: remote_computer
MAIN   Timeout waiting for worker thread to complete; Terminating
MAIN   Worker thread terminated
MAIN   Application completed

MAIN   Starting worker thread
THREAD Started with argument: remote_computer
THREAD Completed with success
MAIN   Worker thread terminated with success; Output=[remote_computer_from_thread]
MAIN   Application completed

Class WMIStuffArgs
        Public strcomputer As String
        Public success As Boolean
        Public e As Exception
        Public stroutput As String

        Public Sub New()
            strcomputer = Nothing
            success = False
            e = Nothing
        End Sub
    End Class

    Sub DoWMIStuff(ByVal state As Object)
        Dim oargs As WMIStuffArgs : oargs = state

            Console.WriteLine("THREAD Started with argument: {0}", oargs.strcomputer)
            '- Note: Uncomment next line to test exception handling
            'Throw New Exception("foo")
            '- Note: Uncomment next line to cause a timeout
            '- Note: Uncomment next line to complete with success
            oargs.stroutput = oargs.strcomputer & "_from_thread"
            oargs.success = True
            Console.WriteLine("THREAD Completed with success")
        Catch e As Exception
            oargs.e = e
        End Try
    End Sub

    Sub Main()
        Dim wmiThread As System.Threading.Thread
        Dim wmiArgs As WMIStuffArgs

        wmiThread = New System.Threading.Thread(AddressOf DoWMIStuff)
        wmiArgs = New WMIStuffArgs

        Console.WriteLine("MAIN   Starting worker thread")
        wmiArgs.strcomputer = "remote_computer"

        If (Not wmiThread.Join(10000)) Then
            Console.WriteLine("MAIN   Timeout waiting for worker thread to complete; Terminating")
            Console.WriteLine("MAIN   Worker thread terminated")
            If (Not (wmiArgs.e Is Nothing)) Then
                Console.WriteLine("MAIN   Worker thread terminated with exception: {0}", wmiArgs.e.ToString)
            ElseIf (wmiArgs.success) Then
                Console.WriteLine("MAIN   Worker thread terminated with success; Output=[{0}]", wmiArgs.stroutput)
                Console.WriteLine("MAIN   Worker thread terminated with failure")
            End If
        End If

        Console.WriteLine("MAIN   Application completed")
    End Sub

Open in new window


Author Closing Comment

ID: 33598392
That's awesome. I've looked everywhere for something easy to follow like this! Thanks so much apresence!

Featured Post

Tech or Treat!

Submit an article about your scariest tech experience—and the solution—and you’ll be automatically entered to win one of 4 fantastic tech gadgets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…

604 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question