前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Inno Setup检测软件依赖环境是否安装

Inno Setup检测软件依赖环境是否安装

作者头像
码客说
发布2021-07-19 15:56:37
2K0
发布2021-07-19 15:56:37
举报
文章被收录于专栏:码客码客

常见环境

从 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++下载

最新支持的 Visual 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目录下

加载文件

代码语言:javascript
复制
[Files]
Source: ".\runtime\VC_redist.x86.exe"; DestDir: "{tmp}"; Check: NeedInstallVC

运行时安装

代码语言:javascript
复制
[Run]
Filename: "{tmp}\VC_redist.x86.exe"; Parameters: /q; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: "Install Microsoft Visual C++ Runtime ..."; Check: NeedInstallVC

检测是否需要安装

代码语言:javascript
复制
[Code]
var vcRuntimeMissing: Boolean;
 
function NeedInstallVC(): Boolean;
begin
  Result := vcRuntimeMissing;
end;
 
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')
    then
      begin
        vcRuntimeMissing := false;
      end
    else
      begin
        vcRuntimeMissing := true;
      end;
  result := true;
end;

检测运行库是否安装是通过注册表进行检测的,其中最后一段字符是运行库的产品ID,每个版本的产品ID都不一样 解压下载后的VC_redist.x86.exe文件,找到名称为0的文件用文本文档打开,

搜索ProductCode会搜索出两个,其中一个是Minimum Runtime,一个是Additional Runtime

代码语言:javascript
复制
RollbackLogPathVariable="WixBundleRollbackLog_vcRuntimeMinimum_x86" ProductCode="{7D75664A-6C04-424C-82A1-EE88913E5F16}"

代码语言:javascript
复制
RollbackLogPathVariable="WixBundleRollbackLog_vcRuntimeAdditional_x86" ProductCode="{01FAEC41-B3BC-44F4-B185-5E8475AEB855}"

我们用到的是WixBundleRollbackLog_vcRuntimeAdditional_x86,在注册表中搜索对应产品ID即可

在线下载

检测C++安装环境

代码语言:javascript
复制
[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;   
  end  
  else  
  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;   
    end  
    else  
    begin  
      MsgBox('没有安装VC++环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);   
      Result := false;   
    end;   
  end;
end;

检测.NET环境

查看各版本和系统的关系:https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

查看本机的版本

输入regedit.exe

代码语言:javascript
复制
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy\

脚本

代码语言:javascript
复制
[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;
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;

function InitializeSetup: Boolean;   
var Path:string;   
    ResultCode: Integer;   
begin  
  if  IsDotNetDetected('v4.5.2', 0) then  
  begin  
    Result := true;   
  end  
  else  
  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;   
    end  
    else  
    begin  
      MsgBox('没有安装.Net Framework环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);   
      Result := false;   
    end;   
  end;
end;

注意很多文章查找注册表的地址为

代码语言:javascript
复制
RegKeyExists(HKLM, 'SOFTWARE/Microsoft/.NETFramework/policy/v2.0')

这个获取的版本比较粗略(类似于v2.0/v4.0)不建议使用这个地址。

如图

image-20210717164543929
image-20210717164543929

地址HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\获取的就比较细致了

image-20210717164514721
image-20210717164514721

检测C++和.NET环境

代码语言:javascript
复制
[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;
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;

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;   
        end  
      else  
      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;   
          end  
        else  
          begin  
            MsgBox('没有安装VC++环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);   
            Result := false;   
          end;   
      end;
    end  
  else  
    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;   
        end  
      else  
        begin  
          MsgBox('没有安装.Net Framework环境,无法运行程序,本安装程序即将退出!',mbInformation,MB_OK);   
          Result := false;   
        end;   
    end;
end;
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 常见环境
  • 本地安装
  • 在线下载
    • 检测C++安装环境
      • 检测.NET环境
        • 检测C++和.NET环境
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档