1

Тема: AHK: Самозакрытие при повторном запуске

В справке имеется такой пример.

#Persistent
#SingleInstance, Force
;DetectHiddenWindows, On

OnExit, ExitSub
Return

ExitSub:
If A_ExitReason not in Logoff,Shutdown
ExitApp
;Process, Close, DllCall("GetCurrentProcessId")
;WinKill, ahk_pid DllCall("GetCurrentProcessId")
;WinClose, ahk_pid DllCall("GetCurrentProcessId")

---------------------------
CloseSelf.ahk
---------------------------
Could not close the previous instance of this script.  Keep waiting?
---------------------------
Да   Нет   
---------------------------

Как же проще заставить (в т.ч. по Reload или Single) самозакрываться?

2

Re: AHK: Самозакрытие при повторном запуске

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

3

Re: AHK: Самозакрытие при повторном запуске

Да, замечал. Но кроме WMI и поиска по комстроке в голову ничего не приходит. Есть получше предложение?

4

Re: AHK: Самозакрытие при повторном запуске

http://forum.script-coding.com/viewtopi … 400#p85400

5

Re: AHK: Самозакрытие при повторном запуске

#Persistent
#SingleInstance, Force
DetectHiddenWindows, On
CurPID := DllCall("GetCurrentProcessId")

OnExit, ExitSub
Return

ExitSub:
#If A_ExitReason not in Logoff,Shutdown
  WinGet, List, List, %A_ScriptFullPath% ahk_class AutoHotkey
  Loop % List { 
      WinGet, PID, PID, % "ahk_id" List%A_Index%
      If (PID != CurPID)
          Process, Close, %PID% 
  }
  ExitApp
#If

По нулям.

6

Re: AHK: Самозакрытие при повторном запуске

При повторном запуске предыдущий экземпляр убивается.
Разве это не то, что вы хотели?

#SingleInstance Off  
DetectHiddenWindows, On
CurPID := DllCall("GetCurrentProcessId")
WinGet, List, List, %A_ScriptFullPath% ahk_class AutoHotkey
Loop % List
{ 
    WinGet, PID, PID, % "ahk_id" List%A_Index%
    If (PID != CurPID)
        Process, Close, %PID% 
}
msgbox

7 (изменено: Flasher, 2017-01-06 05:42:26)

Re: AHK: Самозакрытие при повторном запуске

Эта часть кода, реализующая предложение serzh82saratov, после задействования которой якобы скрипт должен самозакрыться.

#SingleInstance, Off не даст отследить состояние, при котором эта часть должна выполняться.

8 (изменено: teadrinker, 2017-01-06 17:39:36)

Re: AHK: Самозакрытие при повторном запуске

Так:

#Persistent
#SingleInstance, Off
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r|force|f)\s")
   ExitApp

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
         WinClose
   DetectHiddenWindows, % DHW_Prev
   Return res
}

или так:

#SingleInstance, Off
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r|force|f)\s")
   ExitApp

OnMessage(0x111, "WM_COMMAND")

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
         WinClose
   DetectHiddenWindows, % DHW_Prev
   Return res
}

WM_COMMAND(wp)  {
   if (wp = 65303)  ; reload
      ExitApp
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Самозакрытие при повторном запуске

Закрывает до кучи и блокнот со скриптом. Надо обработку ехе.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

10

Re: AHK: Самозакрытие при повторном запуске


#SingleInstance Off  
DetectHiddenWindows, On
OnExit, ExitSub

If Instr(StrGet(DllCall("GetCommandLine", Ptr)), "/restart")
{
	MsgBox, , , ExitApp Reload, 0.5
	ExitApp
}
WinGet, List, List, %A_ScriptFullPath% ahk_class AutoHotkey
Loop % List
{ 
	If (List%A_Index% = A_ScriptHwnd) 
		Continue
    WinGet, PID, PID, % "ahk_id" List%A_Index% + !(res := 1)
	Process, Close, %PID%  
}
If res
{
	MsgBox, , , Instance, 0.5
	ExitApp
}
MsgBox Reload?
Reload
Return

ExitSub:
	ExitApp
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Самозакрытие при повторном запуске

serzh82saratov пишет:

Надо обработку ехе

Достаточно изменить

WinGet, List, List, % A_ScriptFullPath

на

WinGet, List, List, % A_ScriptFullPath "ahk_class AutoHotkey"

Отредактировал. А твой вариант чем отличается, не пойму?
OnExit там лишний, возможные ключи не перечислены, PID напрасно вычисляется.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Самозакрытие при повторном запуске

Это была первая мысль, но в торопях незакавычил ahk_class.
Проверка ключей всё равно не верная, можно конечно для исходника добавить ехе - ключ - путь, у скомпилированного пробела в конце может не быть.
Но например ключ Reload мы же проверяем для запуска из вне, его именно так и запустят, мы же не страхуемся в своём коде от своей же Reload. Потому в ключах можно предположить всё что угодно.
С OnExit твой не работает.
PID для Process Close, думаю надежнее.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

13

Re: AHK: Самозакрытие при повторном запуске

serzh82saratov пишет:

Проверка ключей всё равно не верная

Не совсем понял, почему?

serzh82saratov пишет:

у скомпилированного пробела в конце может не быть.

Ну, у нас изначально об этом речи не было, а так можно добавить проверку на конец строки, в чём проблема.

serzh82saratov пишет:

С OnExit твой не работает.

Вроде работает:

#Persistent
#SingleInstance, Off
OnExit, Exit
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r|force|f)\s")
   ExitApp
Return

Exit:
	ExitApp

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
         WinClose
   DetectHiddenWindows, % DHW_Prev
   Return res
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

14

Re: AHK: Самозакрытие при повторном запуске

OnExit работает, ошибся. Не работает если запустить с ключом /restart.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

15

Re: AHK: Самозакрытие при повторном запуске

teadrinker пишет:

Да работает же. Только что попробовал:

Run "%A_AhkPath%" "D:\AHK\Scripts\_Разработка\NewFile2.ahk" /restart

Закрываются оба.

Удалил, проверял ещё раз. Надо было

Run "%A_AhkPath%" /restart "D:\AHK\Scripts\_Разработка\NewFile2.ahk"

Всё работает.

serzh82saratov пишет:

А если первого при запуске нет?

В смысле?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Самозакрытие при повторном запуске

С ком строки.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

17

Re: AHK: Самозакрытие при повторном запуске

Всё равно не понял.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

18

Re: AHK: Самозакрытие при повторном запуске

Если скрипт не запущен, и выполнить в cmd

%AutoHotkeyPath% /restart %ScriptPath%

то ничего не запускается.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

19

Re: AHK: Самозакрытие при повторном запуске

Ну и не должно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

20

Re: AHK: Самозакрытие при повторном запуске

Так сабж - закрытие при повторном запуске.
А тут мы запуск не повторяем, запущенного скрипта ведь нет.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

21

Re: AHK: Самозакрытие при повторном запуске

Ну да. А кто заставляет /restart писать, если скрипт не запущен? Не понял твою мысль.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: Самозакрытие при повторном запуске

Так не сработает:

#Persistent
#SingleInstance, Off
OnExit, Exit
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r|force|f)\s")
   ExitApp
Runwait, C:\Windows\System32\fsutil.exe file createnew D:\test.txt 10000000000
FileCopy D:\test.txt, D:\test1.txt, 1
Return

Exit:
	ExitApp

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
         WinClose
   DetectHiddenWindows, % DHW_Prev
   Return res
}

23

Re: AHK: Самозакрытие при повторном запуске

А откуда вообще тогда ключ /restart может появится?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Самозакрытие при повторном запуске

serzh82saratov пишет:

PID для Process Close, думаю надежнее.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25

Re: AHK: Самозакрытие при повторном запуске

serzh82saratov пишет:

Но например ключ Reload мы же проверяем для запуска из вне, его именно так и запустят, мы же не страхуемся в своём коде от своей же Reload. Потому в ключах можно предположить всё что угодно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26

Re: AHK: Самозакрытие при повторном запуске

Malcev пишет:

Так не сработает:

Это уже из области извращений. Понятно, что если изменить название скрипта, не сработает. serzh82saratov, всё равно тебя не понял. Давай сначала. В чём могут быть проблемы такого варианта?

#Persistent
#SingleInstance, Off
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r)(\s|$)")
   ExitApp
Return

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
         WinClose
   DetectHiddenWindows, % DHW_Prev
   Return res
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Самозакрытие при повторном запуске

По сабжу скрипт должен запускатся если нет другого запущенного экземпляра.
Даже если мы его запускаем из CMD или с ярлыка например с ключом restart.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28

Re: AHK: Самозакрытие при повторном запуске

teadrinker, я ничего не менял.
Я имею в виду, что если скрипт зависнет на какой-либо операции, то он с твоим кодом закроется только после окончания этой операции.

29

Re: AHK: Самозакрытие при повторном запуске

А, теперь понял. Да кому в голову придёт запускать с ключом restart, если это не нужно, и тем более, если так не запускается?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

30 (изменено: teadrinker, 2017-01-06 19:41:09)

Re: AHK: Самозакрытие при повторном запуске

Malcev пишет:

то он с твоим кодом закроется только после окончания этой операции

А, ясно. Ну предложи обходной вариант. WinKill можно попробовать. Но сомневаюсь, что это входит в задачу.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

Re: AHK: Самозакрытие при повторном запуске

Да кому в голову придёт запускать с ключом restart, если это не нужно, и тем более, если так не запускается?

Если ты не допускаешь такую вероятность, то почему допускаешь то что в скрипте будет команда Reload?
Команда Reload менее вероятна, чем невероятное предположение того что её со стороны зачем то запустят с таким ключом.
Команды Reload не должно быть в принципе, потому как по задаче вместо неё ExitApp.
Зачем прописывать в самом скрипте Reload, а потом думать как их все закрыть?
Вот и вопрос - зачем проверять такой ключ, если ты сам не ждёшь его "со стороны"?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

32

Re: AHK: Самозакрытие при повторном запуске

и тем более, если так не запускается?

По ТЗ должен запускатся, если не запущен другой.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

33 (изменено: teadrinker, 2017-01-06 19:51:55)

Re: AHK: Самозакрытие при повторном запуске

serzh82saratov пишет:

то почему допускаешь то что в скрипте будет команда Reload?

Не пойму, где у меня в скрипте Reload? А в командной строке restart появится автоматически, если перезапускать через меню.

serzh82saratov пишет:

По ТЗ должен запускатся, если не запущен другой.

Ну и запускай обычным способом, в чём проблема. Зачем с ключом restart-то?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

34

Re: AHK: Самозакрытие при повторном запуске

Про меню не подумал, стандартное из трея убрать можно, а из главного окна геморойно. Тогда ок.

Кстати почему

StrGet(DllCall("GetCommandLine", Ptr))

а не

DllCall("GetCommandLine", Str)
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

35

Re: AHK: Самозакрытие при повторном запуске

Ну предложи обходной вариант. WinKill можно попробовать

WinKill не сработает.

#Persistent
#SingleInstance, Off
OnExit, Exit
if CloseCopy() || RegExMatch(StrGet(DllCall("GetCommandLine", Ptr)), "i)\s/(restart|r|force|f)\s")
   ExitApp
Runwait, C:\Windows\System32\fsutil.exe file createnew D:\test.txt 10000000000
FileCopy D:\test.txt, D:\test1.txt, 1
Return

Exit:
	ExitApp

CloseCopy()  {
   DHW_Prev := A_DetectHiddenWindows
   DetectHiddenWindows, On
   WinGet, List, List, % A_ScriptFullPath " ahk_class AutoHotkey"
   Loop % List
   {
      if WinExist("ahk_id" List%A_Index%) != A_ScriptHwnd && res := true
      {
         WinClose
         WinWaitClose,,, 0
         if ErrorLevel
         {
            WinGet, PID, PID, % "ahk_id" List%A_Index%
            Process, Close, %PID%
            Process, WaitClose, %PID%
            NoTrayOrphans()     ; очистить трей от иконок закрытых приложений
         }
      }
   }
   DetectHiddenWindows, % DHW_Prev
   Return res
}


NoTrayOrphans()
{
    TrayInfo := TrayIcons("ahk_class Shell_TrayWnd", "ToolbarWindow32" . GetTrayBar())  
        . TrayIcons("ahk_class NotifyIconOverflowWindow", "ToolbarWindow321")
 
    Loop, Parse, TrayInfo, `n
    {  
        PID := StrX(A_Loopfield, "| PID: ", " |") 
        If !PID
            RemoveTrayIcon(StrX(A_Loopfield, "| hWnd: ", " |"), StrX(A_Loopfield, "| uID: ", " |"))   
    }
}

TrayIcons(traywindow, control)  
{
    DetectHiddenWindows, On
    WinGet, pidTaskbar, PID, %traywindow%
    hProc := DllCall("OpenProcess", "Uint", 0x38, "int", 0, "Uint", pidTaskbar)
    pProc := DllCall("VirtualAllocEx", "Uint", hProc, "Uint", 0, "Uint", 32, "Uint", 0x1000, "Uint", 0x4)
    SendMessage, 0x418, 0, 0, %control%, %traywindow%
    Loop, %ErrorLevel%
    {
        SendMessage, 0x417, A_Index - 1, pProc, %control%, %traywindow%
        VarSetCapacity(btn, 32, 0), VarSetCapacity(nfo, 32, 0)
        DllCall("ReadProcessMemory", "Uint", hProc, "Uint", pProc, "Uint", &btn, "Uint", 32, "Uint", 0)
        iBitmap := NumGet(btn, 0)
        idn := NumGet(btn, 4)
        Statyle := NumGet(btn, 8)
        If dwData := NumGet(btn, 12)
            iString := NumGet(btn, 16)
        Else
        {
            dwData := NumGet(btn, 16, "int64")
            iString := NumGet(btn, 24, "int64")
        }
        DllCall("ReadProcessMemory", "Uint", hProc, "Uint", dwData, "Uint", &nfo, "Uint", 32, "Uint", 0)
        If NumGet(btn,12)
        {
            hWnd := NumGet(nfo, 0)
            uID := NumGet(nfo, 4)
            nMsg := NumGet(nfo, 8)
            hIcon := NumGet(nfo, 20)
        }
        Else
        {
            hWnd := NumGet(nfo, 0, "int64")
            uID := NumGet(nfo, 8)
            nMsg := NumGet(nfo, 12)
            hIcon := NumGet(nfo, 24)
        }
        WinGet, pid, PID, ahk_id %hWnd%
        WinGet, sProcess, ProcessName, ahk_id %hWnd%
        WinGetClass, sClass, ahk_id %hWnd% 
        VarSetCapacity(sTooltip, 128)
        VarSetCapacity(wTooltip, 128*2)
        DllCall("ReadProcessMemory", "Uint", hProc, "Uint", iString, "Uint", &wTooltip, "Uint", 128*2, "Uint", 0)
        DllCall("WideCharToMultiByte", "Uint", 0, "Uint", 0, "str", wTooltip, "int", -1, "str", sTooltip, "int", 128, "Uint", 0, "Uint", 0)
        sTrayIcons .= "| Pid: " pid " | uID: " uID " | hWnd: " hWnd " |`n" 
    }
    DllCall("VirtualFreeEx", "Uint", hProc, "Uint", pProc, "Uint", 0, "Uint", 0x8000)
    DllCall("CloseHandle", "Uint", hProc)
    Return sTrayIcons
}

GetTrayBar()
{
    ControlGet, hParent, hWnd,, TrayNotifyWnd1, ahk_class Shell_TrayWnd
    ControlGet, hChild, hWnd,, ToolbarWindow321, ahk_id %hParent%
    Loop
    {
        ControlGet, hWnd, hWnd,, ToolbarWindow32%A_Index%, ahk_class Shell_TrayWnd
        If (hWnd == hChild)
            idxTB := A_Index
        If !hWnd || (hWnd == hChild)
            Break
    }
    Return idxTB
}

StrX(H, BS = "", ES = "", Tr = 1, ByRef OS = 1)
{
    Return (SP := InStr(H, BS, 0, OS)) && (L := InStr(H, ES, 0, SP + StrLen(BS))) && (OS := L + StrLen(ES)) ? SubStr(H, SP := Tr ? SP + StrLen(BS) : SP, (Tr ? L : L + StrLen(ES)) -SP) : ""
}

RemoveTrayIcon(hWnd, uID, nMsg = 0, hIcon = 0, nRemove = 2)
{
    NumPut(VarSetCapacity(ni,444,0), ni)
    NumPut(hWnd, ni, 4)
    NumPut(uID, ni, 8)
    NumPut(1|2|4, ni, 12)
    NumPut(nMsg, ni, 16)
    NumPut(hIcon, ni, 20)
    Return DllCall("shell32\Shell_NotifyIconA", "Uint", nRemove, "Uint", &ni)
}

36

Re: AHK: Самозакрытие при повторном запуске

Ну, если сильно заморачиваться, можно и так. Проверку ключей лучше делать, как тут, а предыдущий вариант не сработает, если скрипт будет скомпилирован.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

37

Re: AHK: Самозакрытие при повторном запуске

Не, народ, мне нужно что-то полегче для процессорной накачки. Иконки в трее можно опустить, их скорее не будет.
Не нравится, что в скриптах, где, скажем, выполняется быстрый хоткей постоянно будет крутиться функция с циклом поиска окон, почему я и хочу проверять по A_ExitReason или какому-то иному событию.

38

Re: AHK: Самозакрытие при повторном запуске

Flasher пишет:

постоянно будет крутиться функция с циклом поиска окон

А с чего ей постоянно крутиться? Поиск окон идёт только один раз при запуске.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

39

Re: AHK: Самозакрытие при повторном запуске

А как же Return?

40

Re: AHK: Самозакрытие при повторном запуске

Который? У меня всё вроде на месте. В цикле столько итераций, сколько есть окон с путём скрипта в заголовке.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

41 (изменено: Flasher, 2017-01-06 21:26:16)

Re: AHK: Самозакрытие при повторном запуске

Поспешил с выводами. Ладно, пойдёт.

Но с #SingleInstance, Force было бы лучше.

42

Re: AHK: Самозакрытие при повторном запуске

Если без WMI, то так можно:

#Persistent
#SingleInstance, force
OnExit(Func("Exit"))
Return

Exit(ExitReason)  {
   if ExitReason not in Single,Reload
      Return
   
   MyPID := DllCall("GetCurrentProcessId")
   VarSetCapacity(buff, buffSize := 4096, 0)
   DllCall("Psapi\EnumProcesses", Ptr, &buff, UInt, buffSize, UIntP, bytes)
   Loop % bytes//4  {
      PID := NumGet(buff, A_Index * 4, "UInt")
      if (MyPID != PID && InStr(GetCommandLine(PID), A_ScriptFullPath))
         Process, Close, % PID
   }
}

GetCommandLine(PID)  {
   static SYNCHRONIZE := 0x100000, STANDARD_RIGHTS_REQUIRED := 0xF0000, offsetSize := A_IsUnicode ? 2 : 1
        , PROCESS_ALL_ACCESS := STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xFFF, INFINITE := 0xFFFFFFFF
        
   hProc := DllCall("OpenProcess", UInt, PROCESS_ALL_ACCESS, Int, 0, UInt, PID, Ptr)
   if A_Is64bitOS  {
      DllCall("IsWow64Process", Ptr, hProc, UIntP, bool)
      if (bool && A_PtrSize = 8) || (!bool && A_PtrSize = 4)  {
         DllCall("CloseHandle", Ptr, hProc)
         ; MsgBox, Скрипт и целевой процесс разных битностей, функция не будет работать!
         Return
      }
   }
   hModule := DllCall("GetModuleHandle", "str", "Kernel32.dll", Ptr)
   pFunc := DllCall("GetProcAddress", Ptr, hModule, AStr, "GetCommandLine" . (A_IsUnicode ? "W" : "A"), Ptr)
   if !hThrd := DllCall("CreateRemoteThread", Ptr, hProc, Ptr, 0, Ptr, 0, Ptr, pFunc, Ptr, 0, UInt, 0, UInt, 0)  {
      DllCall("CloseHandle", Ptr, hProc)
      Return
   }
   DllCall("WaitForSingleObject", Ptr, hThrd, UInt, INFINITE)
   DllCall("GetExitCodeThread", Ptr, hThrd, UIntP, pPtr)
   DllCall("CloseHandle", Ptr, hThrd)

   VarSetCapacity(buff, 2048, 0)
   Loop  {
      offset := (A_Index - 1) * offsetSize
      DllCall("ReadProcessMemory", Ptr, hProc, Ptr, pPtr + offset, Ptr, &buff + offset, Ptr, offsetSize, Ptr, 0)
   } until !NumGet(&buff + offset, A_IsUnicode ? "UShort" : "UChar")

   DllCall("CloseHandle", Ptr, hProc)
   Return StrGet(&buff)
}

Или так:

#Persistent
#SingleInstance, force
OnExit(Func("Exit"))
Return

Exit(ExitReason)  {
   if ExitReason not in Single,Reload
      Return
   
   MyPID := DllCall("GetCurrentProcessId")
   VarSetCapacity(buff, buffSize := 4096, 0)
   DllCall("Psapi\EnumProcesses", Ptr, &buff, UInt, buffSize, UIntP, bytes)
   Loop % bytes//4  {
      PID := NumGet(buff, A_Index * 4, "UInt")
      if (MyPID != PID && InStr(GetCommandLine(PID), A_ScriptFullPath))
         Process, Close, % PID
   }
}

GetCommandLine(PID)  {
   static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10
   
   VarSetCapacity(PBI, 48)
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)

   (A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
   if (!A_Is64bitOS || IsWow64)
      PtrSize := 4, szPtr := "UInt", pPtr := "UIntP", offsetCMD := 0x44
   else
      PtrSize := 8, szPtr := "UInt64", pPtr := "UInt64P", offsetCMD := 0x78

   if (A_PtrSize < PtrSize)  {    ; скрипт 32, процесс 64
      QueryInformationProcess := "Ntdll\NtWow64QueryInformationProcess64"
      ReadProcessMemory := "Ntdll\NtWow64ReadVirtualMemory64"
      info := 0, szPBI := 48, offsetPEB := 8
   }
   else  {
      QueryInformationProcess := "Ntdll\NtQueryInformationProcess"
      ReadProcessMemory := "ReadProcessMemory"
      if (A_PtrSize > PtrSize)    ; скрипт 64, процесс 32
         info := 26, szPBI := 8, offsetPEB := 0
      else
         info := 0, szPBI := PtrSize * 6, OffsetPEB := PtrSize
   }
   DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, pPtr, bytes)
   pPEB := NumGet(&PBI + OffsetPEB, szPtr)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pPEB + PtrSize * 4, pPtr, pRUPP, szPtr, PtrSize, pPtr, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pRUPP + offsetCMD, pPtr, pCMD, szPtr, PtrSize, pPtr, bytes)

   VarSetCapacity(buff, 1024, 0)
   Loop  {
      offset := (A_Index - 1) * 2
      DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pCMD + offset, Ptr, &buff + offset, szPtr, 2, pPtr, bytes)
   } until !NumGet(&buff + offset, "UShort")

   DllCall("CloseHandle", Ptr, hProc)
   Return StrGet(&buff, "UTF-16")
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

43

Re: AHK: Самозакрытие при повторном запуске

На 32-бит оба не срабатывают.

44

Re: AHK: Самозакрытие при повторном запуске

У меня оба срабатывают. А какая ОС?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

45

Re: AHK: Самозакрытие при повторном запуске

Вот я про неё как раз.

46

Re: AHK: Самозакрытие при повторном запуске

Только что специально в XP x86 перезагрузился, попробовал — всё работает, так что не знаю, в чём проблема. Проверяй версию AHK.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

47

Re: AHK: Самозакрытие при повторном запуске

Win 7 SP1 Max x86, AutoHotkey(A|U)32.exe 1.1.24.04.
Процесс остаётся на месте. После второго вызова часто выскакивает окно:

[Window Title]
AutoHotkey Unicode 32-bit

[Main Instruction]
Прекращена работа программы "AutoHotkey Unicode 32-bit"

[Content]
Возникшая проблема привела к прекращению работы программы. Закройте эту программу.

[Закрыть программу]

48

Re: AHK: Самозакрытие при повторном запуске

Также.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

49 (изменено: teadrinker, 2017-01-08 23:32:43)

Re: AHK: Самозакрытие при повторном запуске

Подправленный второй вариант:

#Persistent
#SingleInstance, force
OnExit(Func("Exit"))
Return

Exit(ExitReason)  {
   if ExitReason not in Single,Reload
      Return
   
   MyPID := DllCall("GetCurrentProcessId")
   VarSetCapacity(buff, buffSize := 4096, 0)
   DllCall("Psapi\EnumProcesses", Ptr, &buff, UInt, buffSize, UIntP, bytes)
   Loop % bytes//4  {
      PID := NumGet(buff, A_Index * 4, "UInt")
      if (MyPID != PID && InStr(GetCommandLine(PID), A_ScriptFullPath))
         Process, Close, % PID
   }
}

GetCommandLine(PID)  {
   static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10
   
   VarSetCapacity(PBI, 48)
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)

   (A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
   if (!A_Is64bitOS || IsWow64)
      PtrSize := 4, szPtr := "UInt", pPtr := "UIntP", offsetCMD := 0x44
   else
      PtrSize := 8, szPtr := "Int64", pPtr := "Int64P", offsetCMD := 0x78

   if (A_PtrSize < PtrSize)  {    ; скрипт 32, процесс 64
      QueryInformationProcess := "Ntdll\NtWow64QueryInformationProcess64"
      ReadProcessMemory := "Ntdll\NtWow64ReadVirtualMemory64"
      info := 0, szPBI := 48, offsetPEB := 8
   }
   else  {
      QueryInformationProcess := "Ntdll\NtQueryInformationProcess"
      ReadProcessMemory := "ReadProcessMemory"
      if (A_PtrSize > PtrSize)    ; скрипт 64, процесс 32
         info := 26, szPBI := 8, offsetPEB := 0
      else
         info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
   }
   DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, pPtr, bytes)
   pPEB := NumGet(&PBI + offsetPEB, szPtr)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pPEB + PtrSize * 4, pPtr, pRUPP, szPtr, PtrSize, pPtr, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pRUPP + offsetCMD, pPtr, pCMD, szPtr, PtrSize, pPtr, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pRUPP + offsetCMD - PtrSize, UShortP, szCMD, szPtr, 2, pPtr, bytes)
   
   VarSetCapacity(buff, szCMD, 0)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pCMD, Ptr, &buff, szPtr, szCMD, pPtr, bytes)
   DllCall("CloseHandle", Ptr, hProc)
   Return StrGet(&buff, "UTF-16")
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

50

Re: AHK: Самозакрытие при повторном запуске

Ещё немного подправил размерность в связи с

Unsigned 64-bit integers produced by a function are not supported.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

51 (изменено: teadrinker, 2017-01-09 01:30:57)

Re: AHK: Самозакрытие при повторном запуске

И ещё немного, получше разобравшись в теме:

#Persistent
#SingleInstance, force
OnExit(Func("Exit"))
Return

Exit(ExitReason)  {
   if ExitReason not in Single,Reload
      Return
   
   MyPID := DllCall("GetCurrentProcessId")
   VarSetCapacity(buff, buffSize := 4096, 0)
   DllCall("Psapi\EnumProcesses", Ptr, &buff, UInt, buffSize, UIntP, bytes)
   Loop % bytes//4  {
      PID := NumGet(buff, A_Index * 4, "UInt")
      if (MyPID != PID && InStr(GetCommandLine(PID), A_ScriptFullPath))
         Process, Close, % PID
   }
}

GetCommandLine(PID)  {
   static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
   
   VarSetCapacity(PBI, 48)
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)

   (A_Is64bitOS && DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64))
   if (!A_Is64bitOS || IsWow64)
      PtrSize := 4, szPtr := "UInt", pPtr := "UIntP", offsetCMD := 0x44
   else
      PtrSize := 8, szPtr := "Int64", pPtr := "Int64P", offsetCMD := 0x78

   if (A_PtrSize < PtrSize)  {    ; скрипт 32, процесс 64
      QueryInformationProcess := "Ntdll\NtWow64QueryInformationProcess64"
      ReadProcessMemory := "Ntdll\NtWow64ReadVirtualMemory64"
      info := 0, szPBI := 48, offsetPEB := 8
   }
   else  {
      QueryInformationProcess := "Ntdll\NtQueryInformationProcess"
      ReadProcessMemory := "ReadProcessMemory"
      if (A_PtrSize > PtrSize)    ; скрипт 64, процесс 32
         info := 26, szPBI := 8, offsetPEB := 0
      else
         info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
   }
   if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS  {
      DllCall("CloseHandle", Ptr, hProc)
      Return
   }
   pPEB := NumGet(&PBI + offsetPEB, szPtr)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pPEB + PtrSize * 4, pPtr, pRUPP, szPtr, PtrSize, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pRUPP + offsetCMD, pPtr, pCMD, szPtr, PtrSize, UIntP, bytes)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pRUPP + offsetCMD - PtrSize, UShortP, szCMD, szPtr, 2, UIntP, bytes)
   
   VarSetCapacity(buff, szCMD, 0)
   DllCall(ReadProcessMemory, Ptr, hProc, szPtr, pCMD, Ptr, &buff, szPtr, szCMD, UIntP, bytes)
   DllCall("CloseHandle", Ptr, hProc)
   Return StrGet(&buff, "UTF-16")
}

Нужно понимать, что в таком виде функция EnumProcesses перечисляет не все процессы, а QueryInformationProcess выдаёт информацию только о процессах, запущенных от имени пользователя. Для получения командной строки AHK-скриптов это не важно, а для получения информации обо всех процессах нужно добавить

SeDebugPrivilege()

SeDebugPrivilege()  {
   static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
   
   hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
   DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
   
   VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
   NumPut(1, TOKEN_PRIVILEGES, 0, "UInt")
   DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
   NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
   NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
   DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
   
   DllCall("CloseHandle", Ptr, token)
   DllCall("CloseHandle", Ptr, hProc)
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder