Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   как убить дерево процессов ? (http://forum.oszone.net/showthread.php?t=227686)

mitiya 12-02-2012 20:29 1857214

как убить дерево процессов ?
 
скрипт запускается с флэшки и запускает тотал коммандер.
скрипт проверяет наличие ini файла на флэшке . когда его нет (то есть флэшка извлечена)
скрипт должен запустить taskkill , но почему-то не запускается. Хотя мэсэджт до и после отрабатываются.
Так же если просто удалить ini файл, то все отрабатывает нормально.

Код:

While FileExists(@ScriptDir & '\settings.ini')
        ; MsgBox(4096, 'pause',$Wait )
        Sleep($Wait)
Wend

MsgBox(4096, "END" ,'')
Run(@ComSpec & " /c " &'taskkill /t /f /PID ' & $exe,'','')
MsgBox(4096, "END" ,'')

ProcessClose($exe) в свою очередь всегда работает нормально , но он не убивает все дерево.

Creat0R 12-02-2012 23:42 1857344

Что содержится в переменной $exe?

Цитата:

Цитата mitiya
ProcessClose($exe) в свою очередь всегда работает нормально , но он не убивает все дерево. »

Вот функция для убийства дерева процесса:

Код:

_ProcessCloseTree("Test.exe")

Func _ProcessCloseTree($iPID)
    If IsString($iPID) Then
        $iPID = ProcessExists($iPID)
    EndIf

    If Not $iPID Then
        Return SetError(-1, 0, $iPID)
    EndIf

    Local Const $TH32CS_SNAPPROCESS = 0x00000002

    Local $a_tool_help = DllCall("Kernel32.dll", "long", "CreateToolhelp32Snapshot", "int", $TH32CS_SNAPPROCESS, "int", 0)

    If Not IsArray($a_tool_help) Or $a_tool_help[0] = -1 Then
        Return SetError(1, 0, $iPID)
    EndIf

    Local $tagPROCESSENTRY32 = _
        DllStructCreate( _
            "dword dwsize;" & _
            "dword cntUsage;" & _
            "dword th32ProcessID;" & _
            "uint th32DefaultHeapID;" & _
            "dword th32ModuleID;" & _
            "dword cntThreads;" & _
            "dword th32ParentProcessID;" & _
            "long pcPriClassBase;" & _
            "dword dwFlags;" & _
            "char szExeFile[260]")

    DllStructSetData($tagPROCESSENTRY32, 1, DllStructGetSize($tagPROCESSENTRY32))

    Local $p_PROCESSENTRY32 = DllStructGetPtr($tagPROCESSENTRY32)
    Local $a_pfirst = DllCall("Kernel32.dll", "int", "Process32First", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32)

    If Not IsArray($a_pfirst) Then
        Return SetError(2, 0, $iPID)
    EndIf

    Local $a_pnext, $i_child_pid, $i_parent_pid
    $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID")

    If $i_child_pid <> $iPID Then
        $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID")

        If $i_parent_pid = $iPID Then
            _ProcessCloseTree($i_child_pid)

            If @error <> 0 Then
                ProcessClose($i_child_pid)
            EndIf
        EndIf
    EndIf

    While 1
        $a_pnext = DllCall("Kernel32.dll", "int", "Process32Next", "long", $a_tool_help[0], "ptr", $p_PROCESSENTRY32)

        If IsArray($a_pnext) And $a_pnext[0] = 0 Then
            ExitLoop
        EndIf

        $i_child_pid = DllStructGetData($tagPROCESSENTRY32, "th32ProcessID")

        If $i_child_pid <> $iPID Then
            $i_parent_pid = DllStructGetData($tagPROCESSENTRY32, "th32ParentProcessID")

            If $i_parent_pid = $iPID Then
                _ProcessCloseTree($i_child_pid)

                If @error <> 0 Then
                    ProcessClose($i_child_pid)
                EndIf
            EndIf
        EndIf
    WEnd

    DllCall("Kernel32.dll", "int", "CloseHandle", "long", $a_tool_help[0])

    Return 1
EndFunc


mitiya 13-02-2012 13:59 1857670

что-то не работает. (по крайней мере на win7 64) , но мне в любом случае надо бы чтоб везде работало.

mitiya 24-02-2012 01:33 1865473

подумал что в моем случае логичней убивать не дерево, а просто процессы путь в которым ведет на флэшку.
для получения буквы диска я хотел использовать примерно следующий код, только в цикле.

Дак вот он работает только с теми приложениями у которых удается корректно получить путь. Путь к explorer.exe почему-то выдается как А , и в той части где происходит выделение из пути диска происходит ошибка.

Мне надо как-то отфильтровать неподходящие значения перед передачей в _PathSplitByRegExp , но в случае вообще пустых значений пути у меня не получилось.

Код:


#include <File.au3>
#include <Array.au3>
#include <GUIListView.au3>

Local $PID = ProcessExists("explorer.exe")

MsgBox(0, '', '-' & $PID & '-')

Local $path = _ProcessGetLocation($PID)

MsgBox(0, '1$path', '|' & $path & '|')

MsgBox(0, '', VarGetType($path))

MsgBox(0, '2', $path)

Local $drive = _PathSplitByRegExp($path)

MsgBox(0, '2', $drive[1])




;===============================================================================
; Function Name:    _PathSplitByRegExp()
; Description:      Split the path to 8 elements.
; Parameter(s):    $sPath - Path to split.
; Requirement(s): 
; Return Value(s):  On seccess - Array $aRetArray that contain 8 elements:
;                  $aRetArray[0] = Full path ($sPath)
;                  $aRetArray[1] = Drive letter
;                  $aRetArray[2] = Path without FileName and extension
;                  $aRetArray[3] = Full path without File Extension
;                  $aRetArray[4] = Full path without drive letter
;                  $aRetArray[5] = FileName and extension
;                  $aRetArray[6] = Just Filename
;                  $aRetArray[7] = Just Extension of a file
;
;                  On failure - If $sPath not include correct path (the path is not splitable),
;                  then $sPath returned.
;                  If $sPath not include needed delimiters, or it's emty,
;                  then @error set to 1, and returned -1.
;
; Note(s):          The path can include backslash as well (exmp: C:/test/test.zip).
;
; Author(s):        G.Sandler a.k.a CreatoR (MsCreatoR) - Thanks to amel27 for help with RegExp
;===============================================================================
Func _PathSplitByRegExp($sPath)
    If $sPath = "" Or (StringInStr($sPath, "\") And StringInStr($sPath, "/")) Then Return SetError(1, 0, -1)
 
    Local $aRetArray[8], $pDelim = ""
 
    If StringRegExp($sPath, '^(?i)([A-Z]:|\\)(\\[^\\]+)+$') Then $pDelim = "\"
    If StringRegExp($sPath, '(?i)(^.*:/)(/[^/]+)+$') Then $pDelim = "//"
 
    If $pDelim = "" Then $pDelim = "/"
    If Not StringInStr($sPath, $pDelim) Then Return $sPath
    If $pDelim = "\" Then $pDelim &= "\"
 
    $aRetArray[0] = $sPath ;Full path
    $aRetArray[1] = StringRegExpReplace($sPath,  $pDelim & '.*', $pDelim) ;Drive letter
    $aRetArray[2] = StringRegExpReplace($sPath, $pDelim & '[^' & $pDelim & ']*$', '') ;Path without FileName and extension
    $aRetArray[3] = StringRegExpReplace($sPath, '\.[^.]*$', '') ;Full path without File Extension
    $aRetArray[4] = StringRegExpReplace($sPath, '(?i)([A-Z]:' & $pDelim & ')', '') ;Full path without drive letter
    $aRetArray[5] = StringRegExpReplace($sPath, '^.*' & $pDelim, '') ;FileName and extension
    $aRetArray[6] = StringRegExpReplace($sPath, '.*' & $pDelim & '|\.[^.]*$', '') ;Just Filename
    $aRetArray[7] = StringRegExpReplace($sPath, '^.*\.', '') ;Just Extension of a file
 
    Return $aRetArray
EndFunc


Func _ProcessGetLocation($iPID)
    Local $aProc = DllCall('kernel32.dll', 'hwnd', 'OpenProcess', 'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $iPID)
    If $aProc[0] = 0 Then Return SetError(1, 0, '')
    Local $vStruct = DllStructCreate('int[1024]')
    DllCall('psapi.dll', 'int', 'EnumProcessModules', 'hwnd', $aProc[0], 'ptr', DllStructGetPtr($vStruct), 'int', DllStructGetSize($vStruct), 'int_ptr', 0)
    Local $aReturn = DllCall('psapi.dll', 'int', 'GetModuleFileNameEx', 'hwnd', $aProc[0], 'int', DllStructGetData($vStruct, 1), 'str', '', 'int', 2048)
    If StringLen($aReturn[3]) = 0 Then Return SetError(2, 0, '')
    Return $aReturn[3]
EndFunc



Время: 23:29.

Время: 23:29.
© OSzone.net 2001-