卸载失败,因为程序正在运行。如何在尝试删除之前让 Inno Setup 检查正在运行的进程?
Posted
技术标签:
【中文标题】卸载失败,因为程序正在运行。如何在尝试删除之前让 Inno Setup 检查正在运行的进程?【英文标题】:Uninstall fails because program is running. How do I make Inno Setup check for running process prior to attempting delete? 【发布时间】:2010-12-07 07:14:07 【问题描述】: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 文件之一
PSVince FindProcDLL或者阅读后自己做
How To Terminate an Application "Cleanly" in Win32
How To Enumerate Applications Using Win32 APIs(这个链接到德文版因为某种原因我找不到英文版的KB175030
或尝试 KB175030-DE 的谷歌翻译版本
KB175030 DE -> EN
【讨论】:
很棒的答案。非常彻底;谢谢!全局互斥锁选项花了 5 分钟才搞定!没有比这更好的了。 您对可以在另一台计算机的内存上打开的基于网络的文件有答案吗? 我可以在 Wayback Machine 上找到的最新英文版 KB 175030 是 2007 年 2 月:web.archive.org/web/20070216103757/http://support.microsoft.com/…。 在这个答案中检查正在运行的应用程序的更多选项:***.com/a/30852146/550712。【参考方案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。
【讨论】:
以上是关于卸载失败,因为程序正在运行。如何在尝试删除之前让 Inno Setup 检查正在运行的进程?的主要内容,如果未能解决你的问题,请参考以下文章
如何卸载.vsix Visual Studio Extensions?