#nsis
#nsis
Вопрос:
Я работаю над установщиком NSIS и пытаюсь проверить, запущено ли определенное приложение перед удалением. Итак, я использую kernel32::CreateMutexA
call. Вот фрагмент:
System::Call 'kernel32::CreateMutexA(i 0, i 0, t "cmd.exe") i .r1 ?e'
Pop $R0
StrCmp $R0 0 3
MessageBox MB_USERICON "The application is already running."
Abort
Я поместил это в un.onInit
. Проблема в том, что процесс ( cmd.exe
здесь) никогда не обнаруживается.
Я что-то пропустил?
Tx.
Комментарии:
1. Любое количество экземпляров cmd.exe может быть запущен в системе по нескольким причинам
2. На самом деле,
cmd.exe
это был просто пример.
Ответ №1:
Я нашел простое решение; используя плагин FindProcDLL.
Итак:
FindProcDLL::FindProc "cmd.exe"
Pop $R0
StrCmp $R0 0 3
MessageBox MB_USERICON "The application is already running." IDOK
Abort
PS FindProcDLL.dll
необходимо скопировать в /Plugins
.
Комментарии:
1. Это не работает с NSIS 2.46, как также описано на странице.
Ответ №2:
Все, что вы делаете, это создаете мьютекс с глобальным именем "cmd.exe"
. Из статьи MSDN для CreateMutex
:
Если lpName совпадает с именем существующего события, семафора, ожидаемого таймера, задания или объекта сопоставления файлов, функция завершается с ошибкой, и функция GetLastError возвращает ERROR_INVALID_HANDLE. Это происходит потому, что эти объекты используют одно и то же пространство имен.
Таким образом, если cmd.exe
не будет создан дескриптор для одного из этих типов объектов с именем "cmd.exe"
, этот вызов просто создаст новый мьютекс с этим именем и вернет вам дескриптор (без ошибок).
Ответ №3:
Вероятно, вы используете неправильную функцию Win32 API. Ваш CreateMutex пытается создать именованный мьютекс «something.exe «. Если экземпляр с таким именем отсутствует, он будет выполнен успешно, поэтому, если процесс, который вы пытаетесь проверить, не создает мьютекс с этим именем, вы не получите желаемого результата.
Вероятно, вы хотите перечислить все запущенные процессы и посмотреть, есть ли тот, который вам нужен. Вы можете сделать это с помощью ToolHelp32 из Win32 API — смотрите пример здесь. Я не знаю, насколько легко будет преобразовать его в «чистый» NSIS, поэтому вы можете захотеть написать плагин DLL или проверить, есть ли существующее решение, распространяемое в сообществе NSIS.
Комментарии:
1. Tx Idan. Это странно. Когда я пытаюсь с помощью самого установщика (например,
my_setup.exe
), это работает! Но не с другим процессом.2. что работает? из вашего примера кода окно сообщения появится, если CreateMutexA был выполнен успешно, то есть нет именованного мьютекса с указанным вами именем. независимо от того, какое поведение вы получаете, это неправильное решение проблемы, которую вы пытаетесь решить.
3.
CreateMutexA()
завершается успешно с помощью самого установщика. Итак, на самом деле это правильное решение для определения того, запущен ли экземпляр программы установки. Но, как вы сказали, не подходит для любого другого процесса.4. Да, использование именованного мьютекса для разрешения доступа к одному экземпляру программы установки является правильным решением. Просто не было ясно, что это было вашим намерением в первую очередь.
Ответ №4:
Для такого рода задач я использовал плагины KillProcess или Find-Close-Terminate для NSIS — смотрите Здесь
Документация довольно проста, надеюсь, это делает то, что вам нужно — с довольно минимальными накладными расходами.