BlackHoleSun Posted December 29, 2010 Share Posted December 29, 2010 I have a script that pulls information from the different Win32 databases on a machine the user inputs. With certain machines the program will crash while it's trying to access the database. The message I get is that it "Variable must be of type Object". The code for one of the databases where it's crashing is: $colItems = $objWMIService.ExecQuery("SELECT Caption, FreePhysicalMemory, ServicePackMajorVersion, Version FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $returnArr[0] = $objItem.Caption $returnArr[1] = $objItem.FreePhysicalMemory $returnArr[2] = $objItem.ServicePackMajorVersion $returnArr[3] = $objItem.Version Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_OperatingSystem" ) Endif It doesn't matter if I put the query inside IsObj(), it still crashes. It doesn't happen with every computer I try. I think there may be a security rights issue behind the problem. My main concern is, is there a way for it to not crash on errors? I would rather it show an empty value than crash completely. Link to comment Share on other sites More sharing options...
KaFu Posted December 29, 2010 Share Posted December 29, 2010 (edited) - You didn't post a working example- My guess is, that the WMI service is not started on those machines where your script crashes, so the correct check would be IsObj($objWMIService)In SMF I use this UDF by Xenobiologist to check whether the service is running and if not trying to start it with this code:Local $b_WMI_was_running = True While Not _ServiceRunning("", "winmgmt") ; Check that WMI service is running $b_WMI_was_running = False Switch MsgBox(4 + 16 + 262144, "SMF - Computer Info Report - Error", "The WMI service is stopped." & @CRLF & "Do you want SMF to try to start it?") Case 6 _StartService("", "winmgmt") Sleep(2000) Case Else Return EndSwitch WEnd ; RUN YOUR WMI CODE HERE If $b_WMI_was_running = False Then While Not _ServiceRunning("", "winmgmt") ; Check that WMI service is running Switch MsgBox(4 + 16 + 262144, "SMF - Computer Info Report - Finished", "The WMI service has been started by SMF." & @CRLF & "Do you want SMF to stop the WMI service again?") Case 6 _StopService("", "winmgmt") Sleep(2000) Case Else Return EndSwitch WEnd EndIf- Instead if relying on WMI I recommend to extract the infos you listed above by using this + a call to MemGetStats()Edit: Upsa, $colItems is an Object, corrected. Edited December 29, 2010 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
BlackHoleSun Posted December 29, 2010 Author Share Posted December 29, 2010 OK, here's the complete re-worked function I have. I only extracted that one part in my first post since I could get the error with only that query. I added the "If IsObj($objWMIService) Then" test starting on line 17 and that worked. So would I need the further IsObj() If Then loops later? It would be nice to take those out, but I can leave them in. expandcollapse popupFunc _CompInfo($computer) $queryPing = Ping($computer) Dim $returnArr[25] If $queryPing Then $wbemFlagReturnImmediately = 0x10 $wbemFlagForwardOnly = 0x20 $colItems = "" If $computer <> "" Then $strComputer = $computer Else $strComputer = "localhost" EndIf $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2") If IsObj($objWMIService) Then $colItems = $objWMIService.ExecQuery("SELECT Caption, Domain, Manufacturer, Model, Name, PartOfDomain, Status, SystemType, TotalPhysicalMemory, UserName, Workgroup FROM Win32_ComputerSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $returnArr[0] = $objItem.Caption $returnArr[1] = $objItem.Domain $returnArr[2] = $objItem.Manufacturer $returnArr[3] = $objItem.Model $returnArr[4] = $objItem.Name $returnArr[5] = $objItem.PartOfDomain $returnArr[6] = $objItem.Status $returnArr[7] = $objItem.SystemType $returnArr[8] = $objItem.TotalPhysicalMemory $returnArr[9] = $objItem.UserName $returnArr[10] = $objItem.Workgroup Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_ComputerSystem" ) Endif $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_ComputerSystemProduct", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $returnArr[11] = $objItem.Caption $returnArr[12] = $objItem.Description $returnArr[13] = $objItem.IdentifyingNumber $returnArr[14] = $objItem.Name $returnArr[15] = $objItem.SKUNumber $returnArr[16] = $objItem.UUID $returnArr[17] = $objItem.Vendor $returnArr[18] = $objItem.Version Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_ComputerSystemProduct" ) Endif $colItems = $objWMIService.ExecQuery("SELECT Caption, FreePhysicalMemory, ServicePackMajorVersion, Version FROM Win32_OperatingSystem", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $returnArr[19] = $objItem.Caption $returnArr[20] = $objItem.FreePhysicalMemory $returnArr[21] = $objItem.ServicePackMajorVersion $returnArr[22] = $objItem.Version Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_OperatingSystem" ) Endif $colItems = $objWMIService.ExecQuery("SELECT MaxClockSpeed FROM Win32_Processor", "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $returnArr[23] = $objItem.MaxClockSpeed Next Else Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_Processor" ) Endif Else $i = 0 Do $returnArr[$i] = "" $i = $i + 1 Until $i = 25 EndIf Return $returnArr EndIf EndFunc ;==> _CompInfo On a side note, I realized I was causing a lot of extra work by calling the function for each thing I need to set (i.e. a = func($comp, 1), b = func($comp, 2)). I cleaned it up to just return the whole array and pick what it needs from the returned array. So it speeds things up a little bit. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now