Вопрос Запрет запуска двух копий инсталлятора.

Natrix

Новичок
Доброго времен суток.
Подскажите, пожалуйста, наподобие приведённого кода, или любое другое решение, но не для проверки стороннего процесса, а для запускаемого, что бы могла быть запущена только одна копия инсталлятора. В идеале бы без вариативности закрыть/нет/продолжить и пр., а запрет запуска по дефолту, без участия пользователя и доп. диалоговых окон.
Код:
[Code]
function KillTask(ExeFileName: AnsiString): Integer;
  external 'KillTask@files:ISTask.dll stdcall';

function RunTask(FileName: AnsiString; bFullpath: Boolean): Boolean;
  external 'RunTask@files:ISTask.dll stdcall';

function InitializeSetup(): Boolean;
begin
  Result := True;
  if RunTask('notepad.exe', False) then
  if MsgBox('Закрыть Блокнот?', mbConfirmation, MB_YESNO) = IDYES then
  KillTask('notepad.exe')
  else
  Result := False;
end;
 
Последнее редактирование:

Natrix

Новичок
Косой, спасибо.
А без AppId не обойтись?
Может, у кого найдётся максимально облегчённый код без модулей, параметров текста, диалоговых окон, сообщений, выбора и пр. только проверка и запрет запуска второй копии по умолчанию, без участия и информирования пользователя?
 
Последнее редактирование:

Косой

Новичок
В SEMAPHORE_UNIQUE_NAME вместо AppId по идее можно вписать что угодно, а модули можно "вырезать". Я просто привёл пример. Есть ещё пример через мютекс:
#define Name2 "OLOLO"

[Setup]
AppName={#Name2}
AppVersion={#Name2}
DefaultDirName={pf}\{#Name2}
AppMutex=1234567890ABC

[*Code]
var
Mutex: THandle;

function CreateMutex(lpMutexAttributes: Longint; bInitialOwner: BOOL; lpName: AnsiString): THandle; external 'CreateMutexA@kernel32.dll stdcall';
function ReleaseMutex(hMutex: THandle): BOOL; external 'ReleaseMutex@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';

procedure SMutex;
begin
Mutex:= CreateMutex(0, False, ExpandConstant('{#SetupSetting("AppMutex")}'));
end;

function InitializeSetup(): Boolean;
begin
Result:= not CheckForMutexes(ExpandConstant('{#SetupSetting("AppMutex")}'));
if not Result then
//MsgBox('Уже запущена одна версия инсталлятора. Одновременный запуск запрещён', mbError,mb_Ok);
CloseHandle(Mutex);
end;

procedure InitializeWizard();
begin
SMutex;
end;

procedure DeinitializeSetup;
begin
ReleaseMutex(Mutex);
CloseHandle(Mutex);
end;
но есть недостаток: при использовании мютекса, если инсталлятор запущен - деинсталлятор не запускается.
 

Natrix

Новичок
Косой, ещё раз спасибо, через мютекс по моему лаконичней.
_________________________________________________________________________________________________________________________________

Назрел ещё вопрос, может как-то можно отвязать taskkill от инсталлятора? Например, установщик через батник после проверки отсутствия исполнения этого процесса. Процесс найден завершить исполнение бат файл, не запуская инсталлятор... или что-то около того?
 
Последнее редактирование:

Хамик

Старожил
или что-то около того?
если правильно понял то как-то так
Код:
#define Name2 "OLOLO"

[Setup]
AppName={#Name2}
AppVersion={#Name2}
DefaultDirName={pf}\{#Name2}
AppMutex=1234567890ABC

[Code]
var
Mutex: THandle;

function CreateMutex(lpMutexAttributes: Longint; bInitialOwner: BOOL; lpName: AnsiString): THandle; external 'CreateMutexA@kernel32.dll stdcall';
function ReleaseMutex(hMutex: THandle): BOOL; external 'ReleaseMutex@kernel32.dll stdcall';
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';

function IsProcessRunning(FileName: String): Boolean;
var
  objSWbemLocator, objSWbemServices: Variant;
begin
  try
    objSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  except
    ShowExceptionMessage;
    Exit;
  end;
  objSWbemServices := objSWbemLocator.ConnectServer();
  objSWbemServices.Security_.ImpersonationLevel := 3;
  Result := (objSWbemServices.ExecQuery('SELECT * FROM Win32_Process WHERE Name="' + FileName + '"').Count > 0);
end;

procedure SMutex;
begin
Mutex:= CreateMutex(0, False, ExpandConstant('{#SetupSetting("AppMutex")}'));
end;

function InitializeSetup(): Boolean;
begin
Result:= not CheckForMutexes(ExpandConstant('{#SetupSetting("AppMutex")}'));
if not Result then
//MsgBox('Уже запущена одна версия инсталлятора. Одновременный запуск запрещён', mbError,mb_Ok);
CloseHandle(Mutex) else
result := not IsProcessRunning('calc.exe');
end;

procedure InitializeWizard();
begin
SMutex;
end;

procedure DeinitializeSetup;
begin
ReleaseMutex(Mutex);
CloseHandle(Mutex);
end;
 
Сверху