1. 程式人生 > 其它 >inno setup打包多個exe、msi 自動檢測.net framework並安裝

inno setup打包多個exe、msi 自動檢測.net framework並安裝

  • 新建一個空白指令碼
    #define MyAppName "傳奇霸業"
	#define MyAppVersion "1.8.8.8"
	#define MyAppPublisher "霸業科技"
	#define MyAppURL "https://www.baye.com/"
	#define MyAppExeName "BY.exe"

	[Setup]
	; 注: AppId的值為單獨標識該應用程式。
	; 不要為其他安裝程式使用相同的AppId值。
	; (若要生成新的 GUID,可在選單中點選 "工具|生成 GUID"。)
	AppId={{C65D84B0-690E-470E-B828-9636F696B92E}
	AppName={#MyAppName}
	AppVersion={#MyAppVersion}
	;AppVerName={#MyAppName} {#MyAppVersion}
	AppPublisher={#MyAppPublisher}
	AppPublisherURL={#MyAppURL}
	AppSupportURL={#MyAppURL}
	AppUpdatesURL={#MyAppURL}
	DefaultDirName={autopf}\{#MyAppName}
	DisableProgramGroupPage=yes
	; [Icons] 的“quicklaunchicon”條目使用 {userappdata},而其 [Tasks] 條目具有適合 IsAdminInstallMode 的檢查。
	UsedUserAreasWarning=no
	; 移除以下行,以在管理安裝模式下執行(為所有使用者安裝)。
	PrivilegesRequired=admin
	OutputBaseFilename={#MyAppName}
	Compression=lzma
	SolidCompression=yes
	WizardStyle=modern

	[Languages]
	Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"
	Name: "english"; MessagesFile: "compiler:Languages\English.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
//元件安裝方式
	[Types]
	Name: win32; Description: Window 預設環境元件安裝
	Name: custom; Description:  自定義環境元件安裝; Flags: iscustom

	//元件列表選擇項
	[Components]
	Name: MainApp; Description: {#MyAppName}主程式; Types: win32 custom ; Flags: fixed
	Name: net; Description: 微軟官方 .Net Framework 4.6.1 執行庫; Types: win32 custom;Flags: fixed
	Name: BYCJ; Description: 霸業外掛; Types: win32 custom;Flags: fixed

	//原始檔所在目錄
	[Files]
	Source: "D:\Develop\cs\install\Release\BY.exe"; DestDir: "{app}"; Flags: ignoreversion;Components: MainApp
	Source: "D:\Develop\cs\install\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
	Source: "D:\Develop\cs\install\dotNetFx461_Full_x86_x64.exe"; DestDir: "{app}"; Flags: ignoreversion  ; Components: net; AfterInstall: net
	Source: "D:\Develop\cs\install\BYCJ.msi"; DestDir: "{app}"; Flags: ignoreversion  ; Components: BYCJ; AfterInstall: BYCJ
	; 注意: 不要在任何共享系統檔案上使用“Flags: ignoreversion”

	[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}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
   [CODE]
	const CDotNetSetupFile = 'dotNetFx461_Full_x86_x64.exe';
	function IsDotNetDetected(version: string; service: cardinal): boolean;
	// Indicates whether the specified version and service pack of the .NET Framework is installed.
	//
	// version -- Specify one of these strings for the required .NET Framework version:
	//    'v1.1'          .NET Framework 1.1
	//    'v2.0'          .NET Framework 2.0
	//    'v3.0'          .NET Framework 3.0
	//    'v3.5'          .NET Framework 3.5
	//    'v4\Client'     .NET Framework 4.0 Client Profile
	//    'v4\Full'       .NET Framework 4.0 Full Installation
	//    'v4.5'          .NET Framework 4.5
	//    'v4.5.1'        .NET Framework 4.5.1
	//    'v4.5.2'        .NET Framework 4.5.2
	//    'v4.6'          .NET Framework 4.6
	//    'v4.6.1'        .NET Framework 4.6.1
	//    'v4.6.2'        .NET Framework 4.6.2
	//    'v4.7'          .NET Framework 4.7
	//    'v4.7.1'        .NET Framework 4.7.1
	//    'v4.7.2'        .NET Framework 4.7.2
	//    'v4.8'          .NET Framework 4.8
	//
	// service -- Specify any non-negative integer for the required service pack level:
	//    0               No service packs required
	//    1, 2, etc.      Service pack 1, 2, etc. required
	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
	// from url https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
	'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; // 460805 On all other Windows operating systems (including other Windows 10 operating systems)
	'v4.7.1': versionRelease := 461308; // 461310 On all other Windows operating systems (including other Windows 10 operating systems)
	'v4.7.2': versionRelease := 461808; // 461814 On all Windows operating systems other than Windows 10 April 2018 Update and Windows Server, version 1803
	'v4.8'  : versionRelease := 528040; // On Windows 10 May 2019 Update and Windows 10 November 2019 Update: 528040; On Windows 10 May 2020 Update and Windows 10 October 2020 Update: 528372; On all other Windows operating systems (including other Windows 10 operating systems): 528049
	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 4.6.1
	procedure net;
	var RetCode:Integer;
	begin

	if not IsDotNetDetected('v4.6.1', 0) then begin
	ShellExec('open', ExpandConstant('{app}\'+CDotNetSetupFile), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, RetCode);
	if RetCode <> 0 then
	begin
	MsgBox(SysErrorMessage(RetCode) + ' 請關閉360等防毒軟體', mbInformation, MB_OK);
	end

	end
	end;

	//安裝BYCJ
	procedure BYCJ;
	var
	RetCode: integer;
	begin
	ShellExec('open', ExpandConstant('{app}\BYCJ.msi'), '', '', SW_SHOWNORMAL, ewWaitUntilTerminated, RetCode);
	if RetCode <> 0 then
	MsgBox(SysErrorMessage(RetCode), mbInformation, MB_OK);
	end;
  • 目錄結構
  • 解釋
    [Components]下的Flags欄位可以選擇
	**Flags**

	此引數是一組額外選項。可以通過用空格分隔它們來使用多個選項。支援以下選項:

	checkablealone

	指定當一個元件的子元件選中時,該元件是否可以選中。按預設值,如果沒有 `Components` 引數直接引用到該元件,未選中所有子元件將會使該元件變成未選中狀態。

	dontinheritcheck

	指定當該元件的上級被選中時,該元件應該不自動變成已選中狀態。這對頂層的元件不影響,且不能與 `exclusive` 標誌組合使用。

	exclusive

	告訴安裝程式這個元件與它的也使用 `exclusive` 標誌的同級元件是互相排斥的。

	fixed

	告訴安裝程式這個元件不能在安裝期間被終端使用者手動選擇或取消選擇。

	restart

	告訴安裝程式如果使用者安裝了這個元件,將詢問使用者重新啟動系統,不管它是不是需要(例如,因為 [Files] 區段條目用了 `restartreplace` 標誌)。有點象 [AlwaysRestart](topic_setup_alwaysrestart.htm),但不是每個元件。

	disablenouninstallwarning

	如果這個元件已經安裝在使用者機器中,重新安裝時在使用者取消這個元件選擇後,這條標誌告訴安裝程式不警告使用者不解除安裝該元件。

	考慮到你的元件的複雜性,你可以嘗試使用 [InstallDelete] 區段和該標誌為自動“解除安裝”取消選定的元件。

[Files]下的Source欄位替換成自己的目錄,Components欄位對應[Components]

  • 效果