Sign in to follow this  
Followers 0
Luigi

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

5 posts in this topic

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

m(o.O)m

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 ;).


[center]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.[/center]

Share this post


Link to post
Share on other sites

SmOke_N, you script work very well, in another way!
Always good learn another way.

I would like to know because you do not much like wmi?
is good to know the pros and cons.
 
Thank you for your reply, is very appreciate.
 
Detefon

m(o.O)m

Share this post


Link to post
Share on other sites

I understand JohnOne, thank you!


m(o.O)m

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  
Followers 0