论坛风格切换切换到宽版
  • 2187阅读
  • 3回复

64位系统istask插件检测安装或卸载程序关闭进程 [复制链接]

上一主题 下一主题
离线syl1130
 

发帖
81
金钱
610
威望
81
只看楼主 倒序阅读 0 发表于: 2016-09-26
Wanfu 版主,
能否分享一个64位系统inno setup 用istask插件检测安装或卸载程序时某程序进程正使用,自动关闭进程的程序再安装或卸载, gnatix帖子都看不了,还希望给一个代码范例,谢谢版主。
本帖提到的人: @wanfu
离线wanfu

发帖
2728
金钱
12110
威望
1211
只看该作者 1 发表于: 2016-09-26
其实,我对 INNO Setup 安装程序不是很精通,先将我封装 Radialix 3 所用的部分脚本贴出来(关键的部分),供你参考。
[Files]
Source: "Tmp\ISTask.dll"; DestDir: "{tmp}"; Flags: deleteafterinstall dontcopy
Source: "App\x86\rdl.exe"; DestDir: "{app}\x86"; Components: "main"; MinVersion: 4.1.2222,5.0;
Source: "App\x64\rdl.exe"; DestDir: "{app}\x64"; Components: "main"; Check: "IsWin64"; MinVersion: 4.1.2222,5.0;

[CustomMessages]
enu.AppIsRuning=%1 is running! %nDo you want Setup to automatically close the program.
enu.AppIsInstalled=You have an old %1 installation, %nDo you want to uninstall it?
chs.AppIsRuning=%1 正在运行!%n是否要让安装程序自动关闭该程序?
chs.AppIsInstalled=您已安装有旧版的 %1。%n要卸载它吗?
cht.AppIsRuning=%1 正在運行!%n是否要讓安裝程式自動關閉該程式?
cht.AppIsInstalled=您已安裝有舊版的 %1。%n要移除它嗎?

[Code]
function RunTask(FileName: string; bFullpath: Boolean): Boolean;
   external 'RunTask@files:ISTask.dll stdcall delayload';

function KillTask(ExeFileName: string): Integer;
   external 'KillTask@files:ISTask.dll stdcall delayload';

Function InitializeSetup(): boolean;
  var
    ResultCode: Integer;  
    ukey, name, uicmd: String;
  Begin
    Result := True;
    ukey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Radialix3_is1';
    RegQueryStringValue(HKEY_LOCAL_MACHINE, ukey, 'DisplayName', name);
    begin
    if name = '' then begin
       ukey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Radialix2_is1';
       RegQueryStringValue(HKEY_LOCAL_MACHINE, ukey, 'DisplayName', name);
       end;
    end;
    if name <> '' then begin    
       if RunTask('rdl.exe', false) then
          begin
          if MsgBox(FmtMessage(CustomMessage('AppIsRuning'),[name]), mbConfirmation, MB_YESNO) = IDYES then
             KillTask('rdl.exe')
          else
             Result := false;
          end
       else if Msgbox(FmtMessage(CustomMessage('AppIsInstalled'), [name]), mbConfirmation, MB_YESNO) = idYES then
          RegQueryStringValue(HKEY_LOCAL_MACHINE, ukey, 'UninstallString', uicmd);
          if uicmd <> '' then begin
             if Exec(RemoveQuotes(uicmd), '/silent', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
                Result := True
             else begin
                MsgBox(SysErrorMessage(ResultCode), mbError, mb_Ok);
                Result := false;
             end;
          end;
    end;
end;
附件: ISTask.rar (31 K) 下载次数:6
离线syl1130

发帖
81
金钱
610
威望
81
只看该作者 2 发表于: 2016-09-28
回 1楼(wanfu) 的帖子
代码:
----------------------


[Files]; 安装前判断进程,dll文件放在inno的安装目录中
Source: "compiler:ISTask.dll"; DestDir: "{tmp}"; Flags: deleteafterinstall dontcopy
Source: "compiler:ISTask.dll"; DestDir: "{app}";
Source: "compiler:psvince.dll"; DestDir: "{tmp}"; Flags: deleteafterinstall dontcopy
Source: "compiler:psvince.dll"; DestDir: "{app}";


[Code]
//安装前判断是否有进程正在运行
// PSVince控件无法检测到64位exe程序的进程,使用下面的函数可以解决。
function IsAppRunning(const FileName: string): Boolean;
var
  FWMIService: Variant;
  FSWbemLocator: 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;

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

function KillTask(ExeFileName: string): Integer;
   external 'KillTask@files:ISTask.dll stdcall delayload';
  
function InitializeSetup():boolean;
var
   IsRunning: boolean;
// 第二步,安装时判断客户端是否正在运行,注意:使用IsAppRunning函数(已在前面定义),
    //可以在32和64位系统下检测32和64位进程,但还是不能识别进程的版本,如果有多版本的话。
    begin
      Result:= true;//安装程序继续
       if not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\McNeel\Rhinoceros\5.0x64') then
       begin
         MsgBox('该系统未检测软件程序,请先行安装软件程序!', mbInformation, MB_OK);
         Result := False;
       end;
      IsRunning:= IsAppRunning('rhino.exe');
      while IsRunning do
         begin
           if MsgBox('安装检测到 软件 正在运行!' #13#13 '先关闭所有软件之后,再单击“确定”继续安装,否则按“取消”退出安装!', mbConfirmation, MB_OKCANCEL) = IDOK then
             begin
             IsRunning:= IsAppRunning('rhino.exe');
             Result:= true;
             end else begin
             IsRunning:= false;
             Result:= false;//安装程序退出
             Exit;
             end;
         end;
    end;
    


    begin
      Result:= true;//安装程序继续
         if RunTask('rhino.exe', false) then
         begin
           if MsgBox('安装程序检测到软件正在运行!'#13''#13'点击 "是" 按钮将关闭进程再继续安装;'#13''#13'点击"否" 按钮将退出安装!', mbConfirmation, MB_YESNO) = IDYES then
              KillTask('rhino.exe');
              Result:= true;
              end else begin
              Result:= false;//安装程序退出
              Exit;
         end;
    end;


// 卸载时判断xxx是否正在运行

function InitializeUninstall(): Boolean;
var
  IsRunning: boolean;
begin
  Result :=true;  //卸载程序继续
  IsRunning:= IsAppRunning('rhino.exe');
  while IsRunning do
  begin
    if Msgbox('卸载检测到 软件 正在运行。'  #13#13 '先关闭进程然后单击“确定”继续卸载,否则按“取消”退出卸载!', mbConfirmation, MB_OKCANCEL) = IDOK then
    begin
      IsRunning:= IsAppRunning('rhino.exe');
      Result :=true; //卸载程序继续
    end else begin
      IsRunning:= false;
      Result :=false; //卸载程序退出
      Exit;
    end;
  end;
  UnloadDLL(ExpandConstant('{app}\psvince.dll'));
end;
--------------------------------------------

运行出错,好奇怪 弄了很多次都是这样子




本帖提到的人: @wanfu
离线wanfu

发帖
2728
金钱
12110
威望
1211
只看该作者 3 发表于: 2016-09-28
自己要好好检查一下代码呀。低级错误。

function InitializeSetup():boolean;
var
   IsRunning: boolean;
// 第二步,安装时判断客户端是否正在运行,注意:使用IsAppRunning函数(已在前面定义),
    //可以在32和64位系统下检测32和64位进程,但还是不能识别进程的版本,如果有多版本的话。
    begin
      Result:= true;//安装程序继续
       if not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\McNeel\Rhinoceros\5.0x64') then
       begin
         MsgBox('该系统未检测软件程序,请先行安装软件程序!', mbInformation, MB_OK);
         Result := False;
       end;
      IsRunning:= IsAppRunning('rhino.exe');
      while IsRunning do
         begin
           if MsgBox('安装检测到 软件 正在运行!' #13#13 '先关闭所有软件之后,再单击“确定”继续安装,否则按“取消”退出安装!', mbConfirmation, MB_OKCANCEL) = IDOK then
             begin
             IsRunning:= IsAppRunning('rhino.exe');
             Result:= true;
             end else begin
             IsRunning:= false;
             Result:= false;//安装程序退出
             Exit;
             end;
         end;
end; // 这里的 end 表示函数已经结束,应该去掉。
  
   begin
      Result:= true;//安装程序继续
         if RunTask('rhino.exe', false) then
         begin
           if MsgBox('安装程序检测到软件正在运行!'#13''#13'点击 "是" 按钮将关闭进程再继续安装;'#13''#13'点击"否" 按钮将退出安装!', mbConfirmation, MB_YESNO) = IDYES then
              KillTask('rhino.exe');
              Result:= true;
              end else begin
              Result:= false;//安装程序退出
              Exit;
         end;
    end;
end; // 这里加一个,表示函数结束。