Inno Setup 安装自动检测 .NET 环境安装解决方案

Inno Setup 安装自动检测 .NET 环境安装解决方案大眼仔旭(www.dayanzai.me)发布。现在有越来越多的程序是基于 .Net Framework 环境开发的,而这类程序多数依赖 .NET 运行环境。作为在打包分发软件的时候,通过使用 Inno Setup 可以在安装包运行时自动检测电脑上是否安装 .NET 环境。毕竟有些用户是没有安装 .NET 环境,如果直接安装发现无法打开应用程序,就会给用户造成非常不可靠的感觉。

以下的检测方法是由 kybso 发布在 GitHub 社区并共享源代码,这里作一些解释引用:

添加 .NET 安装基本的函数及辅助方法:
在 [Setup] 段下引用几个辅助文件:

1
2
3
4
5
6
7
//import dependency for .net
//isxdl operation
#include "dependency/isxdl.iss"
//;TYPES AND VARIABLES
#include "dependency/products.pas"
//about .net versions
#include "dependency/dotnetfxversion.iss"

isxdl.iss — 引用了 isxdl.dll 并添加文件下载、安装函数
products.pas — 版本的安装过程
dotnetfxversion.iss — .NET 版本信息等相关函数

添加 .NET 版本引用及启动执行:

以 .net4.5.iss 为例,添加了版本的信息及下载地址等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[CustomMessages]
dotnetfx45_title=.NET Framework 4.5.2
dotnetfx45_size=68 MB

[Code]
const
    dotnetfx45_url = 'http://download.microsoft.com/download/B/4/1/B4119C11-0423-477B-80EE-7A474314B347/NDP452-KB2901954-Web.exe';

procedure dotnetfx45(minVersion: Integer);
begin
    if (dotnetfxspversion(NetFx4x, '') < minVersion) then
        AddProduct('dotnetfx45.exe',
            '/lcid ' + CustomMessage('lcid') + ' /passive /norestart',
            CustomMessage('dotnetfx45_title'),
            CustomMessage('dotnetfx45_size'),
            dotnetfx45_url,
            false, false, false);
end;

在 [Setup] 中添加要依赖的 .NET 版本:

1
2
3
4
[Setup]
//add .net4.5
#include "dependency/.net versions installation/dotnetfx45.iss"
#include "dependency/.net versions installation/dotnetfx46.iss"

添加自定义语言选项,如果安装包需要支持多语种,可以额外引用其它语言项进行选择。

1
2
3
4
5
6
7
8
9
10
11
12
13
[CustomMessages]
DependenciesDir=MyProgramDependencies
WindowsServicePack=Windows %1 Service Pack %2
//固定英文安装语言
lcid=1033
depdownload_memo_title=Download dependencies
depinstall_memo_title=Install dependencies
depinstall_title=Installing dependencies
depinstall_description=Please wait while Setup installs dependencies on your computer.
depinstall_status=Installing %1...
depinstall_missing=%1 must be installed before setup can continue. Please install %1 and run Setup again.
depinstall_error=An error occured while installing the dependencies. Please restart the computer and run the setup again or install the following dependencies manually:%n
isxdl_langfile=""

安装 .NET 版本:

1
2
3
4
5
6
7
[Code]
function InitializeSetup(): Boolean;
begin
    dotnetfx45(50); // install if version < 4.5.0
    dotnetfx46(60); // install if version < 4.6.0
    Result := true;
end;

Inno Setup 打包 .Net Framework 到安装包方式脚本:

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
; 脚本由 Inno Setup 脚本向导 生成!
; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档!

#define MyAppName "MyApp"
#define MyAppVersion "1.0"
#define IncludeFramework true
#define IsExternal ""
#define MyAppPublisher "App"
#define MyAppURL "http://www.MyApp.cn"
#define MyAppExeName "MyApp.exe"

[Setup]
; 注: AppId的值为单独标识该应用程序。
; 不要为其他安装程序使用相同的AppId值。
; (生成新的GUID,点击 工具|在IDE中生成GUID。)
AppId={{B0C52F2E-939F-4CE2-89F3-2F0677584526}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}/{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=E:/step
Compression=lzma
SolidCompression=yes
#if IncludeFramework
  OutputBaseFilename=setup_FW
#else
  OutputBaseFilename=Setup
#endif

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: "E:/MyApp/MyApp.exe"; DestDir: "{app}"; Flags: ignoreversion {#IsExternal}
#if IncludeFramework
Source: "D:/开发/dotNetFx40_Full_x86_x64.exe"; DestDir: "{tmp}"; Flags: ignoreversion {#IsExternal}; Check: NeedsFramework
#endif
; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion

[Icons]
Name: "{group}/{#MyAppName}"; Filename: "{app}/{#MyAppExeName}"
Name: "{commondesktop}/{#MyAppName}"; Filename: "{app}/{#MyAppExeName}"; Tasks: desktopicon


[Run]
#if IncludeFramework
Filename: {tmp}/dotNetFx40_Full_x86_x64.exe; Parameters: "/q:a /c:""install /l /q"""; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: "Installing .NET Framework if needed"
#endif
Filename: {win}/Microsoft.NET/Framework/v4.0.30319/CasPol.exe; Parameters: "-q -machine -remgroup ""{#MyAppName}"""; WorkingDir: {tmp}; Flags: skipifdoesntexist runhidden; StatusMsg: "Setting Program Access Permissions..."
Filename: {win}/Microsoft.NET/Framework/v4.0.30319/CasPol.exe; Parameters: "-q -machine -addgroup 1.2 -url ""file://{app}/*"" FullTrust -name ""{#MyAppName}"""; WorkingDir: {tmp}; Flags: skipifdoesntexist runhidden; StatusMsg: "Setting Program Access Permissions..."

[UninstallRun]
Filename: {win}/Microsoft.NET/Framework/v4.0.30319/CasPol.exe; Parameters: "-q -machine -remgroup ""{#MyAppName}"""; Flags: skipifdoesntexist runhidden;

[code]
// Indicates whether .NET Framework 2.0 is installed.
function IsDotNET40Detected(): boolean;
var
    success: boolean;
    install: cardinal;
begin
    success := RegQueryDWordValue(HKLM, 'SOFTWARE/Microsoft/NET Framework Setup/NDP/v4/Full', 'Install', install);
     //success := RegQueryDWordValue(HKLM, 'SOFTWARE/Microsoft/NET Framework Setup/NDP/v2.0.50727', 'Install', install);
    Result :=  success and (install = 1);
end;

//RETURNS OPPOSITE OF IsDotNet20Detected FUNCTION
//Remember this method from the Files section above
function NeedsFramework(): Boolean;
begin
  Result := (IsDotNET40Detected = false);
end;



function GetCustomSetupExitCode(): Integer;
begin
  if (IsDotNET40Detected = false) then
    begin
      MsgBox('.NET Framework 未能正确安装!',mbError, MB_OK);
      result := -1
    end
end;

//卸载程序
function InitializeUninstall(): Boolean;
begin
  Result := MsgBox('卸载程序:' #13#13 '你真的要卸载该程序?', mbConfirmation, MB_YESNO) = idYes;
  //if Result = False then
  //  MsgBox('InitializeUninstall:' #13#13 'Ok, bye bye.', mbInformation, MB_OK);
end;


procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
  ErrorCode: Integer;
begin
  case CurUninstallStep of
    usUninstall:
      begin
        //MsgBox('卸载程序:' #13#13 '正在卸载...', mbInformation, MB_OK)
        // ...insert code to perform pre-uninstall tasks here...
      end;
    usPostUninstall:
      begin
        //MsgBox('卸载程序:' #13#13 '卸载完成.', mbInformation, MB_OK);
        // ...insert code to perform post-uninstall tasks here...
        ShellExec('open', 'http://www.asiafinance.cn', '', '', SW_SHOW, ewNoWait, ErrorCode)

      end;
  end;
end;

Inno Setup 在线下载并安装 .NetFramwork:

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
; 脚本由 Inno Setup 脚本向导 生成!
; 有关创建 Inno Setup 脚本文件的详细资料请查阅帮助文档!

#define MyAppName "MyApp"
#define MyAppVersion "1.0"
#define MyAppPublisher "MyApp"
#define MyAppURL "http://www.MyApp.cn/"
#define MyAppExeName "MyApp.exe"

[Setup]
; 注: AppId的值为单独标识该应用程序。
; 不要为其他安装程序使用相同的AppId值。
; (生成新的GUID,点击 工具|在IDE中生成GUID。)
AppId={{769CC8AC-50C3-4776-95F5-A1ABF15A38F4}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}/{#MyAppName}
DefaultGroupName={#MyAppName}
OutputDir=E:/step
OutputBaseFilename=MyApp
Compression=lzma
SolidCompression=yes

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

[Tasks]
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1

[Files]
Source: C:/Program Files/ISTool/isxdl.dll; Flags: dontcopy ;
Source: "E:/MyApp/MyApp.exe"; DestDir: "{app}"; Flags: ignoreversion
; 注意: 不要在任何共享系统文件上使用“Flags: ignoreversion

[Icons]
Name: "{group}/{#MyAppName}"; Filename: "{app}/{#MyAppExeName}"
Name: "{group}/{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{commondesktop}/{#MyAppName}"; Filename: "{app}/{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{app}/{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, "&", "&&")}}"; Flags: nowait postinstall skipifsilent

[Code]
var
  dotnetRedistPath: string;
  downloadNeeded: boolean;
  dotNetNeeded: boolean;
  memoDependenciesNeeded: string;

procedure isxdl_AddFile(URL, Filename: PChar);
external 'isxdl_AddFile@files:isxdl.dll stdcall';
function isxdl_DownloadFiles(hWnd: Integer): Integer;
external 'isxdl_DownloadFiles@files:isxdl.dll stdcall';
function isxdl_SetOption(Option, Value: PChar): Integer;
external 'isxdl_SetOption@files:isxdl.dll stdcall';
const
  dotnetRedistURL = 'http://www.microsoft.com/downloads/info.aspx?na=41&srcfamilyid=e5ad0459-cbcc-4b4f-97b6-fb17111cf544&srcdisplaylang=en&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f2%2f562A10F9-C9F4-4313-A044-9C94E0A8FAC8%2fdotNetFx40_Client_x86_x64.exe';

//this url was correct at time of publication for .net 3.5 you may need to change this in future.
  // local system for testing…
  // dotnetRedistURL = ‘http://192.168.1.1/dotnetfx35.exe’;

function InitializeSetup(): Boolean;

begin
  Result := true;
  dotNetNeeded := false;

  // Check for required netfx installation
  if (not RegKeyExists(HKLM, 'Software/Microsoft/.NETFramework/policy/v4.0')) then begin
    dotNetNeeded := true;
    if (not IsAdminLoggedOn()) then begin
      MsgBox('GasSoft needs the Microsoft .NET Framework to be installed by an Administrator', mbInformation, MB_OK);
      Result := false;
    end else begin
      memoDependenciesNeeded := memoDependenciesNeeded + '.NET Framework' #13;
      dotnetRedistPath := ExpandConstant('{src}/dotnetfx35.exe');
      if not FileExists(dotnetRedistPath) then begin
        dotnetRedistPath := ExpandConstant('{tmp}/dotnetfx35.exe');
        if not FileExists(dotnetRedistPath) then begin
          isxdl_AddFile(dotnetRedistURL, dotnetRedistPath);
          downloadNeeded := true;
        end;
      end;
      SetIniString('install', 'dotnetRedist', dotnetRedistPath, ExpandConstant('{tmp}/dep.ini'));
    end;
  end;
end;

function NextButtonClick(CurPage: Integer): Boolean;
var
  hWnd: Integer;
  ResultCode: Integer;

begin
  Result := true;

  if CurPage = wpReady then begin
          if (not RegKeyExists(HKLM, 'Software/Microsoft/.NETFramework/policy/v4.0')) then begin
    hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));

    // don’t try to init isxdl if it’s not needed because it will error on < ie 3
    if downloadNeeded then begin

      isxdl_SetOption('label', '正在下载 Microsoft .NET Framework');
      isxdl_SetOption('des-c-r-i-p-tion', '您还未安装Microsoft .NET Framework. 请您耐心等待,下载完成后会安装到您的的计算机中。');
      if isxdl_DownloadFiles(hWnd) = 0 then Result := false;
    end;
    if (Result = true) and (dotNetNeeded = true) then begin
      if Exec(ExpandConstant(dotnetRedistPath), '/qb', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
         // handle success if necessary; ResultCode contains the exit code
         if not (ResultCode = 0) then begin
           Result := false;
         end;
      end else begin
         // handle failure if necessary; ResultCode contains the error code
         Result := false;
      end;
      end;
    end;

  end;
end;

以上的代码片段您可以根据自己的需要进行组合使用。

官方主页

资源:1696.rar
解压密码:www.dayanzai.me
转载请保留出处,谢谢合作~
点击下载(提取码:742b)
点击下载
点击下载
点击下载(提取码:697v)

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/courses/141643.html

(0)
上一篇 2021年9月6日 10:22
下一篇 2021年9月6日 10:22

相关推荐

发表回复

登录后才能评论