Guest Posted April 26, 2014 Share Posted April 26, 2014 (edited) Hello, my script using function that get array of all the running services on the computer. that function always worked properly until now. for some reason, now it takes 30 seconds for the function to finish. this is the function: expandcollapse popupFunc _RetrieveRunningServices() Local Const $wbemFlagReturnImmediately = 0x10 Local Const $wbemFlagForwardOnly = 0x20 Local $colItems = "", $even = 1, $objItem, $services[1] $services[0] = 0 Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") If @error Then MsgBox(16, "_RetrieveRunningServices", "ObjGet Error: winmgmts") ;ConsoleWrite("_RetrieveRunningServices -> ObjGet Error: winmgmts"&@CRLF) Return $services ;Exit EndIf $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Service", "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If @error Then MsgBox(16, "_RetrieveRunningServices", "ExecQuery Error: SELECT * FROM Win32_Service") ;ConsoleWrite("_RetrieveRunningServices -> ExecQuery Error: SELECT * FROM Win32_Service"&@CRLF) Return $services ;Exit EndIf If IsObj($colItems) Then For $objItem In $colItems If $objItem.State = "Running" Then If IsArray($services) Then ReDim $services[UBound($services) + 1] Else Dim $services[2] EndIf $services[0] = UBound($services) - 1 ;~ $services[UBound($services) - 1] = $objItem.Name $services[UBound($services) - 1] = $objItem.name ;& "[0]" & $objItem.State EndIf Next EndIf Return $services EndFunc ;==>_RetrieveRunningServices I checked the performance of the function with this code: #include <Array.au3> $timer = TimerInit() $Services = _RetrieveRunningServices() ConsoleWrite("time: "&TimerDiff($timer)&@CRLF) _ArrayDisplay($Services) The output i got is time: 30195.6027959443 and i ran the test several times and it always took 30 seconds. The first thing I decided to do after I found out that the problem is this function, I searched for an alternative function. and i found alternative function in >Computer Info UDF's the alternative function is _ComputerGetServices() so i tested that function and i was surprised to find that I get the exact same result. With the alternate function! this is my test with the alternate function: #include <Array.au3> #include "CompInfo.au3" Dim $Services $timer = TimerInit() _ComputerGetServices($Services, "Running") If @error Then ConsoleWrite("error"&@CRLF) EndIf ConsoleWrite("time: "&TimerDiff($timer)&@CRLF) _ArrayDisplay($Services) the output is: time: 30459.1907821033 I so i decided to go back to the original function check what exactly is slow in that function. at the end, i found that this loop: ....... For $objItem In $colItems ; Anything inside the loop is disabled to isolate the problem ;~ If $objItem.State = "Running" Then ;~ If IsArray($services) Then ;~ ReDim $services[UBound($services) + 1] ;~ Else ;~ Dim $services[2] ;~ EndIf ;~ $services[0] = UBound($services) - 1 ;~ $services[UBound($services) - 1] = $objItem.Name ;~ $services[UBound($services) - 1] = $objItem.name ;& "[0]" & $objItem.State ;~ EndIf Next ConsoleWrite(1&@CRLF) ; only to see when it finish ....... is the slow part that takes 30 secodns. I do not know to go from here .. I did not write this function.I would love if someone will help solve the problem ..I do not know why this is happening .. maybe this giant loop? Thanks for helpers! Edited April 26, 2014 by Guest Link to comment Share on other sites More sharing options...
JohnOne Posted April 26, 2014 Share Posted April 26, 2014 Changed or updated your security software? AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Guest Posted April 26, 2014 Share Posted April 26, 2014 (edited) Changed or updated your security software? I canceled my antivirus for the test to isolate the problem.But even if the problem is antivirus related , I can not tell users to cancel their antivirus .. I hope you understand. The code should work correctly under all conditions (or most conditions if all conditions is impossible). im looking for a command for Command Prompt that will print for me list of all running services with their display names and the short services name. that way, with this Command i can create alternate function that will do it through Command Prompt... Edited April 26, 2014 by Guest Link to comment Share on other sites More sharing options...
jguinch Posted April 26, 2014 Share Posted April 26, 2014 (edited) Well, you can simply use the net start dos command : #Include <Array.au3> $iPid = Run(@ComSpec & " /c net start", @SystemDir, @SW_HIDE, 2) ProcessWaitClose($iPid) $sResult = _OEM2ANSI(StdoutRead($iPid)) ; needed for some languages (like french for me) $aResult = StringRegExp($sResult, "(?m)^\h+(\N+)", 3) _ArraySort($aResult) _ArrayDisplay($aResult) Func _OEM2ANSI($what) $ret = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $what, 'str', '') Return $ret[2] EndFunc ;==>_OEM2ANSI Edited April 26, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Guest Posted April 26, 2014 Share Posted April 26, 2014 Well, you can simply use the net start dos command : #Include <Array.au3> $iPid = Run(@ComSpec & " /c net start", @SystemDir, @SW_HIDE, 2) ProcessWaitClose($iPid) $sResult = _OEM2ANSI(StdoutRead($iPid)) ; needed for some languages (like french for me) $aResult = StringRegExp($sResult, "(?m)^\h+(\N+)", 3) _ArraySort($aResult) _ArrayDisplay($aResult) Func _OEM2ANSI($what) $ret = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $what, 'str', '') Return $ret[2] EndFunc ;==>_OEM2ANSI I know. I tried it.The problem is that it does not give the short names in the list. I need also the short names Link to comment Share on other sites More sharing options...
Solution jguinch Posted April 26, 2014 Solution Share Posted April 26, 2014 (edited) The problem is that it does not give the short names in the list. In my code, _ArraySort($aResult) does the job, no ? Did you try with sc query ? #Include <Array.au3> Local $iPid = Run(@ComSpec & " /c sc query", @SystemDir, @SW_HIDE, 2) ProcessWaitClose($iPid) Local $sResult = _OEM2ANSI(StdoutRead($iPid)) Local $aResult = StringRegExp($sResult, "(?mi)^(?:SERVICE_NAME|DISPLAY_NAME):\h*(\N+)", 3) Local $aServices [ UBound($aResult) / 2][2], $n = 0 For $i = 0 To UBound($aResult) - 1 Step 2 $aServices[$n][0] = $aResult[$i] $aServices[$n][1] = $aResult[$i + 1] $n += 1 Next ;_ArraySort($aServices) ; Sort by ShortName _ArraySort($aServices, 0, 0, 0, 1) ; Sort by DisplayName _ArrayDisplay($aServices) Func _OEM2ANSI($what) $ret = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $what, 'str', '') Return $ret[2] EndFunc ;==>_OEM2ANSI Edited April 26, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Guest Posted April 26, 2014 Share Posted April 26, 2014 In my code, _ArraySort($aResult) does the job, no ? Did you try with sc query ? #Include <Array.au3> Local $iPid = Run(@ComSpec & " /c sc query", @SystemDir, @SW_HIDE, 2) ProcessWaitClose($iPid) Local $sResult = _OEM2ANSI(StdoutRead($iPid)) Local $aResult = StringRegExp($sResult, "(?mi)^(?:SERVICE_NAME|DISPLAY_NAME):\h*(\N+)", 3) Local $aServices [ UBound($aResult) / 2][2], $n = 0 For $i = 0 To UBound($aResult) - 1 Step 2 $aServices[$n][0] = $aResult[$i] $aServices[$n][1] = $aResult[$i + 1] $n += 1 Next ;_ArraySort($aServices) ; Sort by ShortName _ArraySort($aServices, 0, 0, 0, 1) ; Sort by DisplayName _ArrayDisplay($aServices) Func _OEM2ANSI($what) $ret = DllCall('user32.dll', 'Int', 'OemToChar', 'str', $what, 'str', '') Return $ret[2] EndFunc ;==>_OEM2ANSI Thank you!You're an angel! Link to comment Share on other sites More sharing options...
Guest Posted April 26, 2014 Share Posted April 26, 2014 (edited) I did few adjustments. Please check if everything is fine #Include <Array.au3> ;_ArraySort($aServices) ; Sort by ShortName $aServices = _RetrieveRunningServices2(1) _ArrayDisplay($aServices) Func _RetrieveRunningServices2($Sort = 0) Local $Output[1][2] , $iPid , $sResult , $aResult $iPid = Run(@ComSpec & " /c sc query", @SystemDir, @SW_HIDE, 2) ProcessWaitClose($iPid) $sResult = DllCall('user32.dll', 'Int', 'OemToChar', 'str', StdoutRead($iPid), 'str', '')[2] $aResult = StringRegExp($sResult, "(?mi)^(?:SERVICE_NAME|DISPLAY_NAME):\h*(\N+)", 3) If IsArray($aResult) Then Local $aServices [(UBound($aResult) / 2)+1][2] , $n = 1 For $i = 0 To UBound($aResult) - 1 Step 2 $aServices[$n][0] = $aResult[$i] $aServices[$n][1] = $aResult[$i + 1] $n += 1 Next If $Sort = 1 Then _ArraySort($aServices, 0, 0, 0, 1) ; Sort by DisplayName $aServices[0][0] = UBound($aServices)-1 $Output = $aServices EndIf $Output[0][0] = UBound($Output)-1 Return $Output EndFunc thanks! Edited April 26, 2014 by Guest Link to comment Share on other sites More sharing options...
jguinch Posted April 26, 2014 Share Posted April 26, 2014 Seems to be good... Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF 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