Solved

Set timeout for WMI query

Posted on 2010-08-31
8
1,635 Views
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 = ""

                Try



                    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



                    Next



                Catch ex As Exception

                    MsgBox(ex.ToString)

                End Try

               

            End If

Open in new window

0
Comment
Question by:jcamping
  • 3
  • 3
  • 2
8 Comments
 
LVL 6

Expert Comment

by:apresence
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...
0
 

Author Comment

by:jcamping
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?
0
 
LVL 41

Expert Comment

by:graye
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
0
 

Author Comment

by:jcamping
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?
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 41

Expert Comment

by:graye
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.
0
 
LVL 41

Expert Comment

by:graye
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?
0
 
LVL 6

Accepted Solution

by:
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



        Try

            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

            'System.Threading.Thread.Sleep(15000)

            '- Note: Uncomment next line to complete with success

            System.Threading.Thread.Sleep(5000)

            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"

        wmiThread.Start(wmiArgs)



        If (Not wmiThread.Join(10000)) Then

            Console.WriteLine("MAIN   Timeout waiting for worker thread to complete; Terminating")

            wmiThread.Abort()

            Console.WriteLine("MAIN   Worker thread terminated")

        Else

            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)

            Else

                Console.WriteLine("MAIN   Worker thread terminated with failure")

            End If

        End If



        Console.WriteLine("MAIN   Application completed")

        Console.ReadLine()

    End Sub

Open in new window

0
 

Author Closing Comment

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

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

705 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

18 Experts available now in Live!

Get 1:1 Help Now