Inno Setup打包问题汇总

默认主题优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#define MyAppId "{{1AC4D338-0D28-47E4-9FC7-18929EDDF90D}"
#define MyAppName "星火云鸽智慧课堂测试版"
#define MyAppDir "xhschool_test"
#define MyAppVersion "3.8.18"
#define MyAppPublisher "河南星火燎原软件科技有限公司"
#define MyAppURL "http://www.xhkjedu.com/"
#define MySourcePath "D:\Project\CSharp\schoolclient\bin\x86\Debug\"
#define MyIcoName "D:\Project\CSharp\schoolclient\bin\x86\Debug\favicon256.ico"
#define MyExcludes "\XHCLASS,\xhschool.exe.WebView2,\db,\temp,\Log,\wwwroot\school,\wwwroot\tongping,\app_service.xml,\app_service_test.xml"
#define MyAppExeName "xhschool.exe"
#define MyTargetPath "D:\程序打包\星火云鸽-智慧课堂-测试版\"

[Setup]
AppId={#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppDir}
DisableProgramGroupPage=yes
UsedUserAreasWarning=no
OutputDir={#MyTargetPath}
OutputBaseFilename="{#MyAppName}v{#MyAppVersion}"
SetupIconFile="{#MyIcoName}"
Compression=lzma
SolidCompression=yes
WizardStyle=modern

[Languages]
Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode

[Files]
Source: "D:\Tools\runtime\NDP452-KB2901954-Web.exe"; DestDir: "{app}\runtime";
Source: "{#MySourcePath}{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MySourcePath}*"; Excludes: "{#MyExcludes}";DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon

[Run]
Filename: "{app}\runtime\NDP452-KB2901954-Web.exe"; WorkingDir: {app}; Flags: skipifdoesntexist; StatusMsg: "Install .Net Framework ..."; Check: NeedInstallDotNet
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

[Code]
procedure CurPageChanged(CurPage: Integer);
begin
if CurPage=wpFinished then
Wizardform.WizardBitmapImage2.Visible := False;

Wizardform.FinishedHeadingLabel.Visible := True;
Wizardform.FinishedHeadingLabel.Width := WizardForm.ClientWidth - 100;
//Wizardform.FinishedHeadingLabel.Height := 40;
Wizardform.FinishedHeadingLabel.Top := 20;
Wizardform.FinishedHeadingLabel.Left := 50;
WizardForm.FinishedHeadingLabel.Color:=$ffffff;

Wizardform.FinishedLabel.Visible := True;
Wizardform.FinishedLabel.Width := WizardForm.ClientWidth - 100;
//Wizardform.FinishedLabel.Height := 100;
Wizardform.FinishedLabel.Top := Wizardform.FinishedHeadingLabel.Top+Wizardform.FinishedHeadingLabel.ClientHeight+20;
Wizardform.FinishedLabel.Left := 50;
WizardForm.FinishedLabel.Color:=$ffffff;

Wizardform.RunList.Width := WizardForm.ClientWidth - 100
Wizardform.RunList.Top := Wizardform.FinishedLabel.Top+Wizardform.FinishedLabel.ClientHeight+20;;
Wizardform.RunList.Left := 50;
WizardForm.RunList.Color:=$ffffff;
end;


function IsInstallDotNet(version: string; service: cardinal): boolean;
var
key, versionKey: string;
install, release, serviceCount, versionRelease: cardinal;
success: boolean;
begin
versionKey := version;
versionRelease := 0;

// .NET 1.1 and 2.0 embed release number in version key
if version = 'v1.1' then begin
versionKey := 'v1.1.4322';
end
else if version = 'v2.0' then begin
versionKey := 'v2.0.50727';
end

// .NET 4.5 and newer install as update to .NET 4.0 Full
else if Pos('v4.', version) = 1 then begin
versionKey := 'v4\Full';
case version of
'v4.5': versionRelease := 378389;
'v4.5.1': versionRelease := 378675; // 378758 on Windows 8 and older
'v4.5.2': versionRelease := 379893;
'v4.6': versionRelease := 393295; // 393297 on Windows 8.1 and older
'v4.6.1': versionRelease := 394254; // 394271 on Windows 8.1 and older
'v4.6.2': versionRelease := 394802; // 394806 on Windows 8.1 and older
'v4.7': versionRelease := 460798; // Windows 10
'v4.7.1': versionRelease := 461308; // Windows 10
'v4.7.2': versionRelease := 461808; // Windows 10
'v4.8' : versionRelease := 528040; // Windows 10
end;
end;

// installation key group for all .NET versions
key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + versionKey;

// .NET 3.0 uses value InstallSuccess in subkey Setup
if Pos('v3.0', version) = 1 then begin
success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install);
end else begin
success := RegQueryDWordValue(HKLM, key, 'Install', install);
end;

// .NET 4.0 and newer use value Servicing instead of SP
if Pos('v4', version) = 1 then begin
success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount);
end else begin
success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount);
end;

// .NET 4.5 and newer use additional value Release
if versionRelease > 0 then begin
success := success and RegQueryDWordValue(HKLM, key, 'Release', release);
success := success and (release >= versionRelease);
end;

result := success and (install = 1) and (serviceCount >= service);
end;

// 检查.Net是否安装
function NeedInstallDotNet : Boolean;
begin
if IsInstallDotNet('v4.5.2', 0) then
begin
Result := false;
end
else
begin
Result := true;
end
end;

引用DLL整体配置

整体配置大致如下,方便复制修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
; 该执行目录为 setup.iss 所在的目录,请注意拼接相对目录
#define MyAppId "{{1AC4D338-0D28-47E4-9FC7-18929EDDF90D}"
#define MyAppName "xhschool_test"
#define MyAppNameZh "星火云鸽智慧课堂测试版"
#define MyAppVersion "3.8.1"
#define MyAppPublisher "河南星火燎原"
#define MyAppURL "www.xhkjedu.com"
; 打包文件
#define MyAppExeName "xhschool.exe"
#define SourceMain "D:\Project\CSharp\schoolclient\bin\x86\Debug\xhschool.exe"
#define SourceFolder "D:\Project\CSharp\schoolclient\bin\x86\Debug\*"
#define SetupIconFilePath "D:\Project\CSharp\schoolclient\bin\x86\Debug\favicon256.ico"
#define MyExcludes "\XHCLASS,\db,\temp,\Log,\wwwroot\school,\wwwroot\tongping,app.config,app_service.xml,app_service_test.xml"
; 打包生成位置
#define OutputPath "D:\程序打包\星火云鸽-智慧课堂-测试版\"
#define OutputFileName "星火云鸽课堂-测试版"
; license文件
#define LicenseFilePath "..\setup_resources\license.txt"
; 美化资源文件
#define ResourcesPath "..\setup_resources\*"

[setup]
AppId={#MyAppId}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
LicenseFile={#LicenseFilePath}
OutputDir={#OutputPath}
OutputBaseFilename={#OutputFileName}v{#MyAppVersion}
SetupIconFile={#SetupIconFilePath}
Compression=lzma/normal
SolidCompression=yes
PrivilegesRequired=admin
Uninstallable=yes
UninstallDisplayName={#MyAppNameZh}
UninstallDisplayIcon={uninstallexe},0
DefaultGroupName={#MyAppNameZh}
Versioninfodescription={#MyAppName} Install
versioninfocopyright=Copyright(c) 2022
VersionInfoProductName={#MyAppName}
DisableReadyPage=yes
DisableProgramGroupPage=yes
DirExistsWarning=no
DisableDirPage=yes

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode

[Files]
Source: {#ResourcesPath}; DestDir: {tmp}; Flags: dontcopy solidbreak ; Attribs: hidden system
Source: {#SourceMain}; DestDir: "{app}"; Flags: ignoreversion
Source: {#SourceFolder};Excludes: "{#MyExcludes}";DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{autoprograms}\{#MyAppNameZh}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppNameZh}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
Name: "{group}\{#MyAppNameZh}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\卸载{#MyAppNameZh}"; Filename: "{uninstallexe}"

[Code]
#include "..\include\code.iss"

常见问题

请求的操作需要提升

Inno Setup CreateProcess failed;code 740 请求的操作需要提升

这是因为打包的程序默认需要以管理员身份运行

下载之后打开Resource Hacker,然后打开Inno Setup的安装目录,找到SetupLdr.e32文件,打开。

SetupLdr.e32在InnoSetup的根目录

找到Manifest下的文件打开

找到

1
<requestedExecutionLevel level="asInvoker"  uiAccess="false"/>

改为

1
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>

点击F5编译脚本,重新打包运行发现已经不再报错了。

生成快捷方式

新版本6.0.5已经没有该问题了

默认生成的打包的代码是不会生成桌面快捷方式的,所以要想生成桌面快捷方式

Tasks配置段中修改为如下:

1
2
3
[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone
Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone

其中Flags: checkablealone,会在桌面没有快捷方式时自动勾选创建桌面快捷方式

文件排除

https://jrsoftware.org/ishelp/index.php?topic=filessection

示例:

1
2
Source: "*"; Excludes: "*.~*"
Source: "*"; Excludes: "*.~*,\Temp\*"; Flags: recursesubdirs

忽略配置

1
2
3
[Files]
Source: "{#MySourcePath}{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "{#MySourcePath}*"; Excludes: "\db,\temp,\Log,\nginx\html\school,\nginx\html\tongping,app.config,app_service.xml";DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

注意

多个路径之间用,分割

控制面板卸载不显示图标

1
2
3
[Setup]
UninstallDisplayName={#MyAppName}
UninstallDisplayIcon={uninstallexe},0

删除旧的快捷方式

删除旧的快捷方式

1
2
[InstallDelete]
Type: files; Name: "{autodesktop}\星火智慧校园.lnk"

删除安装目录下的文件

1
2
3
[InstallDelete]
Type: files; Name: "{group}\User's Manual (PDF)"
Type: files; Name: "{app}\test.pdf"

其中

  • {autodesktop} 桌面
  • {app} 安装目录
  • {group} 开始菜单

清空图标缓存

如果我们打包时图标设置错了,就算更换了图标重新打包,桌面上的图标还是之前的,这是因为系统图标缓存导致,清空一下图标缓存就行了。

新建 清空图标缓存.bat,用管理员运行即可。

1
2
3
4
5
6
cd /d %userprofile%\AppData\Local\Microsoft\Windows\Explorer 
taskkill /f /im explorer.exe
attrib -h iconcache_*.db
del iconcache_*.db /a
start explorer
pause

常用技巧

脚本引用

1
#include ".\include\code.iss"

生命周期

inno setup基本的过程和函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//该过程在开始的时候改变向导或者向导页,不要指望使用InitializeSetup函数实现改变向导页的功能,因为InitializeSetup函数触发时向导窗口并不存在。
procedure InitializeWizard();

//该函数在安装程序初始化时调用,返回False 将中断安装,True则继续安装.
function InitializeSetup(): Boolean;

//该过程提供用户完成预安装和安装之后的任务,更多的是提供了安装过程中的状态。参数CurStep=ssInstall是在程序实际安装前,CurStep=ssPostInstall是实际安装完成后,而CurStep=ssDone是在一次成功的安装完成后、安装程序终止前(即点击finish按钮后执行)。
procedure CurStepChanged(CurStep: TSetupStep);

//当用户单击下一步按钮时调用。如果返回True,向导将移到下一页;如果返回False,它仍保留在当前页。
function NextButtonClick(CurPageID: Integer): Boolean;

//向导调用这个事件函数确定是否在所有页或不在一个特殊页 (用PageID 指定) 显示。如果返回True,将跳过该页;如果你返回False,该页被显示。注意: 这个事件函数不被wpWelcome、wpPreparing 和wpInstalling 页调用,还有安装程序已经确定要跳过的页也不会调用 (例如,没有包含组件安装程序的wpSelectComponents)。
function ShouldSkipPage(PageID: Integer): Boolean;

//在新向导页 (由CurPageID 指定) 显示后调用。
procedure CurPageChanged(CurPageID: Integer);

代码注释

1
2
3
;   实例 ——  ; 分号
// 实例 —— // 双斜杠 多用在code段
{ } 实例 —— {大括号 多用在code段}

注释符号均在英文输入法状态下输入

换行符号

在 [Messages] 换行符号为%n
在 MsgBox 中换行符号为 #13#10 ,#13 为回车字符

颜色代码

(1)一个值形如 $bbggrr, 这里的 rr, gg 和 bb 指定了两位的亮度值(以十六进制表示)分别为红色,绿色和蓝色。
(2)预定义的颜色名称:

clBlack(黑色),clMaroon(暗红),clGreen(绿色),clOlive(橄榄绿),
clNavy(深蓝),clPurple(紫色),clTeal(深青),clGray(灰色),
clSilver(浅灰),clRed(红色),clLime(浅绿),clYellow(黄色),
clBlue(蓝色),clFuchsia(紫红),clAqua(青绿),clWhite(白色)。

image-20220923124152656

安装

CurStepChanged所对应的全部状态:3种

  • CurStep=ssInstall –是在程序实际安装前(所有配置都准备好了)*

  • CurStep=ssPostInstall –是实际安装完成后*

  • CurStep=ssDone–是在一次成功的安装完成后、安装程序终止前(即点击*finish按钮后执行)

这些状态可以通过InnoSetup自带的过程(一种跟函数差不多的东西)来判断,然后执行一些自定义的动作:

用法如下:

1
2
3
4
5
6
7
procedure CurStepChanged(CurStep: TSetupStep);
begin
if (CurStep=ssInstall) then
begin
//你要执行的代码
end;
end;

卸载

CurUninstallStep 所对应的所有状态 4种

  • CurStep=usAppMutexCheck 在卸载前判断是否已经运行了实例

  • CurStep=usUninstall 卸载前的准备

  • CurStep=usPostUninstall 卸载完成后,

  • CurStep=usDone 卸载完成后,卸载程序终止前,也是点击finish之后执行的

同理:卸载的时候也有对应的过程来处理

1
2
3
4
5
6
7
8
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);

begin
if (CurUnintallStep=usInstall) then
begin
//你要执行的代码
end;
end;

向导

0、 向导页面

Innosetup的预定义向导页(就是安装时让我们点下一步的那些页面)

3.1.wpWelcome –欢迎页面

3.2. wpLicense –协议页面

3.3. wpPassword –密码页面

3.4. wpInfoBefore

3.5. wpUserInfo

3.6. wpSelectDir –选择目录页面

3.7. wpSelectComponents –选择组件页面

3.8. wpSelectProgramGroup –选择程序组页面

3.9. wpSelectTasks

3.10. wpReady

3.11. wpPreparing

3.12. wpInstalling –估计是安装中的进度条页面

3.13. wpInfoAfter

3.14. wpFinished –finish页面

向导变更时执行

1
2
3
4
5
6
[Code]
procedure CurPageChanged(CurPage: Integer);
begin
if CurPage=wpFinished then
Wizardform.WizardBitmapImage.Visible := False;
end;

1 、如何让协议许可页面默认选中我同意按钮

1
2
3
4
5
[code]
procedure InitializeWizard();
begin
WizardForm.LICENSEACCEPTEDRADIO.Checked := true;
end;

2、自定义安装程序右上角图片大小

1
2
3
4
5
6
7
8
[code]
procedure InitializeWizard();
begin
WizardForm.WizardSmallBitmapImage.width:=150; //设置页眉图片的大小
WizardForm.WizardSmallBitmapImage.left:=WizardForm.width-150; //设置左边页眉留出的空隙
WizardForm.PAGENAMELABEL.width:=0; //设置标题文字显示的大小
WizardForm.PAGEDESCRIPTIONLABEL.width:=0; //设置标题文字显示的大小
end;

或者

1
2
3
4
5
6
7
8
9
//自定义安装向导小图片
[code]
procedure InitializeWizard();
begin
Wizardform.WizardSmallBitmapImage.left:= WizardForm.width-164; //自定义安装向导小图片显示位置
WizardForm.WizardSmallBitmapImage.width:=164; //自定义安装向导小图片宽度
Wizardform.PageNameLabel.width:= 495 - 164 -36; //这儿必须定义,数值根据图片宽度更改,显示软件名称的位置
Wizardform.PageDescriptionLabel.width:= 495 - 164 -42; //显示页面信息的位置
end;

3、自定义BeveledLabel显示

1
2
3
4
5
6
7
8
[code]
procedure InitializeWizard();
begin
WizardForm.BeveledLabel.Enabled:=true; //允许显示
WizardForm.BeveledLabel.Font.Color:=$00058451;; //显示颜色
WizardForm.BeveledLabel.Font.Style := WizardForm.BeveledLabel.Font.Style + [fsBold]; //显示字体
WizardForm.BeveledLabel.Left:=5; //显示位置
end;

4、自定义安装向导图片

1
2
3
4
5
6
7
[code]
procedure InitializeWizard();
begin
Wizardform.WELCOMELABEL1.left:= 18; //自定义欢迎页面标题1显示位置
Wizardform.WELCOMELABEL2.left:= 18; //自定义欢迎页面标题2显示位置
Wizardform.WizardBitmapImage.left:= WizardForm.width-164 //自定义安装向导图片显示位置(显示大小,此处为居右显示)
end;

5、显示出组件选择框

1
2
3
4
5
[Types]
Name: full; Description: 推荐
Name: default; Description: 典型
Name: custom; Description: 自定义; Flags: iscustom
;告诉安装程序这个类型是自定义类型。必须定义iscustom这个参数,才能显示出组件选择框

6、定义[Messages]的颜色

1
2
3
4
5
6
[code]
procedure InitializeWizard();
begin
WizardForm.BeveledLabel.Enabled:= True;
WizardForm.BeveledLabel.Font.Color:= clblue;
end;

7、不显示一些特定的安装界面

1
2
3
4
5
6
[code]
function ShouldSkipPage(PageID: Integer): Boolean;
begin
if PageID=wpReady then
result := true;
end;

wpReady 是准备安装界面
PageID查询 INNO帮助中的 Pascal 脚本: 事件函数常量
预定义向导页 CurPageID 值
wpWelcome, wpLicense, wpPassword, wpInfoBefore, wpUserInfo, wpSelectDir, wpSelectComponents, wpSelectProgramGroup, wpSelectTasks, wpReady, wpPreparing, wpInstalling, wpInfoAfter, wpFinished

8、在运行卸载程序前显示弹出式消息

1
2
3
4
5
6
7
8
[code]
function InitializeUninstall(): Boolean;
begin
if MsgBox('', mbConfirmation, MB_YESNO) = IDYES then
result:=true
else
result:=false;
end;

9、安装、卸载时判断是否程序正在运行,卸载完成时自动打开网页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[code]
var
ErrorCode: Integer;
IsRunning: Integer;
// 安装时判断客户端是否正在运行
function InitializeSetup(): Boolean;
begin
Result :=true; //安装程序继续
IsRunning:=FindWindowByWindowName('腾讯视频');
while IsRunning<>0 do
begin
if Msgbox('安装程序检测到客户端正在运行。' #13#13 '您必须先关闭它然后单击“是”继续安装,或按“否”退出!', mbConfirmation, MB_YESNO) = idNO then
begin
Result :=false; //安装程序退出
IsRunning :=0;
end else begin
Result :=true; //安装程序继续
IsRunning:=FindWindowByWindowName('腾讯视频');
end;
end;
end;
// 卸载时判断客户端是否正在运行
function InitializeUninstall(): Boolean;
begin
Result :=true; //安装程序继续
IsRunning:=FindWindowByWindowName('腾讯视频');
while IsRunning<>0 do
begin

if Msgbox('安装程序检测到客户端正在运行。' #13#13 '您必须先关闭它然后单击“是”继续安装,或按“否”退出!', mbConfirmation, MB_YESNO) = idNO then
begin
Result :=false; //安装程序退出
IsRunning :=0;
end else begin
Result :=true; //安装程序继续
IsRunning:=FindWindowByWindowName('腾讯视频');
end;
end;
end;
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
case CurUninstallStep of
usUninstall:
begin // 开始卸载
end;
usPostUninstall:
begin // 卸载完成
// MsgBox('CurUninstallStepChanged:' #13#13 'Uninstall just finished.', mbInformation, MB_OK);
ShellExec('open', 'http://www.psvmc.cn', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
end;
end;

10、 删除文件和删除文件夹

1
2
3
4
//删除文件  用 DeleteFile 只能删除一个文件,不能使用通配符来删除多个文件
DeleteFile(ExpandConstant('{app}\abc.exe'));
//删除所有文件及文件夹
DelTree(ExpandConstant('{app}'), True, True, False);

11、BorderStyle

1
TFormBorderStyle = (bsNone, bsSingle, bsSizeable, bsDialog, bsToolWindow, bsSizeToolWin);

无边界式(bsNone) ,单边固定式(bsSingle),双边可变式(bsSizeable),对话框式(bsDialog)

12、if else

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function NextButtonClick(CurPageID: Integer): Boolean;
var
ResultCode: Integer;
begin
Result := True;
if (CurPageID = wpSelectDir) then
begin
MsgBox('AAAA', mbInformation, MB_OK);
end
else
begin
MsgBox('BBBB', mbInformation, MB_OK);
end;
end;

13、安装结束界面增加“设为首页”选项

1
2
3
4
[Tasks]
Name: changestartpage; Description: "设置百度默认主页"
[Registry]
Root: HKCU; Subkey: "Software\Microsoft\Internet Explorer\Main"; ValueType: string; ValueName: "Start Page"; ValueData: "http://www.baidu.com"; tasks: changestartpage

14、添加“关于”和网站链接按钮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
[Code]
procedure URLLabelOnClick(Sender: TObject);
var
ErrorCode: Integer;
begin
ShellExec('open', 'http://www.psvmc.cn', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
procedure AboutButtonOnClick(Sender: TObject);
begin
MsgBox(#13 '本软件由码客说制作!' #13#13 '版权所有 (C) 码客说工作室', mbInformation, MB_OK);
end;
var
AboutButton, CancelButton: TButton;
URLLabel: TNewStaticText;
procedure InitializeWizard();
begin
{ Create the pages }
WizardForm.PAGENAMELABEL.Font.Color:= clred;
WizardForm.PAGEDESCRIPTIONLABEL.Font.Color:= clBlue;
WizardForm.WELCOMELABEL1.Font.Color:= clGreen;
WizardForm.WELCOMELABEL2.Font.Color:= clblack;
CancelButton := WizardForm.CancelButton;
AboutButton := TButton.Create(WizardForm);
AboutButton.Left := WizardForm.ClientWidth - CancelButton.Left - CancelButton.Width;
AboutButton.Top := CancelButton.Top;
AboutButton.Width := CancelButton.Width;
AboutButton.Height := CancelButton.Height;
AboutButton.Caption := '&About';
AboutButton.OnClick := @AboutButtonOnClick;
AboutButton.Parent := WizardForm;
URLLabel := TNewStaticText.Create(WizardForm);
URLLabel.Caption := '码客说';
URLLabel.Cursor := crHand;
URLLabel.OnClick := @URLLabelOnClick;
URLLabel.Parent := WizardForm;
{ Alter Font *after* setting Parent so the correct defaults are inherited first }
URLLabel.Font.Style := URLLabel.Font.Style + [fsUnderline];
URLLabel.Font.Color := clBlue;
URLLabel.Top := AboutButton.Top + AboutButton.Height - URLLabel.Height - 2;
URLLabel.Left := AboutButton.Left + AboutButton.Width + ScaleX(20);
end;

15、去掉安装程序左上角“关于安装程序”的代码

1
2
3
4
5
6
7
8
9
10
procedure InitializeWizard();
begin
WizardForm.BorderIcons:= [biMinimize];
end;

procedure CurPageChanged(CurPage: Integer);
begin
if CurPage=wpWelcome then
WizardForm.BorderIcons:= [biSystemMenu, biMinimize];
end;

或者

1
2
3
4
procedure InitializeWizard();
begin
WizardForm.BORDERICONS := [biHelp, biSystemMenu, biMinimize];
end;

16、自定义BeveledLabel文字

1
2
[Messages]
BeveledLabel=码客说

17、自定义安装程序界面左上角“安装”文字

1
2
3
[message]
SetupAppTitle=需要的字
SetupWindowTitle=需要的字

18、自定义安装程序版本号

1
2
VersionInfoVersion=1.1
VersionInfoTextVersion=1.1

默认主题修改方法

首先我们看一下属性 方便修改页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
TWizardForm = class(TSetupForm)
property CancelButton: TNewButton; read;
property NextButton: TNewButton; read;
property BackButton: TNewButton; read;
property OuterNotebook: TNotebook; read;
property InnerNotebook: TNotebook; read;
property WelcomePage: TNewNotebookPage; read;
property InnerPage: TNewNotebookPage; read;
property FinishedPage: TNewNotebookPage; read;
property LicensePage: TNewNotebookPage; read;
property PasswordPage: TNewNotebookPage; read;
property InfoBeforePage: TNewNotebookPage; read;
property UserInfoPage: TNewNotebookPage; read;
property SelectDirPage: TNewNotebookPage; read;
property SelectComponentsPage: TNewNotebookPage; read;
property SelectProgramGroupPage: TNewNotebookPage; read;
property SelectTasksPage: TNewNotebookPage; read;
property ReadyPage: TNewNotebookPage; read;
property PreparingPage: TNewNotebookPage; read;
property InstallingPage: TNewNotebookPage; read;
property InfoAfterPage: TNewNotebookPage; read;
property DiskSpaceLabel: TNewStaticText; read;
property DirEdit: TEdit; read;
property GroupEdit: TNewEdit; read;
property NoIconsCheck: TNewCheckBox; read;
property PasswordLabel: TNewStaticText; read;
property PasswordEdit: TPasswordEdit; read;
property PasswordEditLabel: TNewStaticText; read;
property ReadyMemo: TNewMemo; read;
property TypesCombo: TNewComboBox; read;
property Bevel: TBevel; read;
property WizardBitmapImage: TBitmapImage; read;
property WelcomeLabel1: TNewStaticText; read;
property InfoBeforeMemo: TRichEditViewer; read;
property InfoBeforeClickLabel: TNewStaticText; read;
property MainPanel: TPanel; read;
property Bevel1: TBevel; read;
property PageNameLabel: TNewStaticText; read;
property PageDescriptionLabel: TNewStaticText; read;
property WizardSmallBitmapImage: TBitmapImage; read;
property ReadyLabel: TNewStaticText; read;
property FinishedLabel: TNewStaticText; read;
property YesRadio: TNewRadioButton; read;
property NoRadio: TNewRadioButton; read;
property WizardBitmapImage2: TBitmapImage; read;
property WelcomeLabel2: TNewStaticText; read;
property LicenseLabel1: TNewStaticText; read;
property LicenseMemo: TRichEditViewer; read;
property InfoAfterMemo: TRichEditViewer; read;
property InfoAfterClickLabel: TNewStaticText; read;
property ComponentsList: TNewCheckListBox; read;
property ComponentsDiskSpaceLabel: TNewStaticText; read;
property BeveledLabel: TNewStaticText; read;
property StatusLabel: TNewStaticText; read;
property FilenameLabel: TNewStaticText; read;
property ProgressGauge: TNewProgressBar; read;
property SelectDirLabel: TNewStaticText; read;
property SelectStartMenuFolderLabel: TNewStaticText; read;
property SelectComponentsLabel: TNewStaticText; read;
property SelectTasksLabel: TNewStaticText; read;
property LicenseAcceptedRadio: TNewRadioButton; read;
property LicenseNotAcceptedRadio: TNewRadioButton; read;
property UserInfoNameLabel: TNewStaticText; read;
property UserInfoNameEdit: TNewEdit; read;
property UserInfoOrgLabel: TNewStaticText; read;
property UserInfoOrgEdit: TNewEdit; read;
property PreparingErrorBitmapImage: TBitmapImage; read;
property PreparingLabel: TNewStaticText; read;
property FinishedHeadingLabel: TNewStaticText; read;
property UserInfoSerialLabel: TNewStaticText; read;
property UserInfoSerialEdit: TNewEdit; read;
property TasksList: TNewCheckListBox; read;
property RunList: TNewCheckListBox; read;
property DirBrowseButton: TNewButton; read;
property GroupBrowseButton: TNewButton; read;
property SelectDirBitmapImage: TBitmapImage; read;
property SelectGroupBitmapImage: TBitmapImage; read;
property SelectDirBrowseLabel: TNewStaticText; read;
property SelectStartMenuFolderBrowseLabel: TNewStaticText; read;
property PreparingYesRadio: TNewRadioButton; read;
property PreparingNoRadio: TNewRadioButton; read;
property PreparingMemo: TNewMemo; read;
property CurPageID: Integer; read;
function AdjustLabelHeight(ALabel: TNewStaticText): Integer;
procedure IncTopDecHeight(AControl: TControl; Amount: Integer);
property PrevAppDir: String; read;
end;

页面组件图

组件树

注意

6.0.5版本已经去掉了完成页面的图片,不需要添加下面的配置

去除默认完成页面的图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[Code]
procedure CurPageChanged(CurPage: Integer);
begin
if CurPage=wpFinished then
Wizardform.WizardBitmapImage2.Visible := False;

Wizardform.FinishedHeadingLabel.Visible := True;
Wizardform.FinishedHeadingLabel.Width := WizardForm.ClientWidth - 100;
//Wizardform.FinishedHeadingLabel.Height := 40;
Wizardform.FinishedHeadingLabel.Top := 20;
Wizardform.FinishedHeadingLabel.Left := 50;
WizardForm.FinishedHeadingLabel.Color:=$ffffff;

Wizardform.FinishedLabel.Visible := True;
Wizardform.FinishedLabel.Width := WizardForm.ClientWidth - 100;
//Wizardform.FinishedLabel.Height := 100;
Wizardform.FinishedLabel.Top := Wizardform.FinishedHeadingLabel.Top+Wizardform.FinishedHeadingLabel.ClientHeight+20;
Wizardform.FinishedLabel.Left := 50;
WizardForm.FinishedLabel.Color:=$ffffff;

Wizardform.RunList.Width := WizardForm.ClientWidth - 100
Wizardform.RunList.Top := Wizardform.FinishedLabel.Top+Wizardform.FinishedLabel.ClientHeight+20;;
Wizardform.RunList.Left := 50;
WizardForm.RunList.Color:=$ffffff;
end;

注意

组件的高度不能设置为固定的值,在高分辨率的屏幕上会显示异常。