需要在安装升级时阻止访问某些功能
我们的产品允许通过 MSI 安装程序安装更新。更新包含需要复制到磁盘的多个文件,以及安装程序通过运行多个 SQL 脚本添加的数据库条目。
当主可执行文件打开时,可以(并且通常)安装更新。因此,我需要一种方法来防止在升级过程中访问某些数据库密集型功能。
我当前的想法:
- 安装程序在启动时添加一个注册表项。
- 更新已安装。
- 无论成功还是失败,注册表项都会被删除。
同时,应用程序(用 C# 编写)查询注册表项是否存在,如果已设置,则显示错误对话框。
这可靠吗?我担心如果用户通过任务管理器杀死安装程序会发生什么,那么注册表项将永远不会被删除,并且用户将被永久锁定在该功能之外。也不确定上述解决方案可能导致的任何竞争条件。
关于这种方法是否可行或者更好的方法有什么建议吗?
Our product allows updates to be installed via an MSI installer. An update consists of several files which need to be copied to disk, and the addition of database entries which the installer adds by running several SQL scripts.
Updates can be (and commonly are) installed while the main executable is open. Because of this, I need a way of preventing access to a certain database-intensive feature while the upgrade is in progress.
My current thoughts:
- Installer adds a registry key when it starts up.
- Update is installed.
- On success or failure, the registry key is deleted.
Meanwhile, the application (written in C#) queries for the presence of the registry key, displaying an error dialog if it is set.
Is this reliable? I'm concerned about what happens if the user kills the installer via task manager, then the registry key will never be deleted and the user will be permanently locked out of the feature. Also not sure about any race conditions that the above solution could lead to.
Any suggestions about whether this approach is feasible, or a better approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如此处所述,将中断所有其他连接并允许您继续执行更新。
As described here will break all other connections and allow you to proceed with the update.
Windows Installer 已经实现了互斥体来指示安装正在进行中。只需编写数据库密集型代码来检查该互斥锁和空操作是否存在。不需要做任何额外的事情。
(注意:使用此功能将在 MSI 安装产品时停止您的处理,这可能不是一个坏主意。如果您想要一个独特的互斥体,编写自定义操作很简单。)
_MSIExecute Mutex
由 @LeopardSkinPillBoxHat 更新
上面的答案满足了我的需要。这是我最终使用的代码:
Windows Installer already implements a Mutex to indicate that an installation is in progress. Just code your database intensive code to check for that mutex and no-op while it's present. Nothing additional needs to be done.
(Note: using this will stop your processing any time MSI is installing a product which is probably not a bad idea anyways. If you want a unique mutex, it's trivial to write a custom action. )
_MSIExecute Mutex
Update by @LeopardSkinPillBoxHat
The above answer did what I needed. This is the code I ended up using:
在这里使用命名的 Mutex 是否合理?要求密集型任务和更新程序在执行之前首先获取互斥锁。
编辑:我撒谎说将互斥体包装在
using
中将保护您免受任务管理器关闭的影响。这是有道理的,您不会期望finally
块执行。您最终会得到一个 AbandonedMutex,我链接的 msdn 文章中对此进行了讨论。最近还看到一篇有用的小文章关于使用互斥锁来防止同一程序的多个实例执行。
Would using a named Mutex be reasonable here? Require that the intensive tasks and the updater first acquire the mutex before executing.
EDIT: I lied about wrapping the mutex in a
using
will protect you from task manager shutdowns. Makes sense, you wouldn't expectfinally
blocks to execute either. What you'll end up with is an AbandonedMutex, which is discussed in the msdn article I linked.Also saw recently a useful little article about using a Mutex to prevent multiple instances of the same program from executing.