这两天的时间一直在制作应用程序的升级包,期间碰到一些问题这里一并记录下来,相信这是制作升级包必须面临和解决的问题:
1. 升级包安装程序如何不再产生新的安装、卸载程序
Inno_setup中AppId是用来标识某个应用程序的唯一标识,因此升级包中的AppId字段应该和原始安装程序的AppId相同。
CreateUninstallRegKey字段,改值设置为no则安装程序将不会在控制面板的“添加/删除程序”中再创建一个。当这个关键字设置为 no时,UpdateUninstallAppName通常也设置为 no。
UpdateUninstallAppName如果为 yes, 当添加到一个已存在的卸载记录时,安装程序将以当前的安装程序的 AppName 替换在卸载记录中的 AppName。卸载记录中的 AppName决定了卸载程序显示的标题。如果你的安装程序只是一个升级或附加到一个已存在的程序,并且你不想改变卸载程序的标题,那么你可以设置该值为 no。
2. 如何检测以前的应用程序正在运行
判断某个应用程序是否正在运行,这里可以采用两种方式:一种是应用程序的进程是否正在运行;一种是通过窗口名称来检测。采用第一种方式时要引入ISTask.dll文件(它通常可以在Inno_setup安装包里面找到),实例代码如下:
1) 通过进程检测是否正在运行
首先确保ISTask.dll文件和脚本文件位于同一目录:
其次确保[Files]段中添加:
最后[Code]段中加入一下函数调用:
2) 通过窗口检测是否正在运行,主要是通过FindWindowByWindowName()函数,下面以检测有道词典是否正在运行为例:
以上两种情况可以依据自己的实际情况来选择,如果你的应用程序窗口固定那么采用第二种检测方式会方便一些;但是如果你无法确定窗口名称或你的窗口名称是会变化的,则采用第一种方式会更好。
3. 如何修改控制面板里原有程序的版本信息
制作升级包不得不面对的问题是版本升级,那么像下面所示如何修改控制面板中存在的版本信息是我们不得不面对的问题:
如何修改呢?看看我们的注册表就知道了:
图中标识的就是控制面板中可以看到的所有信息,那么解决方案就是修改注册表中的信息,具体代码如下:
具体涉及的两个操作就是:RegQueryStringValue()查询注册表和RegWriteStringValue()修改注册表,具体使用一看便知。
4. 如何修改控制面板里原有程序的显示图标
有了上面的如何修改控制面板里的版本信息,相信你已经猜到了,修改控制面板里应用程序的显示图标也是通过修改注册表来实现的,这里要提到的是:DisplayIcon字段,用来定义控制面板中应用程序图标的显示路径,代码如下:
升级包程序运行之后,控制面板中的信息为:
可以看到应用程序的显示图标和版本信息都已经修改了,再看下注册表里面,添加了DisplayIcon字段,其它信息也已经修改:
5. 如何检测浏览器正在运行
适用于当前主流浏览器,代码如下:
6. 如何进行文件查找及拷贝
不管是在安装包制作或升级包制作过程中,通常面临着文件的拷贝,除了[Files]段中的文件拷贝,请看如下的查找及拷贝操作:
FileSearch('rdp.tmp' , ExpandConstant('{app}'))表示查找应用程序安装目录下是否存在rdp.tmp文件,如果存在则返回该文件的绝对路径,如果不存在则返回' '
FileCopy(ExpandConstant('{tmp}\rdp.tmp') , ExpandConstant('{app}\rdp.tmp') , false)是将临时目录下的rdp.tmp文件拷贝到应用程序安装目录下,这里要注意两点:
1> 第二个参数目标文件,一定要带着最终的文件名,如果只是一个目录的路径,则拷贝操作会出错。
2> 第三个参数为true代表如果最终文件存在则拷贝操作失败,如果为false则拷贝操作会覆盖原有文件。
总结:以上就是2天的收获,升级包制作完成。Inno_setup是个比较强大的工具,里面还可以运行cmd命令。
相关代码:
// 卸载时判断浏览器是否正在运行
function InitializeUninstall(): Boolean;
var
iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;
begin
result:=true;
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');
i := ; while (iehWnd>) or (ffhWnd>) or (b360hWnd>) or (chrhWnd>) or (safhWnd>) do
begin
if i > then
begin
Msgbox('请确保所有浏览器都已关闭!', mbInformation, MB_OK);
end; if Msgbox('插件更新程序检测到浏览器正在运行。' ## '请您先关闭所有浏览器,单击“是”继续更新,否则按“否”退出安装', mbConfirmation, MB_YESNO) = idNO then
begin
Result:=false;
iehWnd :=;
ffhWnd :=;
b360hWnd :=;
chrhWnd :=;
safhWnd :=;
end else begin
Result :=true; //卸载程序继续
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');
end;
i := i+;
end;
end; // 检测应用服务是否正在使用 added by houqd 2013/12/17
// 该函数利用FindWindowByWindowName(),只能通过窗口的名字来判断
// 不适合现在的情况,采用另一种方式判断后台进程是否正在进行
function ifRunningDesktop():Boolean;
var
isRunning:Integer;
cycleCount:Integer;
begin
Result:=true;
cycleCount:=;
isRunning:=FindWindowByWindowName('有道词典');
while isRunning <> do
begin
if cycleCount > then
begin
Msgbox('请确保客户端已关闭!', mbInformation, MB_OK);
end;
if MsgBox('升级程序检测到客户端正在运行。' ## '您必须先关闭客户端然后单击“是”继续安装,或按“否”退出安装!',mbConfirmation, MB_YESNO) = idNO then
begin
Result:=false;
isRunning:=;
end else begin
Result:=true;
isRunning:=FindWindowByWindowName('VSODesktop');
end;
cycleCount:=cycleCount + ;
end;
end; // 判断某个进程是否正在运行,利用安装包里面自带的ISTask.dll插件
function RunTask(FileName: string; bFullpath: Boolean): Boolean;
external 'RunTask@files:ISTask.dll stdcall delayload'; function ifBrowserIsRunning():Boolean;
var
iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;
begin
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}'); if (iehWnd>) or (ffhWnd>) or (b360hWnd>) or (chrhWnd>) or (safhWnd>) then
begin
Result:=true;
end else begin
Result:=false;
end;
end; // 检测vsodesktop进程是否正在运行,即正在打开这vso应用软件
// added by houqd 2013/12/18
function ifVsoIsRunning():Boolean;
var
pstate:Boolean;
begin
Result:= RunTask('VSODesktop.exe', false);
end; // 升级包通过修改注册表,更改控制面板中已安装软件的版本信息
// added by houqd 2013/12/18
function updateVersion():Boolean;
var
ResultStr:String;
nDisplayName:String;
nVersion:String;
begin Result:=true;
nDisplayName:='{#PreDisplayName}'+'{#MyAppVersion}';
nVersion:='{#MyAppVersion}'; // 修改版本信息
if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayName',ResultStr) then
begin
if nDisplayName <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayName', nDisplayName);
end;
end; if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayVersion',ResultStr) then
begin
if nVersion <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayVersion', nVersion)
end;
end;
end; // 升级包通过修改注册表,更改控制面板中已安装软件的显示图标
// added by houqd 2013/12/18
function updateDisplayIcon():Boolean;
var
ResultStr:String;
nDisplayIcon:String;
installLocation:String;
begin
Result:=true; RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','InstallLocation',installLocation);
nDisplayIcon:=installLocation+'VSODesktop.exe'; // 如果DisplayIcon该键值存在则说明它原本就有图标,现在要对比更新
if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayIcon',ResultStr) then
begin
if nDisplayIcon <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)
end;
end else begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)
end;
end; rdpFileExsits:=FileSearch('rdp.tmp',ExpandConstant('{app}')); // 如果文件存在则返回绝对路径,如果不存在则返回空
if rdpFileExsits = '' then
begin
Exec(ExpandConstant('{cmd}'), '/c wmic qfe get hotfixid | find "KB2592687" > '+ExpandConstant('{tmp}\rdp.tmp'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
FileCopy(ExpandConstant('{tmp}\rdp.tmp'),ExpandConstant('{app}\rdp.tmp'),false);
end;
加油,坚持每天的学习,少年!
// 卸载时判断浏览器是否正在运行
function InitializeUninstall(): Boolean;
var
iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;
begin
result:=true;
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');
i := 0;
while (iehWnd>0) or (ffhWnd>0) or (b360hWnd>0) or (chrhWnd>0) or (safhWnd>0) do
begin
if i > 0 then
begin
Msgbox('请确保所有浏览器都已关闭!', mbInformation, MB_OK);
end;
if Msgbox('插件更新程序检测到浏览器正在运行。' #13#13 '请您先关闭所有浏览器,单击“是”继续更新,否则按“否”退出安装', mbConfirmation, MB_YESNO) = idNO then
begin
Result:=false;
iehWnd :=0;
ffhWnd :=0;
b360hWnd :=0;
chrhWnd :=0;
safhWnd :=0;
end else begin
Result :=true; //卸载程序继续
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');
end;
i := i+1;
end;
end;
// 检测应用服务是否正在使用 added by houqd 2013/12/17
// 该函数利用FindWindowByWindowName(),只能通过窗口的名字来判断
// 不适合现在的情况,采用另一种方式判断后台进程是否正在进行
function ifRunningDesktop():Boolean;
var
isRunning:Integer;
cycleCount:Integer;
begin
Result:=true;
cycleCount:=0;
isRunning:=FindWindowByWindowName('有道词典');
while isRunning <> 0 do
begin
if cycleCount > 0 then
begin
Msgbox('请确保客户端已关闭!', mbInformation, MB_OK);
end;
if MsgBox('升级程序检测到客户端正在运行。' #13#13 '您必须先关闭客户端然后单击“是”继续安装,或按“否”退出安装!',mbConfirmation, MB_YESNO) = idNO then
begin
Result:=false;
isRunning:=0;
end else begin
Result:=true;
isRunning:=FindWindowByWindowName('VSODesktop');
end;
cycleCount:=cycleCount +1 ;
end;
end;
// 判断某个进程是否正在运行,利用安装包里面自带的ISTask.dll插件
function RunTask(FileName: string; bFullpath: Boolean): Boolean;
external 'RunTask@files:ISTask.dll stdcall delayload';
function ifBrowserIsRunning():Boolean;
var
iehWnd, ffhWnd, chrhWnd, b360hWnd, safhWnd, i: Integer;
begin
iehWnd := FindWindowByClassName('IEFrame');
ffhWnd := FindWindowByClassName('MozillaWindowClass');
b360hWnd := FindWindowByClassName('360se6_Frame');
chrhWnd := FindWindowByClassName('Chrome_WidgetWin_1');
safhWnd := FindWindowByClassName('{1C03B488-D53B-4a81-97F8-754559640193}');
if (iehWnd>0) or (ffhWnd>0) or (b360hWnd>0) or (chrhWnd>0) or (safhWnd>0) then
begin
Result:=true;
end else begin
Result:=false;
end;
end;
// 检测vsodesktop进程是否正在运行,即正在打开这vso应用软件
// added by houqd 2013/12/18
function ifVsoIsRunning():Boolean;
var
pstate:Boolean;
begin
Result:= RunTask('VSODesktop.exe', false);
end;
// 升级包通过修改注册表,更改控制面板中已安装软件的版本信息
// added by houqd 2013/12/18
function updateVersion():Boolean;
var
ResultStr:String;
nDisplayName:String;
nVersion:String;
begin
Result:=true;
nDisplayName:='{#PreDisplayName}'+'{#MyAppVersion}';
nVersion:='{#MyAppVersion}';
// 修改版本信息
if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayName',ResultStr) then
begin
if nDisplayName <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayName', nDisplayName);
end;
end;
if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayVersion',ResultStr) then
begin
if nVersion <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayVersion', nVersion)
end;
end;
end;
// 升级包通过修改注册表,更改控制面板中已安装软件的显示图标
// added by houqd 2013/12/18
function updateDisplayIcon():Boolean;
var
ResultStr:String;
nDisplayIcon:String;
installLocation:String;
begin
Result:=true;
RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','InstallLocation',installLocation);
nDisplayIcon:=installLocation+'VSODesktop.exe';
// 如果DisplayIcon该键值存在则说明它原本就有图标,现在要对比更新
if RegQueryStringValue(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1','DisplayIcon',ResultStr) then
begin
if nDisplayIcon <> ResultStr then
begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)
end;
end else begin
RegWriteStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{C77BFCB0-66A4-4D04-82D9-FF74356FA0B1}_is1', 'DisplayIcon', nDisplayIcon)
end;
end;
rdpFileExsits:=FileSearch('rdp.tmp',ExpandConstant('{app}')); // 如果文件存在则返回绝对路径,如果不存在则返回空
if rdpFileExsits = '' then
begin
Exec(ExpandConstant('{cmd}'), '/c wmic qfe get hotfixid | find "KB2592687" > '+ExpandConstant('{tmp}\rdp.tmp'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
FileCopy(ExpandConstant('{tmp}\rdp.tmp'),ExpandConstant('{app}\rdp.tmp'),false);
end;
nno_setup制作升级包必须面临的几个问题 2的更多相关文章
-
Inno_setup制作升级包必须面临的几个问题
Inno_setup制作升级包必须面临的几个问题 分类: c/c++/GamingAnyWhere JavaScript linux shell基础知识 2013-12-18 22:14 1496人阅 ...
-
制作OTA升级包
OTA 软件包工具 本文地址http://wossoneri.github.io/2018/09/21/%5BAndroid%5D%5BFramework%5Dcreate-ota-update-zi ...
-
Android系统OTA升级包制作【转】
本文转载自:http://blog.csdn.net/dingfengnupt88/article/details/52882788 Android系统升级分为整包升级和差分包升级,整包升级就是将系统 ...
-
OTA升级包制作工具处理过程分析
http://blog.csdn.net/ly890700/article/details/56048815 Android Recovery(30) 1.概述 OTA升级包制作工具是一个用pyt ...
-
Wix打包系列(一)如何使用wix制作安装程序
原文:Wix打包系列(一)如何使用wix制作安装程序 最近由于项目需要,需要给客户制作安装程序,一开始使用vs2005自带的打包工程来打包,但用了一段时间发现vs打包太死板,而且使用起来问题很多.收费 ...
-
OTA制作及升级过程笔记【转】
本文转载自:http://www.it610.com/article/5752570.htm 1.概述 1.1 文档概要 前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理 ...
-
【转】高通平台android 环境配置编译及开发经验总结
原文网址:http://blog.csdn.net/dongwuming/article/details/12784535 1.高通平台android开发总结 1.1 搭建高通平台环境开发环境 在高通 ...
-
Wix打包系列(五) 部署数据库
原文:Wix打包系列(五) 部署数据库 很多人在使用vs进行打包的时候,经常会为数据库部署的问题犯愁,即便是重写Installer类的方法,也不是很可靠方便,下面我们来看看在wix中如何部署数据库. ...
-
fedroa20中将ssh,ssl升级到当前最新版本
Fedroa20下手工安装openssh-server 本例以Fedroa20为例,需要下载:zlib-1.2.8.tar.openssl-1.0.2e.tar. openssh-7.1p1.tar. ...
随机推荐
-
《C++必知必会》学习笔记
转载:http://dsqiu.iteye.com/blog/1734640 条款一 数据抽象 抽象数据设计遵循步骤:(1)为类型取一个描述性的名字.(2)列出类型所能执行的操作,不要忘了初始化(构造 ...
-
Winform开发框架之权限管理系统的改进
权限管理系统,一直是很多Mis系统和一些常见的管理系统所需要的,所以一般可以作为独立的模块进行开发,需要的时候进行整合即可,不需要每次从头开发,除非特殊的系统需求.我在Winform开发框架介绍中的随 ...
-
kafka监控项目大全
https://github.com/claudemamo/kafka-web-console http://github.com/pinterest/doctorkafka http://g ...
-
XGBoost参数调优完全指南
简介 如果你的预测模型表现得有些不尽如人意,那就用XGBoost吧.XGBoost算法现在已经成为很多数据工程师的重要武器.它是一种十分精致的算法,可以处理各种不规则的数据.构造一个使用XGBoost ...
-
Bcompare工具永久使用方法
bcompare的简介 我们在工作中会经常用到bcompare工具:合入驱动,对比原始文件等. bcompare,即Beyond Compare 是一个综合的比对工具. 可比对的对象包括纯文字档. ...
-
[SDOI2016]储能表——数位DP
挺隐蔽的数位DP.少见 其实减到0不减了挺难处理.....然后就懵了. 其实换个思路: xor小于k的哪些都没了, 只要留下(i^j)大于等于k的那些数的和以及个数, 和-个数*k就是答案 数位DP即 ...
-
项目笔记---事半功倍之GhostDoc(二)
前言 前一篇文章<项目笔记---事半功倍之StyleCop(一)>提到如何约束代码,规范代码风格,这一节,我们将了解如何快速生成符合规则的代码注释---GhostDoc 一.安装Ghost ...
-
【转发】Linux中设置服务自启动的三种方式
有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s 在/etc/rc.d/rc*.d目录中建立/e ...
-
sql学习之创建表空间创建用户并授权
--创建表空间语法:create tablespace [name]create tablespace hclTest--设置参数datafile 'F:/orcale/hclTest'--设置表空间 ...
-
【转载】Spark学习——入门
要学习分布式以及数据分析.机器学习之类的,觉得可以通过一些实际的编码项目入手.最近Spark很火,也有不少招聘需要Spark,而且与传统的Hadoop相比,Spark貌似有一些优势.所以就以Spark ...