安装更新之前关闭正在运行的程序版本 (Inno Setup)
这应该很简单,我需要在安装程序启动时停止运行任何以前版本的程序。
大多数人建议创建一个执行此操作的 exe 并在 Inno Setup 启动之前调用它。我使用 AutoIt 创建了一个 exe,它会杀死程序的所有进程。问题是我不知道如何让 Inno Setup 在安装任何东西之前调用它。
如何在安装文件之前调用可执行文件?
或者,如果我可以检测程序是否正在运行并告诉用户关闭它,那也可以。
This should be simple, I need to stop any previous version of my program from running when the installer starts.
Most people suggested making an exe
which does this and calling it before Inno Setup starts. I created an exe
using AutoIt which kills all processes of my program. The problem is I don't know how to get Inno Setup to call it before it installs anything.
How do I call an executable before installing files?
Alternatively, if I can just detect if a program is running and tell the user to close it, that would work too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
如果应用程序有互斥锁,您可以在 Inno Setup 安装程序中添加一个
AppMutex
值,它将显示一条消息,告诉用户停止该程序。您可以通过使用 SysInternals Process Explorer 并选择程序/进程并查看下部窗格中的句柄 (CTRL-H) 来找到互斥体(如果有的话)。以下是知识库文章的链接,其中提到了几种方法:
http://www.vincenzo.net/isxkb/index.php?title=Detect_if_an_application_is_running
或者,您可以在
InitializeSetup
中尝试以下(未经测试)代码:If the application has a Mutex, you can add an
AppMutex
value in your Inno Setup installer and it will display a message telling the user to stop the program. You might be able to find the Mutex (if it's got one) by using SysInternals Process Explorer and selecting the program / process and looking at the Handles (CTRL-H) in the Lower Pane.Here's a link to the a KB article that mentions several methods:
http://www.vincenzo.net/isxkb/index.php?title=Detect_if_an_application_is_running
Alternatively, you might try this (UNTESTED) code in the
InitializeSetup
:在版本 5.5.0 中(2012 年 5 月发布)添加了 Inno Setup在 Windows Vista 和较新。
引用 MSDN 链接文档(重点是我的):
好处是:您不需要在安装程序或应用程序中编写自定义代码来要求用户关闭它或自动关闭它。
如果您希望应用程序在更新完成后重新启动,则必须调用
RegisterApplicationRestart
函数。新指令的默认值会关闭安装程序的
[Files]
部分中包含的所有 .exe、.dll 和 .chm 文件。与之相关的更改是(来自发行说明):
In version 5.5.0 (Released on May 2012) Inno Setup added support for the Restart Manager API on Windows Vista and newer.
Quote from MSDN linked documentation (emphasis mine):
The good thing is: you don't need to write custom code in the installer or your application to ask the user to close it, or close it automatically.
If you want your application to restart after the update is complete, you have to call the
RegisterApplicationRestart
function from your application first.The default values for the new directives closes all the .exe, .dll and .chm files contained within the
[Files]
section of the installer.The changes related to it are (from release notes):
我尝试使用已接受的答案(以及 jachguate 的跟进),但它不会终止我的应用程序。看起来部分原因是我的应用程序窗口没有与之关联的文本,但无论真正的原因是什么,我使用 shell 命令来终止它并且有效。在 [code] 部分中,您要添加以下函数。它在复制安装文件之前被调用。
I tried using the accepted answer (and the follow up by jachguate) but it wouldn't kill my application. It looks like part of the reason was that my application window had no text associated with it but whatever is the real reason, I used shell command to kill it and that worked. In the [code] section, you want to add the following function. It is called just before setup files are copied.
如果您使用 InnoSetup,您可以考虑让 InnoSetup 安装程序执行 Windows SendBroadcastMessage,并让您的应用程序侦听该消息。当您的应用程序收到该消息时,它应该自行关闭。
我自己使用 InnoSetup 安装程序完成了此操作,效果非常好。
If you're using InnoSetup, you could look into getting your InnoSetup installer to do a Windows SendBroadcastMessage, and get your application to listen for that message. When your application receives the message, it should shut itself down.
I've done this myself with an InnoSetup installer, and it works very well.
下面是 Inno Setup 脚本的链接,如果检测到目标程序正在运行,该脚本会提示用户关闭目标程序。用户关闭程序后,可以单击“重试”按钮继续安装:
http://www.domador.net/extras/code-samples/inno-setup-close-a-program-before-reinstalling-it/
此脚本基于一个更简单的脚本,可在 Inno Setup Extensions 知识库中找到:
http://www.vincenzo.net/isxkb/index.php?title=Call_psvince.dll_on_install_and_uninstall
Here's a link to an Inno Setup script that prompts a user to close the target program, if it detects that the program is running. After the user closes the program, they can click on a "Retry" button to proceed with the installation:
http://www.domador.net/extras/code-samples/inno-setup-close-a-program-before-reinstalling-it/
This script is based on a simpler script, found in the Inno Setup Extensions Knowledge Base:
http://www.vincenzo.net/isxkb/index.php?title=Call_psvince.dll_on_install_and_uninstall
我已经成功使用 WMIC :
您也可以在
InitializeSetup
中执行此操作,但如果您这样做,请记住您还没有访问{app}
常量的权限。我的程序不要求安装路径,但你的程序可能会。I have had success using WMIC :
You can also do it in the
InitializeSetup
but if you do, keep in mind you don't have yet access to the{app}
constant. My program doesn't ask for install path, but yours might.在 [Setup] 部分添加 CloseApplications=true。
如果设置为“yes”或“force”并且安装程序不是以静默方式运行,并且安装程序检测到应用程序正在使用需要由 [Files] 或 [InstallDelete] 部分更新的文件,则安装程序将在“准备安装向导”页面上暂停,显示应用程序并询问用户是否应在安装完成后自动关闭应用程序并重新启动它们。
Add CloseApplications=true in [Setup] section.
If set to yes or force and Setup is not running silently, Setup will pause on the Preparing to Install wizard page if it detects applications using files that need to be updated by the [Files] or [InstallDelete] section, showing the applications and asking the user if Setup should automatically close the applications and restart them after the installation has completed.
InnoSetup 允许您将 Pascal 脚本附加到构建过程中的各个位置。尝试附加一个调用 ShellExecute 的脚本。 (如果脚本引擎还没有,您可能需要将其导入。)
InnoSetup allows you to attach Pascal scripts to various places in the build process. Try attaching a script that calls ShellExecute. (Which you may have to import to the script engine if it doesn't already have it.)
如果您愿意编写自己的 DLL,则可以使用 TlHelp32.pas 的工具帮助 API 来确定正在运行的应用程序,然后使用 EnumWindows 获取它们的窗口句柄,然后将 WM_CLOSE 发送到窗口句柄。
这有点痛苦,但应该有效:
我不久前和朋友一起开发了一些实用程序包装类。不记得我们是否基于其他人的代码。
TWindows.ProcessISRunning 和 TWindows.StopProcess 可能会有所帮助。
If you are happy to write your own DLL, you can use the tool help API for TlHelp32.pas to determine what applications are running, and then get a window handle for them using EnumWindows, then send a WM_CLOSE to the window handle.
It's a bit of a pain, but it should work:
I have some utility wrapper classes I developed with a friend a while back. Can't remember if we based it on someone else's code.
TWindows.ProcessISRunning and TWindows.StopProcess may help.
好吧,我认为执行此操作的更简单方法可能是在 Delphi 中创建一个 DLL,它检测您的程序是否正在运行并要求用户关闭它,将该 DLL 放入您的设置中并使用标志“dontcopy”(签入 http://www.jrsoftware.org/ishelp/ 位于 Pascal Scripting \ 使用 DLL 下作为示例)。
顺便说一句,下次使用互斥体时,Inno Setup 也支持这一点,并且要容易得多。
编辑:要提取文件(如果您想使用您提到的 .exe),只需使用 ExtractTemporaryFile() 即可。
Well, I think the easier way to perform this may be creating a DLL in Delphi that detects if your program is running and ask the user to close it, put that DLL in your setup and use the flag "dontcopy" (check in http://www.jrsoftware.org/ishelp/ under Pascal Scripting \ Using DLLs for an example).
Btw, next time use mutexes, Inno Setup also support that and is far more easier.
EDIT: and for extracting a file (if you want to use that .exe you mention), just use ExtractTemporaryFile().