常见环境
从 Visual Studio .NET 到 Visual Studio 2013,C++ 编译器和工具的每个主版本都包含一个新的独立版本的 Microsoft C 运行 (CRT) 库。 CRT 的这些独立版本彼此独立,并在不同程度上彼此不兼容。 例如,Visual Studio 2012 使用的 CRT 库是第 11 版,名为 msvcr110.dll,而 Visual Studio 2013 使用的 CRT 是第 12 版,名为 msvcr120.dll。 从 Visual Studio 2015 开始,不再是这样。 Visual Studio 2015 及更高版本的 Visual Studio 都使用一个通用 CRT。
通用 CRT (UCRT) 是 Microsoft Windows 操作系统组件。 它包含在 Windows 10 和 Windows Server 2016 或更高版本中作为操作系统的一部分。 对于仍处于扩展支持的较早版本的操作系统,可使用 Windows 更新来提供 UCRT。 支持通用 CRT 本地部署,但有一些限制。
C++下载
32位下载地址: https://aka.ms/vs/16/release/vc_redist.x86.exe
.NET Framework下载
https://dotnet.microsoft.com/download/visual-studio-sdks
.NET Framework 4.5.2离线安装包: https://www.microsoft.com/en-us/download/details.aspx?id=42642
本地安装
下载文件放在打包的代码同级
runtime
目录下
加载文件
[Files]
Source: ".\runtime\VC_redist.x86.exe"; DestDir: "{tmp}"; Check: NeedInstallVC
运行时安装
[Run]
Filename: "{tmp}\VC_redist.x86.exe"; Parameters: /q; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: "Install Microsoft Visual C++ Runtime ..."; Check: NeedInstallVC
检测是否需要安装
[Code]
var vcRuntimeMissing: Boolean;
function NeedInstallVC(): Boolean;
begin
Result := vcRuntimeMissing;
function InitializeSetup(): Boolean;
begin
// 这里,不同版本运行环境对应的GUID不同
if RegValueExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7D75664A-6C04-424C-82A1-EE88913E5F16}', 'Version')
or RegValueExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{01FAEC41-B3BC-44F4-B185-5E8475AEB855}', 'Version')
begin
vcRuntimeMissing := false;
begin
vcRuntimeMissing := true;
result := true;
end;
检测运行库是否安装是通过注册表进行检测的,其中最后一段字符是运行库的产品ID,每个版本的产品ID都不一样
解压下载后的
VC_redist.x86.exe
文件,找到名称为
0
的文件用文本文档打开,
搜索
ProductCode
会搜索出两个,其中一个是Minimum Runtime,一个是Additional Runtime
RollbackLogPathVariable="WixBundleRollbackLog_vcRuntimeMinimum_x86" ProductCode="{7D75664A-6C04-424C-82A1-EE88913E5F16}"
和
RollbackLogPathVariable="WixBundleRollbackLog_vcRuntimeAdditional_x86" ProductCode="{01FAEC41-B3BC-44F4-B185-5E8475AEB855}"
我们用到的是
WixBundleRollbackLog_vcRuntimeAdditional_x86
,在注册表中搜索对应产品ID即可
在线下载
检测C++安装环境
[Code]
function InitializeSetup: Boolean;
var Path:string;
ResultCode: Integer;
begin
if RegValueExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{01FAEC41-B3BC-44F4-B185-5E8475AEB855}', 'Version') then
begin
Result := true;
begin
if MsgBox('系统检测到您没有安装VC++环境,是否立刻下载并安装?', mbConfirmation, MB_YESNO) = idYes then
begin
Path := ExpandConstant('{pf}/Internet Explorer/iexplore.exe');
Exec(Path, 'https://xhkjedu.oss-cn-huhehaote.aliyuncs.com/runtime/VC_redist.x86.exe', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
MsgBox('请安装好VC++环境后,再运行本安装包程序!',mbInformation,MB_OK);
Result := false;
begin
MsgBox('没有安装VC++环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);
Result := false;
end;
检测.NET环境
查看各版本和系统的关系: https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed
查看本机的版本
输入
regedit.exe
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy\
脚本
[Code]
// 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
function IsDotNetDetected(version: string; service: cardinal): boolean;
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';
else if version = 'v2.0' then begin
versionKey := 'v2.0.50727';
// .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
// 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);
// .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);
// .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);
result := success and (install = 1) and (serviceCount >= service);
function InitializeSetup: Boolean;
var Path:string;
ResultCode: Integer;
begin
if IsDotNetDetected('v4.5.2', 0) then
begin
Result := true;
begin
if MsgBox('系统检测到您没有安装.Net Framework4.5.2,是否立刻下载并安装?', mbConfirmation, MB_YESNO) = idYes then
begin
Path := ExpandConstant('{pf}/Internet Explorer/iexplore.exe');
Exec(Path, 'https://xhkjedu.oss-cn-huhehaote.aliyuncs.com/runtime/NDP452-KB2901907-x86-x64-AllOS-ENU.exe', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
MsgBox('请安装好.Net Framework环境后,再运行本安装包程序!',mbInformation,MB_OK);
Result := false;
begin
MsgBox('没有安装.Net Framework环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);
Result := false;
end;
注意很多文章查找注册表的地址为
RegKeyExists(HKLM, 'SOFTWARE/Microsoft/.NETFramework/policy/v2.0')
这个获取的版本比较粗略(类似于v2.0/v4.0)不建议使用这个地址。
如图
地址
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\
获取的就比较细致了
检测C++和.NET环境
[Code]
// 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
function IsDotNetDetected(version: string; service: cardinal): boolean;
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';
else if version = 'v2.0' then begin
versionKey := 'v2.0.50727';
// .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
// 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);
// .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);
// .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);
result := success and (install = 1) and (serviceCount >= service);
function InitializeSetup: Boolean;
var Path:string;
ResultCode: Integer;
begin
if IsDotNetDetected('v4.5.2', 0) then
begin
if RegValueExists(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{01FAEC41-B3BC-44F4-B185-5E8475AEB855}', 'Version') then
begin
Result := true;
begin
if MsgBox('系统检测到您没有安装VC++环境,是否立刻下载并安装?', mbConfirmation, MB_YESNO) = idYes then
begin
Path := ExpandConstant('{pf}/Internet Explorer/iexplore.exe');
Exec(Path, 'https://xhkjedu.oss-cn-huhehaote.aliyuncs.com/runtime/VC_redist.x86.exe', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
MsgBox('请安装好VC++环境后,再运行本安装包程序!',mbInformation,MB_OK);
Result := false;
begin
MsgBox('没有安装VC++环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);
Result := false;
begin
if MsgBox('系统检测到您没有安装.Net Framework4.5.2,是否立刻下载并安装?', mbConfirmation, MB_YESNO) = idYes then
begin
Path := ExpandConstant('{pf}/Internet Explorer/iexplore.exe');
Exec(Path, 'https://xhkjedu.oss-cn-huhehaote.aliyuncs.com/runtime/NDP452-KB2901907-x86-x64-AllOS-ENU.exe', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode);
MsgBox('请安装好.Net Framework环境后,再运行本安装包程序!',mbInformation,MB_OK);
Result := false;