Jump to content
Sign in to follow this  
Luigi

the are another best way to know if a Windows Service is running by your path?

Recommended Posts

Hello forum!

I need knows if a Windows Service is running and know your Windows Service Name to stop it.

I give a path's windows service, and return an array with Windows Service Name and you state...

There are another (best) way to do this?

Br, Detefon

#include <String.au3>
#include <Array.au3>

Local $aRun = Service_Is_Running_From_Path('C:\Program Files (x86)\Common Files\Adobe\ARM\1.0\armsvc.exe')
_ArrayDisplay($aRun)

Func Service_Is_Running_From_Path($in = '')
    Local $aRet[2] = [0, 0]
    Local $aServ[1][3]
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\cimv2")
    Local $arrName = StringSplit("Name,PathName,State", ",", 2)

    Local $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Service", "WQL", 0x30)

    Local $id
    If IsObj($colItems) Then
        For $objItem In $colItems
            $id = UBound($aServ, 1)
            ReDim $aServ[$id + 1][3]
            For $jj = 0 To 2
                $aServ[$id - 1][$jj] = Execute('$objItem.' & $arrName[$jj])
            Next
            If StringInStr($aServ[$id - 1][1], $in) Then
                $aRet[0] = $aServ[$id - 1][0]
                Switch $aServ[$id - 1][2]
                    Case "Running"
                        $aRet[1] = True
                    Case "Stopped"
                        $aRet[1] = False
                EndSwitch
                Return $aRet
            EndIf
        Next
        Return SetError(1, 0, $aRet)
    Else
        Return SetError(2, 0, $aRet)
    EndIf
EndFunc   ;==>Service_Is_Running_From_Path

Share this post


Link to post
Share on other sites

I'm not a real fan of WMI, so this is an alternative (I imagine it's faster as well).

#include <WinAPI.au3>
#include <WinAPIProc.au3>
#include <Array.au3>

_EnableDebugPrivilege()

; get an array of processes that match my criteria
Global $gsExeToFind = "svchost.exe"; obviously change this, it's just for demo
Global $gsPathToExe = "C:\Windows\System32\svchost.exe" ; change this to path
Global $gaProcess = _myGetRunningProcesses($gsExeToFind, $gsPathToExe)
; here is where we would do a loop like:
; For $i = 1 to Ubound($gaProcess) - 1
;    ProcessClose($gaProcess[$i])
; Next

_ArrayDisplay($gaProcess)

Func _myGetRunningProcesses($vProcess, $sPath)

    Local $aPList = 0
    Local $bWorkWithList = (IsInt($vProcess) Or _
        StringIsInt($vProcess)) ? False : True

    If $bWorkWithList Then $aPList = ProcessList($vProcess)

    Local $sPID = ""
    If IsArray($aPList) Then
        For $i = 1 To UBound($aPList) - 1
            If _ProcessGetPathEx($aPList[$i][1]) = $sPath Then
                $sPID &= $aPList[$i][1] & @LF
            EndIf
        Next
    Else
        If _ProcessGetPathEx($vProcess) = $sPath Then
            $sPID &= $vProcess & @LF
        EndIf
    EndIf

    Local $aRet = StringSplit(StringTrimRight($sPID, 1), @LF)
    ; turn back into integers
    For $i = 1 To UBound($aRet) - 1
        $aRet[$i] = Int($aRet[$i])
    Next

    Return $aRet
EndFunc

;

Func _EnableDebugPrivilege()

    Local $h_curproc = _WinAPI_GetCurrentProcess()
    Local $h_token = _Security__OpenProcessToken($h_curproc, _
            BitOR($TOKEN_ADJUST_PRIVILEGES, $TOKEN_QUERY))
    If Not $h_token Then
        Return SetError(2, 0, 0)
    EndIf

    Local $n_sdn = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME)

    Local $t_tokenpriv = DllStructCreate("dword;dword;long;dword")
    Local $p_tokenpriv = DllStructGetPtr($t_tokenpriv)
    DllStructSetData($t_tokenpriv, 1, 1)
    DllStructSetData($t_tokenpriv, 2, $n_sdn)
    DllStructSetData($t_tokenpriv, 3, 0)
    DllStructSetData($t_tokenpriv, 4, $SE_PRIVILEGE_ENABLED)
    Local $n_tokensize = DllStructGetSize($t_tokenpriv)

    Local $b_ret = _Security__AdjustTokenPrivileges($h_token, False, _
            $p_tokenpriv, $n_tokensize)

    _WinAPI_CloseHandle($h_token)

    Return SetError(Not $b_ret, 0, $b_ret)
EndFunc   ;==>_EnableDebugPrivilege

; @param1 = process name or pid
; @param2 = default 0 = drive\etc format
;           true = native system path format
Func _ProcessGetPathEx($v_process, $b_native = 0)

    Local $i_pid = ProcessExists($v_process)
    If Not $i_pid Then
        ; process does not exist
        Return SetError(1, 0, "")
    EndIf

    Local $sz_filepath = ""
    ; are we working with anything less than vista?
    Local Static $nWVers = ($__WINVER <> "") ? $__WINVER : __WINVER()
    If $nWVers < 0x0600 Then
        ; _WinAPI_GetProcessFileName seems misleading
        $sz_filepath = _WinAPI_GetProcessFileName($i_pid)
        Return SetError(@error, @extended, $sz_filepath)
    EndIf

    ; vista and above, should help with possible 64bit issues as well
    Local $h_k32 = DllOpen("Kernel32.dll")
    If @error Or Not $h_k32 Then
        ; could not open kernel32.dll
        Return SetError(2, 0, 0)
    EndIf

    Local Const $pgp_PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
    Local Const $pgp_PROCESS_QUERY_INFORMATION = 0x0400
    Local Const $pgp_PROCESS_NAME_NATIVE = 0x00000001

    ; open process with query info only
    Local $a_openprocess = DllCall($h_k32, "handle", "OpenProcess", _
            "long", BitOR($pgp_PROCESS_QUERY_INFORMATION, _
            $pgp_PROCESS_QUERY_LIMITED_INFORMATION), _
            "int", 0, "long", $i_pid)
    Local $i_err = @error
    If $i_err Or Not IsArray($a_openprocess) Then
        DllClose($h_k32)
        ; error code from dllcall sent as extended
        Return SetError(3, $i_err, 0)
    EndIf
    Local $h_openproc = $a_openprocess[0]

    Local $n_native = $b_native ? $pgp_PROCESS_NAME_NATIVE : 0
    Local $a_query = DllCall($h_k32, "bool", "QueryFullProcessImageNameW", _
            "handle", $h_openproc, "dword", $n_native, "wstr", "", "int*", 4096)
    $i_err = @error
    If $i_err Or Not IsArray($a_query) Then
        DllClose($h_k32)
        ; error code from dllcall sent as extended
        Return SetError(4, $i_err, 0)
    EndIf

    _WinAPI_CloseHandle($h_openproc)
    DllClose($h_k32)

    ; return string length as extended
    Return SetError(0, $a_query[4], $a_query[3])
EndFunc   ;==>_ProcessGetPathEx

Don't let the length of the helper functions take away from the simplicity of the use ;).


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...