inno setup 安装前判断程序是否运行,以及停止相应程序
https://www.cnblogs.com/w-pound/p/13158219.html
这份代码在卸载的时候出现了问题........
源代码的bug在于如果卸载了点击否!那么会删除.dll 下次还要卸载的时候....就不行了
所以我们需要做的事情就是......
先上截图:
改下
要引入psvince.dll这个dll,放在inno setup的安装目录下(与其他dll相同目录),代码如下:
[Files]
Source: compiler:psvince.dll;Flags: dontcopy noencryption
[code] // function IsModuleLoaded to call at install time // added also setuponly flag function IsModuleLoaded(modulename: String ): Boolean; external 'IsModuleLoaded@files:psvince.dll stdcall setuponly'; //;判断进程是否存在 function IsAppRunning(const FileName : string): Boolean; var FSWbemLocator: Variant; FWMIService : Variant; FWbemObjectSet: Variant; begin Result := false; 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); FWbemObjectSet := Unassigned; FWMIService := Unassigned; FSWbemLocator := Unassigned; except if (IsModuleLoaded(FileName)) then begin Result := false; end else begin Result := true; end end; end; //;通过名称终结进程 procedure TaskKillProcessByName(AppName: String); var WbemLocator : Variant; WMIService : Variant; WbemObjectSet: Variant; WbemObject : Variant; begin; WbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2'); WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"'); if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then begin WbemObject := WbemObjectSet.ItemIndex(0); if not VarIsNull(WbemObject) then begin WbemObject.Terminate(); WbemObject := Unassigned; end; end; end; //;安装的时候判断进程是否存在,存在则先提示是否结束进程 function InitializeSetup(): Boolean; begin Result := true; if IsAppRunning('{#MyAppExeName}') then begin if MsgBox('安装程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续安装;'#13''#13'单击“否”按钮退出安装!', mbConfirmation, MB_YESNO) = IDYES then begin TaskKillProcessByName('{#MyAppExeName}'); TaskKillProcessByName('{#MyAppExeName}'); Result:= true; end else Result:= false; end; end; //;卸载的时候判断进程是否存在,存在则先提示是否结束进程 function InitializeUninstall(): Boolean; begin Result:= true; if IsAppRunning('{#MyAppExeName}') then begin if MsgBox('卸载程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续卸载;'#13''#13'单击“否”按钮退出卸载!', mbConfirmation, MB_YESNO) = IDYES then begin TaskKillProcessByName('{#MyAppExeName}'); TaskKillProcessByName('{#MyAppExeName}'); Result:= true; end else Result:= false; end; end;
完整代码:
; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "My Program" #define MyAppVersion "1.5" #define MyAppPublisher "My Company, Inc." #define MyAppURL "https://www.example.com/" #define MyAppExeName "MyProg.exe" #define MyAppAssocName MyAppName + " File" #define MyAppAssocExt ".myp" #define MyAppAssocKey StringChange(MyAppAssocName, " ", "") + MyAppAssocExt [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{723A4833-89BA-485C-B07C-9D7CEEB88F7C} AppName={#MyAppName} AppVersion={#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={autopf}\{#MyAppName} ChangesAssociations=yes DisableProgramGroupPage=yes ; Uncomment the following line to run in non administrative install mode (install for current user only.) ;PrivilegesRequired=lowest OutputDir=C:\Users\Administrator\Desktop\2222222 OutputBaseFilename=mysetup Compression=lzma SolidCompression=yes WizardStyle=modern [Languages] Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] Source: "C:\Program Files (x86)\Inno Setup 6\Examples\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion Source: "C:\Program Files (x86)\Inno Setup 6\Examples\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files Source: compiler:psvince.dll;Flags: dontcopy noencryption [Registry] Root: HKA; Subkey: "Software\Classes\{#MyAppAssocExt}\OpenWithProgids"; ValueType: string; ValueName: "{#MyAppAssocKey}"; ValueData: ""; Flags: uninsdeletevalue Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}"; ValueType: string; ValueName: ""; ValueData: "{#MyAppAssocName}"; Flags: uninsdeletekey Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName},0" Root: HKA; Subkey: "Software\Classes\{#MyAppAssocKey}\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""%1""" Root: HKA; Subkey: "Software\Classes\Applications\{#MyAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".myp"; ValueData: "" [Icons] Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent [code] // function IsModuleLoaded to call at install time // added also setuponly flag function IsModuleLoaded(modulename: String ): Boolean; external 'IsModuleLoaded@files:psvince.dll stdcall setuponly'; //;判断进程是否存在 function IsAppRunning(const FileName : string): Boolean; var FSWbemLocator: Variant; FWMIService : Variant; FWbemObjectSet: Variant; begin Result := false; 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); FWbemObjectSet := Unassigned; FWMIService := Unassigned; FSWbemLocator := Unassigned; except if (IsModuleLoaded(FileName)) then begin Result := false; end else begin Result := true; end end; end; //;通过名称终结进程 procedure TaskKillProcessByName(AppName: String); var WbemLocator : Variant; WMIService : Variant; WbemObjectSet: Variant; WbemObject : Variant; begin; WbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); WMIService := WbemLocator.ConnectServer('localhost', 'root\CIMV2'); WbemObjectSet := WMIService.ExecQuery('SELECT * FROM Win32_Process Where Name="' + AppName + '"'); if not VarIsNull(WbemObjectSet) and (WbemObjectSet.Count > 0) then begin WbemObject := WbemObjectSet.ItemIndex(0); if not VarIsNull(WbemObject) then begin WbemObject.Terminate(); WbemObject := Unassigned; end; end; end; //;安装的时候判断进程是否存在,存在则先提示是否结束进程 function InitializeSetup(): Boolean; begin Result := true; if IsAppRunning('{#MyAppExeName}') then begin if MsgBox('安装程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续安装;'#13''#13'单击“否”按钮退出安装!', mbConfirmation, MB_YESNO) = IDYES then begin TaskKillProcessByName('{#MyAppExeName}'); TaskKillProcessByName('{#MyAppExeName}'); Result:= true; end else Result:= false; end; end; //;卸载的时候判断进程是否存在,存在则先提示是否结束进程 function InitializeUninstall(): Boolean; begin Result:= true; if IsAppRunning('{#MyAppExeName}') then begin if MsgBox('卸载程序检测到 {#MyAppName} 正在运行!'#13''#13'单击“是”按钮关闭程序并继续卸载;'#13''#13'单击“否”按钮退出卸载!', mbConfirmation, MB_YESNO) = IDYES then begin TaskKillProcessByName('{#MyAppExeName}'); TaskKillProcessByName('{#MyAppExeName}'); Result:= true; end else Result:= false; end; end;