Что нового

[Процессы]Перезапуск Total Commander разных версий (x64-x86)

Skif_off

Знающий
Сообщения
173
Репутация
12
Кажется, оптимальный вариант, правильно работающий и в случае нескольких копий ТС (+ перезапуск со сменой разрядности).
Код:
#NoTrayIcon
#include <WinAPIEx.au3>

Opt('WinWaitDelay', 150)

Global $Title
Local $iTCPID, $COMMANDER_EXE

If $CmdLine[0] <> 1 Then
    MsgBox(4096, 'Restart TC:', 'Проверьте параметры запуска')
    Exit
EndIf

$iTCPID = _WinAPI_GetParentProcess(@AutoItPID)
$COMMANDER_EXE = @ScriptDir & '\' & _WinAPI_GetProcessName($iTCPID)

$Title = _Process2Win($iTCPID)

Select
    Case $CmdLine[1] = '--restart'
        WinClose($Title)
        Sleep(150)
        While ProcessExists($iTCPID)
            Sleep(100)
        WEnd
        Run($COMMANDER_EXE)
    Case $CmdLine[1] = '--8664'
        If @OSArch = 'X86' Then
            MsgBox(48 + 4096, 'Restart TC', 'Вы пытаетесь перезапустить TC со сменой разрядности х86 > х64 на' & _
                  ' х86 ОС!' & @CRLF & 'Это невозможно.')
            Exit
        EndIf
        WinClose($Title)
        Sleep(150)
        While ProcessExists($iTCPID)
            Sleep(100)
        WEnd
        $COMMANDER_EXE = StringRegExpReplace($COMMANDER_EXE, '^.*\\', '')
        If $COMMANDER_EXE = 'TOTALCMD.EXE' Then
            Run('"' & @ScriptDir & '\TOTALCMD64.EXE"')
        ElseIf $COMMANDER_EXE = 'TOTALCMD64.EXE' Then
            Run('"' & @ScriptDir & '\TOTALCMD.EXE"')
        EndIf
EndSelect

Func _Process2Win($Pid)
    If IsString($Pid) Then $Pid = ProcessExists($Pid)
    If $Pid = 0 Then Return -1
    $List = WinList('[CLASS:TTOTAL_CMD]')
    For $i = 1 To $List[0][0]
        If $List[$i][0] <> '' And BitAND(WinGetState($List[$i][1]), 2) Then
            $wPid = WinGetProcess($List[$i][1])
            If $wPid = $Pid Then Return $List[$i][1]
        EndIf
    Next
    Return -1
EndFunc
Код:
TOTALCMD#BAR#DATA
"%COMMANDER_PATH%\AutoIt3.exe" "%COMMANDER_PATH%\Restart.au3" --restart

%COMMANDER_PATH%\ButtonBar\TCRestart2.ico
Перезапуск ТС
%COMMANDER_PATH%\
0
-1
Код:
TOTALCMD#BAR#DATA
"%COMMANDER_PATH%\AutoIt3.exe" "%COMMANDER_PATH%\Restart.au3" --8664

%COMMANDER_PATH%\ButtonBar\TCRestart2.ico
x86 <-> x64
%COMMANDER_PATH%\
0
-1
Код:
If WinExists('[CLASS:TFindFile]') Then __Close_TFindFile_And_TCmpForm('[CLASS:TFindFile]')
If WinExists('[CLASS:TCmpForm]') Then __Close_TFindFile_And_TCmpForm('[CLASS:TCmpForm]')

Func __Close_TFindFile_And_TCmpForm($sFindCmp)
    Local $aFindCmpList, $iFindCmpPID, $iParentPID, $i
    $aFindCmpList = WinList($sFindCmp)
    If $aFindCmpList[0][0] = 1 Then
        $iFindCmpPID = WinGetProcess($aFindCmpList[1][1])
        $iParentPID = _WinAPI_GetParentProcess($iFindCmpPID)
        If $iParentPID = $iTCPID Then
            WinClose($aFindCmpList[1][1])
        EndIf
    ElseIf $aFindCmpList[0][0] > 1 Then
        For $i = 1 To $aFindCmpList[0][0]
            $iFindCmpPID = WinGetProcess($aFindCmpList[$i][1])
            $iParentPID = _WinAPI_GetParentProcess($iFindCmpPID)
            If $iParentPID = $iTCPID Then
                WinClose($aFindCmpList[$i][1])
            EndIf
        Next
    EndIf
EndFunc   ;==>__Close_TFindFile_And_TCmpForm

Заменил Sleep() на While...WEnd, очевидно же: проще ждать закрытия родительской копии ТС, ведь PID известен. Вместе с Opt('WinWaitDelay', 150) заметно уменьшилось время до запуска ТС.

Upd:
- Sleep(250) -> Sleep(150);
- два параметра запуска скрипта:
Код:
--restart - перезапуск;
--8664 - перезапуск со сменой разрядности;
чтобы не перезапустить при ненамеренном клике по скрипту;
- при перезапуске со сменой разрядности на х86 ОС процесс ТС не будет завершён и вылезет предупреждение;
- поправлена и переименована функция закрытия дочерних запущенных отдельным процессом поиска и синхронизации;
- заголовки окон, декларирование переменных, Opt('WinWaitDelay', 150)
 
Верх