Adam9 Posted May 18, 2005 Posted May 18, 2005 I need to check the state of the service. The problem is that technically it has started, but it may be paused. So checking for start/stop states isn't enough.The MSDN article here says that this function will return the state that I need because it uses information from this structure. I originally borrowed some code from someone on the forums to check the state of the service, but it only checks for started/stopped. And a paused service (which is what I need to check for) is technically started.Here is my existing servicerunning function:Func _ServiceRunning($sComputerName, $sServiceName) Local $hAdvapi32 Local $arRet Local $hSC Local $hService Local $bRunning = 0 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _ "str", $sComputerName, _ "str", "ServicesActive", _ "long", $SC_MANAGER_CONNECT) If $arRet[0] <> 0 Then $hSC = $arRet[0] $arRet = DllCall($hAdvapi32, "long", "OpenService", _ "long", $hSC, _ "str", $sServiceName, _ "long", $SERVICE_INTERROGATE) If $arRet[0] <> 0 Then $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "int", "ControlService", _ "long", $hService, _ "long", $SERVICE_CONTROL_INTERROGATE, _ "str", "") $bRunning = $arRet[0] DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC) EndIf DllClose($hAdvapi32) Return $bRunning EndFuncAny ideas on how I can check for the actual state? Thanks!
Kerberuz Posted May 18, 2005 Posted May 18, 2005 (edited) After looking at some of the api calls it looks like you should use the QueryServiceStatus API call. In this VB example you can convert it to use in AutoIt pretty easily it looks like. You will want the function ServiceStatus.Here check out this, I'm sure you will be able to piece it all together.API Call Edited May 18, 2005 by Kerberuz Kerby
DaveF Posted May 18, 2005 Posted May 18, 2005 You can run:sc query [servicename] > output.txt...and check the output text file for PAUSED.If you use the beta release of AutoIt there is an extension of the Run function that would let you capture the output directly without redirecting to a text file. Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.
Adam9 Posted May 20, 2005 Author Posted May 20, 2005 The sc command does exactly what I need. Unfortunately, this app has to run on Windows versions older than XP I took a look at the VB code and tried porting it, but the array I get back is exactly the same regardless of the state of the service I am checking for. Array Results: 0 1527358 (Blank) 4 Here's my AutoIt code without the variable declarations:_ServiceRunning('', 'McShield') Func _ServiceRunning($sComputerName, $sServiceName) Local $hAdvapi32 Local $arRet Local $hSC Local $hService Local $bRunning = 0 Local $status $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $arRet = DllCall($hAdvapi32, "long", "OpenSCManager", _ "str", $sComputerName, _ "str", "ServicesActive", _ "long", $SC_MANAGER_CONNECT) If $arRet[0] <> 0 Then $hSC = $arRet[0] $arRet = DllCall($hAdvapi32, "long", "OpenService", _ "long", $hSC, _ "str", $sServiceName, _ "long", $SERVICE_INTERROGATE) If $arRet[0] <> 0 Then $hService = $arRet[0] $arRet = DllCall($hAdvapi32, "long", "QueryServiceStatus", "long", $hSC, "str", 'McShield', "long", $SERVICE_QUERY_STATUS) $bRunning = $arRet[0] _ArrayDisplay($arRet, 'hi') ;MsgBox(4096,'Debug', $bRunning) DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSC) EndIf DllClose($hAdvapi32) EndFunc Here's the relevant VB code:Public Function ServiceStatus(ComputerName As String, ServiceName As String) As String Dim ServiceStat As SERVICE_STATUS Dim hSManager As Long Dim hService As Long Dim hServiceStatus As Long ServiceStatus = "" hSManager = OpenSCManager(ComputerName, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS) If hSManager <> 0 Then hService = OpenService(hSManager, ServiceName, SERVICE_ALL_ACCESS) If hService <> 0 Then hServiceStatus = QueryServiceStatus(hService, ServiceStat) If hServiceStatus <> 0 Then Select Case ServiceStat.dwCurrentState Case SERVICE_STOPPED ServiceStatus = "Stopped" Case SERVICE_START_PENDING ServiceStatus = "Start Pending" Case SERVICE_STOP_PENDING ServiceStatus = "Stop Pending" Case SERVICE_RUNNING ServiceStatus = "Running" Case SERVICE_CONTINUE_PENDING ServiceStatus = "Coninue Pending" Case SERVICE_PAUSE_PENDING ServiceStatus = "Pause Pending" Case SERVICE_PAUSED ServiceStatus = "Paused" End Select End If CloseServiceHandle hService End If CloseServiceHandle hSManager End If End Function
SumTingWong Posted May 20, 2005 Posted May 20, 2005 Here you go. You need the latest beta for DllStruct support. expandcollapse popupOpt("MustDeclareVars", 1) Global Const $SC_MANAGER_CONNECT = 0x0001 Global Const $SERVICE_QUERY_STATUS = 0x0004 ; Service State -- for CurrentState Global Const $SERVICE_STOPPED = 0x00000001 Global Const $SERVICE_START_PENDING = 0x00000002 Global Const $SERVICE_STOP_PENDING = 0x00000003 Global Const $SERVICE_RUNNING = 0x00000004 Global Const $SERVICE_CONTINUE_PENDING = 0x00000005 Global Const $SERVICE_PAUSE_PENDING = 0x00000006 Global Const $SERVICE_PAUSED = 0x00000007 ConsoleWrite(_ServiceCurrentState(@ComputerName, "spooler") & @LF) Func _ServiceCurrentState($sComputerName, $sServiceName) Local $hAdvapi32 Local $hSCM Local $hService Local $aDllRet Local $SERVICE_STATUS Local $nState = 0 $hAdvapi32 = DllOpen("advapi32.dll") If $hAdvapi32 = -1 Then Return 0 $aDllRet = DllCall($hAdvapi32, "long", "OpenSCManager", _ "str", $sComputerName, _ "str", "ServicesActive", _ "long", $SC_MANAGER_CONNECT) If $aDllRet[0] <> 0 Then $hSCM = $aDllRet[0] ConsoleWrite("hSCM=" & $hSCM & @LF) $aDllRet = DllCall($hAdvapi32, "long", "OpenService", _ "long", $hSCM, _ "str", $sServiceName, _ "long", $SERVICE_QUERY_STATUS) If $aDllRet[0] <> 0 Then $hService = $aDllRet[0] ConsoleWrite("hService=" & $hService & @LF) $SERVICE_STATUS = DllStructCreate("dword;dword;dword;dword;dword;dword;dword") If Not @error Then $aDllRet = DllCall($hAdvapi32, "int", "QueryServiceStatus", _ "long", $hService, _ "ptr", DllStructGetPtr($SERVICE_STATUS)) If Not @error And $aDllRet[0] > 0 Then $nState = DllStructGetData($SERVICE_STATUS, 2) DllStructDelete($SERVICE_STATUS) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hService) EndIf DllCall($hAdvapi32, "int", "CloseServiceHandle", "long", $hSCM) EndIf DllClose($hAdvapi32) Return $nState EndFunc
sylvanie Posted May 20, 2005 Posted May 20, 2005 Hello,The sc command does exactly what I need. Unfortunately, this app has to run on Windows versions older than XPÂ If your app will run on 2000 or NT, you can use psservice from the pstools ( http://www.sysinternals.com )the syntax yo query the state of a service is : psservice query process_name
Adam9 Posted May 20, 2005 Author Posted May 20, 2005 Sylvanie: Thanks for the tip, but I got the API calls working. Sum: Thanks! I integrated the code and it worked perfectly.
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