InnoSetup 制作安装包进阶版
如何制作更进阶一点的软件包?比如根据安装包选择的语言设置软件启动时的语言,比如对注册表进行操作,再比如检测电脑是否安装相关的.NET环境等等。
下面来一一介绍,根据前面制作的简单脚本安装包来升级,请参考我的上一篇Inno Setup 软件安装包制作
一 添加快捷方式的图标
1 准备图标
这是在阿里巴巴图库上找的图片, 在[Files] 段,将图片添加进来
[Files]
Source: "E:\安装包测试\logo.ico"; DestDir: "{app}"; Flags: ignoreversion
2 创建图标快捷方式
在[Icons]段,设置图标,比如下面设置了桌面快捷方式的图标是logo.ico,卸载程序的图标是delete.ico, 如果你还有其它exe程序需要设置图标可以参考下面的脚本
[Icons]
Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\logo.ico"; Tasks: desktopicon
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"; IconFilename: "{app}\delete.ico"
二 根据安装时选择的语言设置软件的初始语言
思路是对软件中的某个配置语言文件写文字。
1 初始脚本语言
在 [Languages]段里,设置了中文和英文两种,注释掉的是原始的脚本,因为Name名称有点长,在这里我们改一下,将english更改为en, chinesesimplified更改为ch,便于后面的使用。
[Languages]
;Name: "english"; MessagesFile: "compiler:Default.isl"
;Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "ch"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
还有一个将要更改的文件加入到[Files]段中
[Files]
Source: "E:\安装包测试\ZedgraphMulY\Config.ini"; DestDir: "{app}"; Flags: ignoreversion
2 写脚本,将选择的语言写入文件中
在[Code]段写一段脚本,使用系统提供的函数来处理,在软件安装完成之后将修改Config.ini的值。
procedure CurStepChanged(CurStep: TSetupStep);
你可以用这个事件函数执行你自己的预安装和安装后任务。TSetupStep 值,可以取下面三个
ssInstall, ssPostInstall, ssDone含义分别是:
在实际安装开始之前用 CurStep=ssInstall 调用,
或在实际安装完成之后用 CurStep=ssPostInstall 调用,
或在安装程序终止之前和安装完成之后用 CurStep=ssDone 调用。
;执行脚本
[Code]
//修改软件语言信息
procedure CurStepChanged(CurStep: TSetupStep);
var
languageName: string;
beginif CurStep=ssDone then //软件安装后执行beginlanguageName := ActiveLanguage(); // 获取用户选择的语言if 'ch' = languageName thenbeginSetIniString('Lang','CurLang','Chinese',ExpandConstant('{app}/Config.ini'));endelse if 'en' = languageName thenbeginSetIniString('Lang','CurLang','English',ExpandConstant('{app}/Config.ini'));end;end;
end;
三 对注册表进行操作
1 注册表[Registry] 区段
Root
[Registry] 区段
这个可选区段用来定义一些你想用安装程序在用户系统中创建、修改或删除的注册表键/值。按默认值,用安装程序创建的注册表键和值在卸载时不删除。如果你想让卸载程序删除键或值,你必须包含下面描述的 uninsdelete* 标志之一。Root (必需的)
根键。必须是下列值中的一个:
HKCU (HKEY_CURRENT_USER)
HKLM (HKEY_LOCAL_MACHINE)
HKCR (HKEY_CLASSES_ROOT)
HKU (HKEY_USERS)
HKCC (HKEY_CURRENT_CONFIG)
Subkey
Subkey (必需的)
子键名称,可以包含常量。示例:
Subkey: "Software\My Company\My Program"
Subkey: "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags"
ValueType
值的数据类型。必须是下面中的一个:none
string
expandsz
multisz
dword
qword
binary如果指定了 none(默认设置),安装程序将创建一个没有键值的键,在这种情况下,ValueName 和 ValueData 参数将被忽略。
如果指定了 string,安装程序将创建一个字串(REG_SZ)值。
如果指定了 expandsz,安装程序将创建一个扩展字串(REG_EXPAND_SZ)值。
如果指定了 multisz,安装程序将创建一个多行文本(REG_MULTI_SZ)值。
如果指定了 dword,安装程序将创建一个32-位整数(REG_DWORD)值。
如果指定了 qdword,安装程序将创建一个64-位整数(REG_QDWORD)值。
如果指定了 binary,安装程序将创建一个二进制(REG_BINARY)值。示例:
ValueType: string
ValueData
值的数据。
如果 ValueType 参数是 string,expandsz 或 multisz,这是这一个可以包含常量的字串。
如果数据类型是 dword或qdword,这可以是一个十进制整数(例如“123”),一个十六进制整数(例如“$7B”)或解析为整数的常量。
如果数据类型是 binary,这可以是下列形式的十六进制字节序列: “00 ff 12 34”。如果数据类型是 none,将被忽略。示例:
ValueData: "1.0"
Flags
仅介绍了两个常用的flags
uninsdeletekey
当卸载程序时,删除整个键,包含其中的所有值和子键。这对于 Windows 自身使用的键明显不是一个好方法。你只能用于你的应用程序特有的键中。
为防止意外,安装期间如果 Subkey 是空白或只包含反斜杠符号,该标志被忽略。uninsdeletekeyifempty
当程序卸载时,如果这个键的内部没有值或子键,则删除这个键。该标志可以与 uninsdeletevalue 组合使用
为防止意外,安装期间如果 Subkey 是空白或只包含反斜杠符号,该标志被忽略。
2 注册表的使用
[Registry]
Root: HKLM; Subkey: Software\ZedgraphMulY; ValueType: string; ValueName: Installed version; ValueData: '1.0'; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY工程文件"; ValueType: string; ValueData: "ZedgraphMulY工程文件"; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY\DefaultIcon"; ValueType: string; ValueData: "{app}\logo.ico"; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY工程文件\shell\open\command"; ValueType: string; ValueData: """{app}\ZedgraphMulY.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: ".zt"; ValueType: string; ValueData: "ZedgraphMulY工程文件"; Flags: uninsdeletekey
;解决解决提示你要允许来自未知发布者的此应用对你的设备进行更改吗的问题
Root: HKCU; Subkey: "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"; ValueType: string; ValueName: "{app}\ZedgraphMulY.exe" ; ValueData: RunAsInvoker; Flags: uninsdeletekey
键盘按WIN+R键,调出运行界面,输入regedit,点击回车调出注册表信息。这是一个树形节点结构的。
四 检测电脑的.NET环境
使用VS开发.net框架的桌面应用程序,如果要在其它电脑上正常运行起来需要相应的.net框架支持。我们想在客户安装软件的时候就可以将环境一起安装好,而不是用户自己手动去下载安装。
这里给的例子是离线安装(会导致我们的安装包会比较大),因为连网安装一个是速度比较慢,还有一个是客户可能没有网。
先说一下思路,将.net离线安装包放到制作安装包的文件里面,检测到电脑没有这个.net 框架时就运行.net安装包,等待程序全部安装完成之后会将.net安装包删除掉。
1 先准备.net环境安装包
根据自己软件需要的环境,下载.net离线安装包,可参考我的这篇找.NET Framework 离线安装包下载地址
将.NET安装包放在“E:\安装包测试\ZedgraphMulY\tmp\“目录下
使用脚本将.NET安装包添加的我们制作的安装包中,在[Files]段添加如下脚本
[Files]
;.net环境安装包
Source: "E:\安装包测试\ZedgraphMulY\tmp\*"; DestDir: "{app}\tmp"; Flags: ignoreversion recursesubdirs createallsubdirs
2 检测.NET环境
在这里我们通过访问电脑的注册表信息 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4.0来判断是否安装了.net
在Code段中,定义了Framework40IsNotInstalled()函数来检测是否有安装.NET 4.0,如果没有,则安装InstallFramework
;执行脚本
[Code]
//判断当前是否有安装.net4.0 运行环境
function Framework40IsNotInstalled() : Boolean;
var
bSuccess: Boolean;
regVersion: Cardinal;
tmppath: string;
begin
Result := True;
tmppath := ExpandConstant('{app}') + '\tmp';
//检查版本
bSuccess := RegKeyExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4');
if(True = bSuccess) then begin Result := False;//不需要安装,则删除安装包tmp// 删除目录 C:\Test 和它内部的一切//DelTree('C:\Test', True, True, True);if FileOrDirExists(tmppath) then beginDelTree(tmppath, true, true, true);end;end;end;procedure InstallFramework;
varStatusText: string;ResultCode: Integer;tmppath:string ; setupOk: Boolean;begin//先抽取到临时目录 ,将相对目录 展开到常量(绝对)目录 ExpandConstant('{app}\tmp\ndp40.exe')tmppath := ExpandConstant('{app}') + '\tmp\dotNetFx40_Full_x86.exe';StatusText := WizardForm.StatusLabel.Caption;WizardForm.StatusLabel.Caption := ExpandConstant('{cm:CmCaption}');WizardForm.ProgressGauge.Style := npbstMarquee;try// if not Exec(tmppath, '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) thenif FileOrDirExists(tmppath) then beginsetupOk := Exec(tmppath, '/q', '', SW_SHOW, ewWaitUntilTerminated, ResultCode); if( setupOk = False) then beginMsgBox(tmppath + IntToStr(ResultCode) + '.', mbError, MB_OK);end;end;finallyWizardForm.StatusLabel.Caption := StatusText;WizardForm.ProgressGauge.Style := npbstNormal; // 删除目录 C:\Test 和它内部的一切//DelTree('C:\Test', True, True, True);tmppath := ExpandConstant('{app}') + '\tmp';DelTree(tmppath, true, true, true);end;
end;
在[Code]字段前面的判断语言处,添加该脚本
//检测.net环境,如果没有则安装if CurStep=ssPostInstall thenbeginif Framework40IsNotInstalled() thenbeginInstallFramework();end;end;
五 整个脚本代码
最后附上整个安装包文件的结构和整个脚本的代码
; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!#define MyAppName "ZedgraphMulY"
#define MyAppVersion "1.0"
#define MyAppPublisher "唠嗑一夏"
#define MyAppURL "http://www.example.com/"
#define MyAppExeName "ZedgraphMulY.exe"[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{22AED403-1AC3-4712-BD48-CDE942CEB8AD}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DisableProgramGroupPage=yes
OutputDir=E:\安装包测试
OutputBaseFilename=setup
Compression=lzma
SolidCompression=yes[Languages]
;Name: "english"; MessagesFile: "compiler:Default.isl"
;Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"Name: "en"; MessagesFile: "compiler:Default.isl"
Name: "ch"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked[Files]
Source: "E:\安装包测试\ZedgraphMulY\ZedgraphMulY.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\安装包测试\ZedgraphMulY\ZedGraph.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\安装包测试\ZedgraphMulY\ZedGraph.xml"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\安装包测试\ZedgraphMulY\ZedgraphMulY.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\安装包测试\ZedgraphMulY\es\*"; DestDir: "{app}\es"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "E:\安装包测试\ZedgraphMulY\zh-cn\*"; DestDir: "{app}\zh-cn"; Flags: ignoreversion recursesubdirs createallsubdirs;.net环境安装包
Source: "E:\安装包测试\ZedgraphMulY\tmp\*"; DestDir: "{app}\tmp"; Flags: ignoreversion recursesubdirs createallsubdirs;语言配置文件
Source: "E:\安装包测试\ZedgraphMulY\Config.ini"; DestDir: "{app}"; Flags: ignoreversion;图片
Source: "E:\安装包测试\logo.ico"; DestDir: "{app}"; Flags: ignoreversion
Source: "E:\安装包测试\delete.ico"; DestDir: "{app}"; Flags: ignoreversion; NOTE: Don't use "Flags: ignoreversion" on any shared system files[Icons]
Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\logo.ico"; Tasks: desktopicon[Run]
;安装完成是否需要直接运行,如果不需要该功能可以删除Run段
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent[Registry]
Root: HKLM; Subkey: Software\ZedgraphMulY; ValueType: string; ValueName: Installed version; ValueData: '1.0'; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY工程文件"; ValueType: string; ValueData: "ZedgraphMulY工程文件"; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY\DefaultIcon"; ValueType: string; ValueData: "{app}\logo.ico"; Flags: uninsdeletekey
Root: HKCR; Subkey: "ZedgraphMulY工程文件\shell\open\command"; ValueType: string; ValueData: """{app}\ZedgraphMulY.exe"" ""%1"""; Flags: uninsdeletekey
Root: HKCR; Subkey: ".zt"; ValueType: string; ValueData: "ZedgraphMulY工程文件"; Flags: uninsdeletekey
;解决解决提示你要允许来自未知发布者的此应用对你的设备进行更改吗的问题
Root: HKCU; Subkey: "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"; ValueType: string; ValueName: "{app}\ZedgraphMulY.exe" ; ValueData: RunAsInvoker; Flags: uninsdeletekey; //用于定义{cm:...}常量的自定义消息值
[CustomMessages]en.CmCaption = Installing.NET Framework 4.0 May take a few minutes...
en.CmNetErr = .NET installation failed, please contact administrator, code: ch.CmCaption = 正在安装 .NET Framework 4.0 可能需要几分钟的时间...
ch.CmNetErr = .NET 安装失败,请联系管理员,代码: ;执行脚本
[Code]//卸载程序清除注册表信息
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
beginif CurUninstallStep = usUninstall thenbeginRegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\ZedgraphMulY');RegDeleteKeyIncludingSubkeys(HKEY_CLASSES_ROOT, 'ZedgraphMulY');DelTree(ExpandConstant('{app}'), True, True, True);end;
end;//判断当前是否有安装.net4.0 运行环境
function Framework40IsNotInstalled() : Boolean;
var
bSuccess: Boolean;
regVersion: Cardinal;
tmppath: string;
begin
Result := True;
tmppath := ExpandConstant('{app}') + '\tmp';
//检查版本
bSuccess := RegKeyExists(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4');
if(True = bSuccess) then begin Result := False;//不需要安装,则删除安装包tmp// 删除目录 C:\Test 和它内部的一切//DelTree('C:\Test', True, True, True);if FileOrDirExists(tmppath) then beginDelTree(tmppath, true, true, true);end;end;end;procedure InstallFramework;
varStatusText: string;ResultCode: Integer;tmppath:string ; setupOk: Boolean;begin//先抽取到临时目录 ,将相对目录 展开到常量(绝对)目录 ExpandConstant('{app}\tmp\ndp40.exe')tmppath := ExpandConstant('{app}') + '\tmp\dotNetFx40_Full_x86.exe';StatusText := WizardForm.StatusLabel.Caption;WizardForm.StatusLabel.Caption := ExpandConstant('{cm:CmCaption}');WizardForm.ProgressGauge.Style := npbstMarquee;try// if not Exec(tmppath, '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) thenif FileOrDirExists(tmppath) then beginsetupOk := Exec(tmppath, '/q', '', SW_SHOW, ewWaitUntilTerminated, ResultCode); if( setupOk = False) then beginMsgBox(tmppath + IntToStr(ResultCode) + '.', mbError, MB_OK);end;end;finallyWizardForm.StatusLabel.Caption := StatusText;WizardForm.ProgressGauge.Style := npbstNormal; // 删除目录 C:\Test 和它内部的一切//DelTree('C:\Test', True, True, True);tmppath := ExpandConstant('{app}') + '\tmp';DelTree(tmppath, true, true, true);end;
end;//修改软件语言信息
procedure CurStepChanged(CurStep: TSetupStep);
var
languageName: string;
beginif CurStep=ssDone then //软件安装后执行beginlanguageName := ActiveLanguage(); // 获取用户选择的语言if 'ch' = languageName thenbeginSetIniString('Lang','CurLang','Chinese',ExpandConstant('{app}/Config.ini'));endelse if 'en' = languageName thenbeginSetIniString('Lang','CurLang','English',ExpandConstant('{app}/Config.ini'));end;end;//检测.net环境,如果没有则安装if CurStep=ssPostInstall thenbeginif Framework40IsNotInstalled() thenbeginInstallFramework();end;end;end;
六 效果图
1桌面快捷方式的图标
2 设置软件语言
3 检测.net环境
4 注册表信息
控制面板
安装过程的效果图可参考 第一篇的软件安装包的制作
InnoSetup 制作安装包进阶版相关推荐
- Qt软件发布(版本信息,Release版程序,代码打包,制作安装包)
序言 当我们完成了Qt程序的开发,希望交予测试,或是正式发布的时候,需要将我们的程序进行层层封装,最终以一个安装包的形式呈现给用户.专业版的软件发布,以Qt软件为例,需要三个步骤:生成版本信息,生成R ...
- 使用NSIS制作安装包
使用NSIS制作安装包 (2018-01-08 14:25:12) 转载▼ 标签: nsis 分类: windows 这两天使用NSIS制作了一个程序安装包,这里记录一下过程. 开始参考博客:http ...
- vs2005制作安装包(自动安装.net framework 2.0)(小寿原创)
vs2005制作安装包(自动安装.net framework 2.0)(小寿原创) 新建项目-> 其他项目类型->安装和部署->安装向导! 安装向导会提示你添加要安装的文件,这时你可 ...
- VS2008制作安装包
图文详细地址:http://www.itwis.com/html/net/kaifagongju/20090218/3387.html VS2008制作安装包 安装与部署 2010-03-13 14: ...
- Debian、Ubuntu源码编译制作安装包(二)
在<Debian.Ubuntu源码编译制作安装包(一)>文章中描述了dpkg基本制作安装包过程,本篇文章描述如何增加patch及解决出错问题. 章节预览: 5. 增加patch 6. 修改 ...
- Debian、Ubuntu源码编译制作安装包(一)
Debian.Ubuntu系列linux操作系统制作安装包相较于CentOS更简便一些,如"dpkg -b"指令即可重新打包.如果需要源码级制作安装包则更困难一些,接下来,我们逐步 ...
- 利用WIX制作安装包(2)
利用WIX制作安装包(2) 原文 利用WIX制作安装包(2) 这一篇文章将为大家介绍如何使用WIX自定义UI.上一篇文章我们讲过WIX为我们提供了五种安装界面.每种安装界面都是由不同的Dialog组成 ...
- 为自己编写的windows应用程序制作安装包
1 写好了一个windows程序之后如何制作安装包 这个在vs中就可以直接发布了,可以制作msi的安装包和exe的安装包. 2 window应用程序安装包做了哪些事情 rpm安装包的话,只是把相应的文 ...
- vs 2019使用Installer Project制作安装包的问题
项目场景: vs 2019 C# 项目使用Installer Project制作安装包 问题描述: 1.vs 2019 中visual studio marketplace中无法下载Installer ...
- 使用NSIS制作安装包(1)
NSIS是一个基于脚本语言的制作安装包的免费工具,它使用起来也很方便,下面是制作安装.NET框架和语言包的脚本. NSIS的编译器和脚本编辑工具可以到nsis.sf.net上下载 !include W ...
最新文章
- 树莓派4装Ubuntu
- 浪潮集团执行总裁王柏华:这次人工智能产业发展大潮“是真的”
- https://www.ibm.com/developerworks/cn/topics/ ibm中国开发主题网站。
- vue开发(1) 软件安装
- 成员缩写_「gnps,nbcs」是什么意思?00后饭圈缩写你看懂多少
- 几分钟学会归并排序和快速排序
- 基于.NetCore3.1搭建项目系列 —— 认证授权方案之Swagger加锁
- ADO.net中临时表DataTable的简单应用
- python excel详解_Python - excel 详解
- 常用linux网络配置命令
- Linux内核协议栈分析之网卡初始化——tcp/ip通信并不神秘(1)
- Linux 配置Tomcat
- 【独家】一种手机上实现屏幕录制成gif的方案
- VS-C++ 调试----调试信息输出至调试器(输出界面)
- Skype协议分析[0]_安装Skype
- matlab 张德风,Matlab图形界面图像的旋转、平移和缩放
- stm32学习笔记---STM32F4知识
- android音频系统(5):AudioService之音频焦点
- 3GPP TS 23501-g51 中英文对照 | 4.4.4 Location services
- MySQL插入数据的多种方式