Set timeout for WMI query

Posted on 2010-08-31
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
  • 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:

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?
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

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 500 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
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.…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

914 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now