Что нового

Как получить дескриптор окна процесса

lixar21

Новичок
Сообщения
70
Репутация
0
Доброе утро. Подскажите с решением.

Имеется скрипт, который каким-то образом получает дескриптор окна процесса.
Но вот как задать в этом скрипте нужный процесс (для которого нужно определить дескриптор) - непонятно...
Код:
#Include <WinAPI.au3>

#Region Local Variables and Constants

Global $__Data

#EndRegion Local Variables and Constants

; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_EnumProcessWindows
; Description....: Enumerates the windows that belong to the specified process.
; Syntax.........: _WinAPI_EnumProcessWindows ( $PID [, $fVisible] )
; Parameters.....: $PID      - The PID of the process. Default (0) is the current process.
;                  $fVisible - Specifies whether enumerates the invisible window, valid values:
;                  |TRUE     - Enumerate only visible windows. (Default)
;                  |FALSE    - Enumerate all windows.
; Return values..: Success   - The 2D array of the handles to the windows and classes for the specified process.
;                              [0][0] - Number of rows in array (n).
;                              [0][1] - Unused.
;                              [1][0] - Window handle.
;                              [1][1] - Window class name.
;                              [n][0] - Window handle.
;                              [n][1] - Window class name.
;                  Failure   - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: None
; Related........:
; Link...........: None
; Example........: Yes
; ===============================================================================================================================

Func _WinAPI_EnumProcessWindows($PID, $fVisible = 1)

    Local $Threads = _WinAPI_EnumProcessThreads($PID)

    If @error Then
        Return SetError(1, 0, 0)
    EndIf

    Local $hEnumProc = DllCallbackRegister('__EnumWindowsProc','int','hwnd;int')
    Local $Error = 1

    Dim $__Data[101][2] = [[0]]
    For $i = 1 To $Threads[0]
        DllCall('user32.dll', 'int', 'EnumThreadWindows', 'dword', $Threads[$i], 'ptr',  DllCallbackGetPtr($hEnumProc), 'int', $fVisible)
        If @error Then
            $__Data = 0
            ExitLoop
        EndIf
    Next
    If IsArray($__Data) Then
        $Error = 0
        If $__Data[0][0] Then
            ReDim $__Data[$__Data[0][0] + 1][2]
        Else
            $__Data = 0
        EndIf
    EndIf
    DllCallbackFree($hEnumProc)
    Return SetError($Error, 0, $__Data)
EndFunc   ;==>_WinAPI_EnumProcessWindows

Func _WinAPI_EnumProcessThreads($PID)

    If Not $PID Then
        $PID = _WinAPI_GetCurrentProcessID()
        If Not $PID Then
            Return SetError(1, 0, 0)
        EndIf
    EndIf

    Local $hSnapshot = DllCall('kernel32.dll', 'ptr', 'CreateToolhelp32Snapshot', 'dword', 0x00000004, 'dword', 0)

    If (@error) Or ($hSnapshot[0] = 0) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $tTHREADENTRY32 = DllStructCreate('dword Size;dword Usage;dword ThreadID;dword OwnerProcessID;long BasePri;long DeltaPri;dword Flags')
    Local $pTHREADENTRY32 = DllStructGetPtr($tTHREADENTRY32)
    Local $Ret, $Result[101] = [0]

    $hSnapshot = $hSnapshot[0]
    DllStructSetData($tTHREADENTRY32, 'Size', DllStructGetSize($tTHREADENTRY32))
    $Ret = DllCall('kernel32.dll', 'int', 'Thread32First', 'ptr', $hSnapshot, 'ptr', $pTHREADENTRY32)
    While (Not @error) And ($Ret[0])
        If DllStructGetData($tTHREADENTRY32, 'OwnerProcessID') = $PID Then
            $Result[0] += 1
            If $Result[0] > UBound($Result) - 1 Then
                ReDim $Result[$Result[0] + 100]
            EndIf
            $Result[$Result[0]] = DllStructGetData($tTHREADENTRY32, 'ThreadID')
        EndIf
        $Ret = DllCall('kernel32.dll', 'int', 'Thread32Next', 'ptr', $hSnapshot, 'ptr', $pTHREADENTRY32)
    WEnd
    _WinAPI_CloseHandle($hSnapshot)
    If $Result[0] Then
        ReDim $Result[$Result[0] + 1]
    Else
        Return SetError(1, 0, 0)
    EndIf
    Return $Result
EndFunc   ;==>_WinAPI_EnumProcessThreads

Func __EnumWindowsProc($hWnd, $fVisible)
    If ($fVisible) And (Not BitAND(WinGetState($hWnd), 2)) Then
        Return 1
    EndIf
    $__Data[0][0] += 1
    If $__Data[0][0] > UBound($__Data) - 1 Then
        ReDim $__Data[$__Data[0][0] + 100][2]
    EndIf
    $__Data[$__Data[0][0]][0] = $hWnd
    $__Data[$__Data[0][0]][1] = _WinAPI_GetClassName($hWnd)
    Return 1
EndFunc   ;==>__EnumWindowsProc

#Region Example

#Include <Array.au3>

Global $aWnd = _WinAPI_EnumProcessWindows(ProcessExists('explorer.exe'))

If IsArray($aWnd) Then
    _ArrayDisplay($aWnd, '_WinAPI_EnumProcessWindows')
EndIf

#EndRegion Example

Как получить дескриптор окна процесса, который в диспетчере задач называется 1642342.exe ?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Код:
ProcessList('Имя процесса')

Возвращает Pid процесса.
Это значение используешь в функции
Код:
_WinAPI_EnumProcessWindows

Получаешь массив с дескриптором окна процесса
 

Zmy

Знающий
Сообщения
18
Репутация
6
Попробуйте вот так.

Код:
#Include <WinAPI.au3>
#Region Local Variables and Constants
Global $__Data, $sPr
#EndRegion Local Variables and Constants
; #FUNCTION# ====================================================================================================================
; Name...........: _WinAPI_EnumProcessWindows
; Description....: Enumerates the windows that belong to the specified process.
; Syntax.........: _WinAPI_EnumProcessWindows ( $PID [, $fVisible] )
; Parameters.....: $PID      - The PID of the process. Default (0) is the current process.
;                  $fVisible - Specifies whether enumerates the invisible window, valid values:
;                  |TRUE     - Enumerate only visible windows. (Default)
;                  |FALSE    - Enumerate all windows.
; Return values..: Success   - The 2D array of the handles to the windows and classes for the specified process.
;                              [0][0] - Number of rows in array (n).
;                              [0][1] - Unused.
;                              [1][0] - Window handle.
;                              [1][1] - Window class name.
;                              [n][0] - Window handle.
;                              [n][1] - Window class name.
;                  Failure   - 0 and sets the @error flag to non-zero.
; Author.........: Yashied
; Modified.......:
; Remarks........: None
; Related........:
; Link...........: None
; Example........: Yes
; ===============================================================================================================================
$sPr = StringRegExpReplace(StringStripWS(InputBox("Input Proc Name", "Введите имя процесса." , "explorer"), 3), '\.exe', '') & '.exe'
If @error Then Exit
Func _WinAPI_EnumProcessWindows($PID, $fVisible = 1)
Local $Threads = _WinAPI_EnumProcessThreads($PID)
If @error Then
Return SetError(1, 0, 0)
EndIf
Local $hEnumProc = DllCallbackRegister('__EnumWindowsProc','int','hwnd;int')
Local $Error = 1
Dim $__Data[101][2] = [[0]]
For $i = 1 To $Threads[0]
DllCall('user32.dll', 'int', 'EnumThreadWindows', 'dword', $Threads[$i], 'ptr',  DllCallbackGetPtr($hEnumProc), 'int', $fVisible)
If @error Then
$__Data = 0
ExitLoop
EndIf
Next
If IsArray($__Data) Then
$Error = 0
If $__Data[0][0] Then
ReDim $__Data[$__Data[0][0] + 1][2]
Else
$__Data = 0
EndIf
EndIf
DllCallbackFree($hEnumProc)
Return SetError($Error, 0, $__Data)
EndFunc

Func _WinAPI_EnumProcessThreads($PID)
If Not $PID Then
$PID = _WinAPI_GetCurrentProcessID()
If Not $PID Then
Return SetError(1, 0, 0)
EndIf
EndIf
Local $hSnapshot = DllCall('kernel32.dll', 'ptr', 'CreateToolhelp32Snapshot', 'dword', 0x00000004, 'dword', 0)
If (@error) Or ($hSnapshot[0] = 0) Then
Return SetError(1, 0, 0)
EndIf
Local $tTHREADENTRY32 = DllStructCreate('dword Size;dword Usage;dword ThreadID;dword OwnerProcessID;long BasePri;long DeltaPri;dword Flags')
Local $pTHREADENTRY32 = DllStructGetPtr($tTHREADENTRY32)
Local $Ret, $Result[101] = [0]
$hSnapshot = $hSnapshot[0]
DllStructSetData($tTHREADENTRY32, 'Size', DllStructGetSize($tTHREADENTRY32))
$Ret = DllCall('kernel32.dll', 'int', 'Thread32First', 'ptr', $hSnapshot, 'ptr', $pTHREADENTRY32)
While (Not @error) And ($Ret[0])
If DllStructGetData($tTHREADENTRY32, 'OwnerProcessID') = $PID Then
$Result[0] += 1
If $Result[0] > UBound($Result) - 1 Then
ReDim $Result[$Result[0] + 100]
EndIf
$Result[$Result[0]] = DllStructGetData($tTHREADENTRY32, 'ThreadID')
EndIf
$Ret = DllCall('kernel32.dll', 'int', 'Thread32Next', 'ptr', $hSnapshot, 'ptr', $pTHREADENTRY32)
WEnd
_WinAPI_CloseHandle($hSnapshot)
If $Result[0] Then
ReDim $Result[$Result[0] + 1]
Else
Return SetError(1, 0, 0)
EndIf
Return $Result
EndFunc

Func __EnumWindowsProc($hWnd, $fVisible)
If ($fVisible) And (Not BitAND(WinGetState($hWnd), 2)) Then
Return 1
EndIf
$__Data[0][0] += 1
If $__Data[0][0] > UBound($__Data) - 1 Then
ReDim $__Data[$__Data[0][0] + 100][2]
EndIf
$__Data[$__Data[0][0]][0] = $hWnd
$__Data[$__Data[0][0]][1] = _WinAPI_GetClassName($hWnd)
Return 1
EndFunc

#Region Example
#Include <Array.au3>
Global $aWnd = _WinAPI_EnumProcessWindows(ProcessExists($spr))
If IsArray($aWnd) Then
_ArrayDisplay($aWnd, '_WinAPI_EnumProcessWindows')
EndIf
#EndRegion Example
 
Автор
L

lixar21

Новичок
Сообщения
70
Репутация
0
Zmy , вроде работает.
Спасибо за ответ.
 
Верх