我们的产品允许通过MSI安装程序安装更新。更新包括几个需要复制到磁盘的文件,以及安装程序通过运行多个SQL脚本添加的数据库条目。
当主可执行文件打开时,可以(而且通常是)安装更新。因此,在升级过程中,我需要一种防止访问某个数据库密集型功能的方法。
我现在的想法是:
同时,应用程序(用C#编写)查询注册表项的存在,如果设置了错误对话框,则显示错误对话框。
这可靠吗?我担心的是,如果用户通过任务管理器杀死安装程序,那么注册表项将永远不会被删除,并且用户将被永久地锁定在特性之外。另外,也不确定上述解决方案可能导致的任何竞赛条件。
对于这种方法是否可行,还是更好的方法,有什么建议吗?
发布于 2012-02-01 05:54:58
Windows已经实现了Mutex,以指示安装正在进行中。只需对数据库密集型代码进行编码,以检查是否存在互斥和无操作。不需要做任何额外的事情。
(注意:在MSI安装产品时,使用它将停止您的处理,这可能是一个不错的主意。)如果您想要一个唯一的互斥对象,那么编写自定义操作就很简单了。)
MSIExecute互斥
@LeopardSkinPillBoxHat更新
上面的答案做了我所需要的。这是我最后使用的代码:
static void Main(string[] args)
{
try
{
Mutex mutex = Mutex.OpenExisting(@"Global\_MSIExecute");
if (!mutex.WaitOne(TimeSpan.FromSeconds(5), false))
{
Console.WriteLine("Installation in progress!");
return;
}
}
catch (AbandonedMutexException)
{
Console.WriteLine("Mutex was abandoned");
}
catch (WaitHandleCannotBeOpenedException)
{
Console.WriteLine("MSI installer not running");
}
// Perform operation here
}
发布于 2012-02-01 02:05:09
在这里使用命名的互斥是否合理?要求密集型任务和更新程序在执行之前首先获取互斥对象。
编辑:--我在using
中包装互斥锁时撒了谎,这样可以防止任务管理器关闭。有道理,您也不会期望finally
块执行。您最终将得到一个AbandonedMutex,在我链接的msdn文章中将对此进行讨论。
最近还看到了一个有用的小文章,它使用Mutex来防止同一个程序的多个实例执行。
发布于 2012-02-01 03:49:15
ALTER DATABASE <name> SINGLE_USER
如上所述,这里将中断所有其他连接,并允许您继续进行更新。
https://stackoverflow.com/questions/9089452
复制相似问题