1

Тема: AHK: #SingleInstance Force как определить был ли запущен скрипт

Есть ли способ узнать заменял ли новый процесс скрипта старый, при его запуске с директивой #SingleInstance Force, для не скомпилированного скрипта.
Код ниже работает только для скомпилированной версии, и я не уверен, что он будет всегда корректно срабатывать.

#NoEnv
#Persistent
#NoTrayIcon
#SingleInstance Off
Gui, Show, w250 h0 ,Gui для наглядности

Process, priority, , Realtime
Pid := ErrorLevel

Process, Wait, test.exe, 0.1
If ErrorLevel != %Pid%
	{
	Process, Close, % ErrorLevel
	MsgBox Старый процесс закрыт как "#SingleInstance Force"
	}
Return

GuiClose:
ExitApp

2

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

Возможно, можно мониторить сообщение закрытия (надо погуглить), и записывать в файл по OnExit, затем считывать на старте этот файл... возможно это бред.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

3

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

OnExit с A_ExitReason рассматривал как вариант, но не хочеться создавать файлы при работе срипта.

4 (изменено: Alectric, 2015-10-30 16:36:02)

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

Попытался сделать через посыл сообщения, но поток "нового" скрипта не стартует пока не завершится "старый". Так что только через файл.

#SingleInstance,Force
OnExit,EXIT

iniread,ExitReason,%A_scriptdir%\ExitReason,A_ExitReason,A_ExitReason
filedelete,%A_scriptdir%\ExitReason
tooltip,% ExitReason
return

f1::
return


exit:
IniWrite,%A_ExitReason%,%A_scriptdir%\ExitReason,A_ExitReason,A_ExitReason
exitapp



Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

5

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

На форуме нашёл похожую проблему и её решение от: creature.ws
На подобии получилось следующее:

#SingleInstance Off
Gui, Show, w250 h0 ,Gui для наглядности
Process, priority, , Realtime
Pid1 := ErrorLevel

Loop
{
for Process in ComObjGet("winmgmts:").InstancesOf("Win32_Process")
if (InStr(Process.CommandLine,A_ScriptName) && Process.ProcessId!=%Pid1%)
{
   ProcessId := Process.ProcessId
   SearchProcess := Process.CommandLine
      If ProcessId-Pid1=0
      {
         Goto ExitLoop
      }
      Else
      {
         OldPar := "1"
         RegExMatch(SearchProcess, A_ScriptName "(.*)", OldPar)
         StringReplace,OldPar,OldPar,%A_ScriptName%,,All
         Process.Terminate
      }
}
}
ExitLoop:
If OldPar
MsgBox Скрипт перезапущен `n %OldPar%
Else
MsgBox Скрипт запущен в первые
Return

Escape::
GuiClose:
ExitApp

Не понимаю как правильно написать,

if (InStr(Process.CommandLine,A_ScriptName) && Process.ProcessId!=%Pid1% && Process.Caption=AutoHotkey.exe)

что-бы реагировало только на скрипты, вместо того, что есть:

if (InStr(Process.CommandLine,A_ScriptName) && Process.ProcessId!=%Pid1%)

которая закрывает всё содержащее имя скрипта(блокноты итп)

6 (изменено: Alectric, 2015-11-06 13:53:31)

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

Ссылка.

ProcessName := "AutoHotkey.exe"
Processes := ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process Where Name = '" ProcessName "'")

Как можно пользоваться поиском.

Win 10 x64
AHK v1.1.33.02
                       Справка тебе в помощь.

7

Re: AHK: #SingleInstance Force как определить был ли запущен скрипт

#SingleInstance Off
Gui, Show, w250 h0 ,Gui для наглядности
Process, priority, , Realtime
Pid1 := ErrorLevel

Loop
{
ProcessName := "AutoHotkey.exe"
for Process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process Where Name = '" ProcessName "'")
if (InStr(Process.CommandLine,A_ScriptName) && Process.ProcessId!=%Pid1%)
{
    ProcessId := Process.ProcessId
    SearchProcess := Process.CommandLine
        If ProcessId-Pid1=0
        {
            Goto ExitLoop
        }
        Else
        {
            OldPar := "1"
            RegExMatch(SearchProcess, A_ScriptName "(.*)", OldPar)
            StringReplace,OldPar,OldPar,%A_ScriptName%,,All
            Process.Terminate
        }
}
}
ExitLoop:
If OldPar
MsgBox Скрипт перезапущен `n %OldPar%
Else
MsgBox Скрипт запущен в первые
Return

Escape::
GuiClose:
ExitApp

Спасибо, теперь работает как задумано.