Sådan kontrolleres med inno-setup, hvis en proces kører på en Windows 2008 r2 64bit?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har læst følgende indlæg. Min kode ser ud til det samme, men fungerer ikke:


Inno Setup Kontrol af køringsproces


Jeg kopierede eksemplet fra http://www.vincenzo.net/isxkb/index.php?title=PSVince[10]


Men eksemplet fungerer heller ikke, selvom jeg ændrer koden som denne:


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


Koden returnerer altid falsk (programmet kører ikke, selvom det kører).
Testet i Windows 2008 R2 og Windows 7


Faktisk vil jeg kontrollere, om tomcat5.exe kører eller ej. Så jeg tror, ​​jeg kan ikke arbejde med en AppMutex.


Nogle ideer?


UPDATE
Jeg har set https://code.google.com/p/psvince/source/detail?r=5
Men jeg kan ikke finde nogen fakta om kompatibilitet af den DLL. [11]


CODE
Komplet udstedelse:


[Setup]
AppName=PSVince
AppVerName=PSVince 1.0
DisableProgramGroupPage=true
DisableStartupPrompt=true
OutputDir=.
OutputBaseFilename=testpsvince
Uninstallable=false
DisableDirPage=true
DefaultDirName={pf}PSVince

[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;

Bedste reference


Desværre kan psvince.dll ikke forespørge om 64 bit kørende processer baseret på min observation, og da jeg ikke er dens udvikler, ved jeg ikke hvordan man løser det til arbejde på Windows x64.


Min løsning er at bruge et hjemmelavet kommandolinjeværktøj, processviewer.exe,


http://github.com/lextm/processviewer[12]


Dette er blevet testet på Windows 7 x64 i Touch Mouse Mate [13]


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

Andre referencer 1


Du kan bruge WMI og Win32\_Process. [15]


Prøv at tilføje denne funktion til dit inno setup script.


function IsAppRunning(const FileName : string): Boolean;
var
    FSWbemLocator: Variant;
    FWMIService   : Variant;
    FWbemObjectSet: Variant;
begin
    Result := false;
    FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
    FWMIService := FSWbemLocator.ConnectServer('', 'rootCIMV2', '', '');
    FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32\_Process Where Name="\%s"',[FileName]));
    Result := (FWbemObjectSet.Count > 0);
    FWbemObjectSet := Unassigned;
    FWMIService := Unassigned;
    FSWbemLocator := Unassigned;
end;

Andre referencer 2


Jeg har ikke nok rep point til at tilføje en kommentar til RRUZs fremragende svar, så jeg vil bare tilføje dette her.
Sørg for at få vist undtagelser, ellers vil installationsprogrammet mislykkes for brugere, som ikke kan få adgang til tjenesten.


try
      FSWbemLocator := CreateOleObject('WBEMScripting.SWBEMLocator');
      FWMIService := FSWbemLocator.ConnectServer('', 'rootCIMV2', '', '');
      FWbemObjectSet := FWMIService.ExecQuery(Format('SELECT Name FROM Win32\_Process Where Name="\%s"',[FileName]));
      Result := (FWbemObjectSet.Count > 0);
except
end;

Andre referencer 3


Der er en endnu enklere løsning på dette, idet du bruger koden foreslået af RRUZ, afhænger af, at du kender installationsvej, som hvis du kører, når installationsprogrammet initialiseres, ved du ikke dette.


Den bedste løsning er at bruge FindWindowByClassName. Det har en lille forudsætning, at du har en hovedformular, som altid er åben, men du kan altid køre flere checks, hvis du har en række forskellige former, der kan være åbne. Det siger sig selv også, at du skal gøre klassenavnet som unik som muligt!


Eksempel funktion:


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


De # forkompilere referencer er defineret tidligere op installations scriptet ...


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


Så i kodesektionen kalder du det som følger:


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;


Hvis du har brug for noget mere komplekst end dette, så skal du kigge på mutexes, men skønheden med ovenstående kode er, at det er simpelt, hurtigt og så længe du har rimeligt unikke klassenavne, så godt som noget andet.


(Selvom det er sikkert, at hvis du kører på et multifunktionssystem, vil det nok ikke vinde vinduet hvis det er i en anden brugers session. Men som sagt, for de fleste simple situationer ville det være fint. )

Andre referencer 4


En simpel løsning kan være at forsøge at slette exe-filen. Jeg går ud fra, at du vil erstatte eller afinstallere det alligevel. Hvis filen eksisterer og sletter den fejler, så løber den sikkert.