1、源起:

KV项目下载底层升级包,老是报出升级文件占用问题,反复分析,不得其所。

今天突然发现同时启动多个升级程序实例,分析认为安装包同时被调用多次,引发实例访问文件冲突,导致此问题。

安装程序由Inno Setup制作,遂找其解决方案,最先想到的是互斥体,就由此开始!

2、AppMutex

[Setup]
AppMutex=MyAppMutex

安装程序Setup段,此互斥变量,会在安装程序启动时检测是否有此互斥体的程序在运行,若有则提示:

通常在程序中置同名互斥体,此处判断,可避免程序在运行时,安装包再去安装,比如产品升级。

好,可在安装程序中创建一互斥体,以其做为判断条件。  

3、CreateMutex()

Inno Setup中,此函数是创建互斥体的,我们在安装程序运行后创建互斥体,这样再次运行安装程序,就可互斥了。

[Code]
procedure InitializeWizard();
begin
//开始运行,创建此互斥体
CreateMutex('MyAppMutex');
end;

注意此互斥体创建不能置于function InitializeSetup(): Boolean;函数, 它先于[Setup]段运行,会导致安装程序不能执行。

4、CheckForMutexes()

因为升级程序是静默安装的,以上代码虽可执行,但会弹出节2那个提示框,不够友好。

即使加静默安装参数/SP- /VERYSILENT也无济于事,它仍然不能避免此弹出框,怎么办?

这么办:

function InitializeSetup(): Boolean;
begin
//若此例已运行,则不再执行
Result := not CheckForMutexes('MyAppMutex');
end;

此函数中判断互斥体,若已存在,直接退出,安静得像那夜的月光!

就这样,问题解决了。

大体来说,正常安装程序,需要弹提示框的,前三步都能解决问题,正常交互亦当如此。

而用互斥量处理多实例运行,相比FindWindowByWindowName()方法可靠的多,这个好用。

Inno Setup安装程序单例运行的更多相关文章

  1. Inno Setup 安装前卸载原程序

    Inno Setup 安装前卸载原程序 分类: Install Setup 2013-02-02 15:53 2315人阅读 评论(0) 收藏 举报 很多時候我們需要在安裝文件之前卸載原有的程序而不是 ...

  2. DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法

    原文:DevExpress Winform使用单例运行程序方法和非DevExpress使用Mutex实现程序单实例运行且运行则激活窗体的方法 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...

  3. 一个比较完整的Inno Setup 安装脚本(转)

    一个比较完整的Inno Setup 安装脚本,增加了对ini文件设置的功能,一个安装包常用的功能都具备了. [Setup] ; 注: AppId的值为单独标识该应用程序. ; 不要为其他安装程序使用相 ...

  4. Inno Setup 安装、卸载前检测进程或服务

    [转载]Inno Setup 安装.卸载前检测进程或服务 (2015-04-24 17:37:20) 转载▼ 标签: 转载   原文地址:Inno Setup 安装.卸载前检测进程或服务作者:一去丶二 ...

  5. 一个比较完整的Inno Setup 安装脚本

    一个比较完整的Inno Setup 安装脚本,增加了对ini文件设置的功能,一个安装包常用的功能都具备了. [Setup] ; 注: AppId的值为单独标识该应用程序. ; 不要为其他安装程序使用相 ...

  6. PHP实现程序单例执行

    原创文章,转载请注明出处:http://huyanping.sinaapp.com/?p=222 作者:Jenner 一.场景描写叙述: 近期我们一块业务.须要不断的监听一个文件夹的变化.假设文件夹中 ...

  7. C#应用程序单例并激活程序的窗口 使其显示在最前端

    public class SoftHelper { ///<summary> /// 该函数设置由不同线程产生的窗口的显示状态 /// </summary> /// <p ...

  8. Qt实现应用程序单实例运行--LocalServer方式

    使Qt应用程序能够单实例运行的典型实现方法是使用共享内存实现.该方法实现简单,代码简洁. 但有一个致命缺陷:共享内存(QSharedMemory)实现的单程序运行,当运行环境是UNIX时,并且程序不幸 ...

  9. INNO SETUP卸载程序中加入自定义窗体

    原文:INNO SETUP卸载程序中加入自定义窗体 [Setup] AppName=My Program AppVerName=My Program v.1.2 DefaultDirName={pf} ...

随机推荐

  1. centos7 自动定时备份mysql数据库

    shell脚本:mysqlbak.sh #!/bin/bashPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbinexpo ...

  2. Redis简单生产者消费者

    注意:redis客户端执行是单线程的,不能将客户端放在外面,内部执行使用多线程的方式. // 创建生产端连接 final Jedis jedisProducter = new Jedis(R_HOST ...

  3. APP-10-文字识别-票据识别

    1.Postman测试 2.参数 https://cloud.baidu.com/doc/OCR/OCR-API.html#.E9.80.9A.E7.94.A8.E7.A5.A8.E6.8D.AE.E ...

  4. C++17尝鲜:编译期 if 语句

    Constexpr If(编译期 if 语句) 以 if constexpr 打头的 if 语句被称为 Constexpr If. Constexpr If 是C++17所引入的新的语法特性.它为C+ ...

  5. Kotlin语言学习笔记(1)

    fun main(args: Array<String>) { println("Hello, World!") } 基本语法 声明常量用val,声明变量用var,声明 ...

  6. [ SHELL编程 ] echo和printf使用实例

    本文主要描述Linux系统中echo和printf命令的使用方法,包括命令参数的含义.使用技巧. 1.echo    了解一个命令我们首先要知道它能做什么,它有哪些参数,参数的含义,可以实现我们哪方面 ...

  7. 10.mysql-触发器.md

    目录 定义 语法 定义 当操作了某张表时,希望同时触发一些动作/行为,可以使用触发器完成 语法 -- 需求: 当向员工表插入一条记录时,希望mysql自动同时往日志表插入数据 -- 创建触发器(添加) ...

  8. Java复习 之容器

    小生快要准备找工作了 现在开始复习一下Java基础之容器 Set和List是一个个往里面存 Map是两个两个往里面装 所谓重复指的是他们互相equals Collection 接口定义了存取一组对象的 ...

  9. Swift中的的注释

    1. Swift支持与OC中相同的     /**/  ./***/  不同点Swift支持 /*/**/ 这样的注释  ,多行注释 2. 直接双杠注释 // 单行注释 3. 利用 //MARK: 返 ...

  10. EF 控制code-first生成的数据库表名的单复数

    原地址:https://blog.csdn.net/winnyrain/article/details/51248410 在Code-First中,默认生成的数据库表的名称为类型的复数形式,如Mode ...