【问题标题】:Uninstall fails because program is running. How do I make Inno Setup check for running process prior to attempting delete?卸载失败,因为程序正在运行。如何在尝试删除之前让 Inno Setup 检查正在运行的进程?
【发布时间】:2010-12-07 07:14:07
【问题描述】:

Inno Setup 在卸载过程中无法删除组件,因为我的程序仍在运行并且无法删除可执行文件。在允许卸载继续之前,我如何让它检查它是否正在运行?

【问题讨论】:

    标签: inno-setup


    【解决方案1】:

    我们使用了上述以外的其他方式。因为这是一个卸载,我们可以杀死应用程序并卸载它。 最简单的方法,当你不能使用AppMutex时:(与Really killing a process in Windows相关)

    [UninstallRun]
    Filename: "{cmd}"; Parameters: "/C ""taskkill /im <precessname>.exe /f /t"
    

    希望有人能帮忙。这个我找了很久。

    【讨论】:

    • taskkill 是否会杀死同一进程的多个正在运行的实例?
    • 用notepad.exe试了一下,效果很好。它会在没有反馈的情况下终止应用程序。
    • 谢谢!是的,除非您以低于提升进程的权限运行设置,否则它会杀死所有实例。 [无论如何+1 :)]
    • 似乎要终止进程,但卸载程序仍将文件视为已锁定并不会删除它们。
    • 最佳解决方案 imo.
    【解决方案2】:

    检查这些

    Inno Setup: Detect instances running in any user session with AppMutex

    Inno Setup: Is application running?

    Inno Setup: Detect if an application is running

    有几种方法。如果你的程序定义了一个互斥体使用

    [Setup]
    AppMutex=MyMutexName
    

    Code 部分中的指定互斥锁

    function CheckForMutexes (Mutexes: String): Boolean;
    

    你也可以使用

    function FindWindowByClassName (const ClassName: String): Longint; 
    

    通过类名获取窗口句柄并向其发送消息。

    或者通过名字来获取它

    function FindWindowByWindowName (const WindowName: String): Longint;
    

    或者您为这个特定用例使用几个 DLL 文件之一

    或者阅读后自己做

    How To Terminate an Application "Cleanly" in Win32

    How To Enumerate Applications Using Win32 APIs(这个链接到德文版因为某种原因我找不到英文版的KB175030

    或尝试 KB175030-DE 的谷歌翻译版本

    KB175030 DE -> EN

    【讨论】:

    【解决方案3】:

    试试这个解决方案!我在关闭应用程序时遇到了其他解决方案的问题,但 Inno Setup 仍然认为已安装的文件已被锁定。

    记得定义你的常量:

    #define MyAppName "AppName"
    #define MyAppExeName "AppName.exe"
    
    [Code]
    function InitializeUninstall(): Boolean;
      var ErrorCode: Integer;
    begin
      ShellExec('open','taskkill.exe','/f /im {#MyAppExeName}','',SW_HIDE,ewNoWait,ErrorCode);
      ShellExec('open','tskill.exe',' {#MyAppName}','',SW_HIDE,ewNoWait,ErrorCode);
      result := True;
    end;
    

    original source of this solution 的主要支持。

    【讨论】:

    • 这很好,我改变的一件事是使用不同的过程而不是“function InitializeUninstall(): Boolean;”由于即使用户取消卸载过程,此功能也会终止应用程序,而“procedure InitializeUninstallProgressForm;”只有当他确认卸载时才会运行。
    【解决方案4】:

    当应用程序运行时,使用AppMutex directive 阻止卸载程序继续进行。

    [Setup]
    AppMutex=MyProgMutex
    

    应用程序必须创建指令指定的互斥锁。有关示例,请参阅链接的 AppMutex 指令文档。


    如果您想让卸载程序杀死应用程序,当它仍在运行时,请改用以下代码:

    function InitializeUninstall(): Boolean;
    var
      ErrorCode: Integer;
    begin
      if CheckForMutexes('MyProgMutex') and
         (MsgBox('Application is running, do you want to close it?',
                 mbConfirmation, MB_OKCANCEL) = IDOK) then
      begin
        Exec('taskkill.exe', '/f /im MyProg.exe', '', SW_HIDE, 
             ewWaitUntilTerminated, ErrorCode);
      end;
    
      Result := True;
    end;
    

    与上面的AppMutex 指令一样,应用程序必须创建CheckForMutexes 调用中指定的互斥锁。


    请注意,对于安装程序,您不必对此进行编码。安装程序内置了重启管理器。
    Kill process before (re)install using "taskkill /f /im" in Inno Setup

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2016-11-02
      • 2011-04-21
      • 2018-05-04
      • 1970-01-01
      • 2011-03-31
      相关资源
      最近更新 更多