Как проверить с помощью Inno Setup, запущен ли процесс на Windows 2008 R2 64bit? - PullRequest
13 голосов
/ 30 марта 2012

Я прочитал следующий пост.Мой код выглядит точно так же, но не работает:
Inno Setup Проверка работающего процесса

Я скопировал пример из http://www.vincenzo.net/isxkb/index.php?title=PSVince

Но примертоже не работает, даже если я изменю код следующим образом:

[Code]
function IsModuleLoaded(modulename: AnsiString):  Boolean;
external 'IsModuleLoaded@files:psvince.dll stdcall';

Код всегда возвращает false (программа не работает, даже она работает).Протестировано в Windows 2008 R2 и Windows 7.

На самом деле я хочу проверить, работает tomcat5.exe или нет.Поэтому я думаю, что не могу работать с AppMutex.

Я также видел https://code.google.com/p/psvince/source/detail?r=5
Но я не могу найти какие-либо факты о совместимости этой DLL.

Полный код:

[Files]
Source: psvince.dll; Flags: dontcopy

[Code]
function IsModuleLoaded(modulename: AnsiString ):  Boolean;
external 'IsModuleLoaded@files:psvince.dll stdcall';

function InitializeSetup(): Boolean;
begin
  if(IsModuleLoaded( 'notepad.exe' )) then
    begin
      MsgBox('Running', mbInformation, MB_OK);
      Result := false;
    end
  else
    begin
      MsgBox('Not running', mbInformation, MB_OK);
      Result := true;
    end
end;

Ответы [ 5 ]

45 голосов
/ 31 марта 2012

Вы можете использовать WMI и Win32_Process.

Попробуйте добавить эту функцию в скрипт Inno Setup.

function IsAppRunning(const FileName : string): Boolean;
var
    FSWbemLocator: Variant;
    FWMIService   : Variant;
    FWbemObjectSet: Variant;
begin
    Result := false;
    FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
    FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
    FWbemObjectSet :=
      FWMIService.ExecQuery(
        Format('SELECT Name FROM Win32_Process Where Name="%s"', [FileName]));
    Result := (FWbemObjectSet.Count > 0);
    FWbemObjectSet := Unassigned;
    FWMIService := Unassigned;
    FSWbemLocator := Unassigned;
end;
7 голосов
/ 27 августа 2014

У меня недостаточно точек повторения, чтобы добавить комментарий к отличному ответу RRUZ, поэтому я просто добавлю это здесь. Убедитесь, что вы перехватываете исключения, иначе программа установки не будет работать для пользователей, которые не могут получить доступ к службе.

try
      FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
      FWMIService := FSWbemLocator.ConnectServer('', 'root\CIMV2', '', '');
      FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32_Process Where Name="%s"',[FileName]));
      Result := (FWbemObjectSet.Count > 0);
except
end;
1 голос
/ 21 мая 2014

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

1 голос
/ 06 сентября 2013

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

Лучшее решение - использовать FindWindowByClassName.У него есть небольшое предварительное условие, что у вас есть основная форма, которая всегда открыта, но вы всегда можете запустить несколько проверок, если у вас есть множество форм, которые могут быть открыты.Само собой разумеется, что вам нужно сделать имя класса как можно более уникальным!

Пример функции:

function IsAppRunning(): Boolean;
begin                                                                
  Result := (FindWindowByClassName( '{#AppWndClassName}') <> 0) or (FindWindowByClassName( '{#AltAppWndClassName}') <> 0);
end;

# Прекомпиляция ссылок определена ранее в сценарии установки ...

#define AppWndClassName "TMySplashScreen"
#define AltAppWndClassName "TMyMainForm"

Затем в разделе кода вы называете это следующим образом:

function InitializeUninstall(): Boolean;
begin
  // check if application is running
  if IsAppRunning() then
  begin
    MsgBox( 'An Instance of MyFantasticApp is already running. - Please close it and run the uninstall again.', mbError, MB_OK );
    Result := false;
  end
  else 
    Result := true;
End;

Если вам нужно что-то более сложное, чем это, то вам нужно смотреть на мьютексы, но красота сПриведенный выше код состоит в том, что он простой, быстрый и при условии, что у вас достаточно уникальные имена классов, как и все остальное.

(Хотя по общему признанию, если вы работаете в многопользовательской системе, это, вероятно, победитЯ не могу найти окно, если оно находится в сеансе другого пользователя. Но, как я уже сказал, для большинства простых ситуаций это было бы хорошо.)

0 голосов
/ 30 марта 2012

К сожалению, psvince.dll не может запрашивать 64-битные запущенные процессы на основании моих наблюдений, и, поскольку я не являюсь его разработчиком, я не знаю, как это исправить для работы в Windows x64.

Мой обходной путь - использовать домашнюю утилиту командной строки processviewer.exe,

http://github.com/lextm/processviewer

Это было проверено на Windows 7 x64 в Touch Mouse Mate

http://www.lextm.com/2012/03/new-inno-setup-installer-script-samples-version-compare-running-processes/

...