45

在我的 inno setup RUN 选择中,我强制静默安装 MSVCRT。我想知道如何使它仅在尚未安装的情况下自行安装?

这就是我现在所说的:

Filename: {tmp}\vcredist_x86.exe; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: Installing 2010 RunTime...
4

6 回答 6

92

由于您不想告诉您需要什么最小版本的 Visual C++ 可再发行包,因此这里有代码示例,您可以从中自己构建它。请注意,我不知道,哪些版本与哪些版本兼容,必须安装哪些较低版本,我会一直告诉你。

我唯一可以告诉您的是,您绝对应该使用Check条件参数,在打开向导时尝试安装框架或运行时库的解决方案是错误的。此条件参数的工作方式与您返回 True 时一样,正在安装文件,如果为 False,则跳过它。VCRedistNeedsInstall因此,当您想要安装运行时库时,您需要返回 True 才能运行,否则返回 False。VCVersionInstalled使用以 here 开头的常量的辅助函数VC_在安装包时返回 True,否则返回 False。

作为这个来源,我使用了以下来源:

  1. 如何检测 VC 8.0 运行时可再发行包的存在
  2. 如何检测 VC 9.0 运行时可再发行包的存在
  3. 如何检测 VC 2010 运行时可再发行包的存在

由于kobik 使用条件定义的想法,以下代码应该与 Inno Setup 的 Unicode 和 ANSI 版本兼容。

这是代码:

[Files]
Source: "vcredist_x86.exe"; DestDir: {tmp}; Flags: deleteafterinstall

[Run]
; add the Parameters, WorkingDir and StatusMsg as you wish, just keep here
; the conditional installation Check
Filename: "{tmp}\vcredist_x86.exe"; Check: VCRedistNeedsInstall

[Code]
#IFDEF UNICODE
  #DEFINE AW "W"
#ELSE
  #DEFINE AW "A"
#ENDIF
type
  INSTALLSTATE = Longint;
const
  INSTALLSTATE_INVALIDARG = -2;  { An invalid parameter was passed to the function. }
  INSTALLSTATE_UNKNOWN = -1;     { The product is neither advertised or installed. }
  INSTALLSTATE_ADVERTISED = 1;   { The product is advertised but not installed. }
  INSTALLSTATE_ABSENT = 2;       { The product is installed for a different user. }
  INSTALLSTATE_DEFAULT = 5;      { The product is installed for the current user. }

  VC_2005_REDIST_X86 = '{A49F249F-0C91-497F-86DF-B2585E8E76B7}';
  VC_2005_REDIST_X64 = '{6E8E85E8-CE4B-4FF5-91F7-04999C9FAE6A}';
  VC_2005_REDIST_IA64 = '{03ED71EA-F531-4927-AABD-1C31BCE8E187}';
  VC_2005_SP1_REDIST_X86 = '{7299052B-02A4-4627-81F2-1818DA5D550D}';
  VC_2005_SP1_REDIST_X64 = '{071C9B48-7C32-4621-A0AC-3F809523288F}';
  VC_2005_SP1_REDIST_IA64 = '{0F8FB34E-675E-42ED-850B-29D98C2ECE08}';
  VC_2005_SP1_ATL_SEC_UPD_REDIST_X86 = '{837B34E3-7C30-493C-8F6A-2B0F04E2912C}';
  VC_2005_SP1_ATL_SEC_UPD_REDIST_X64 = '{6CE5BAE9-D3CA-4B99-891A-1DC6C118A5FC}';
  VC_2005_SP1_ATL_SEC_UPD_REDIST_IA64 = '{85025851-A784-46D8-950D-05CB3CA43A13}';

  VC_2008_REDIST_X86 = '{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}';
  VC_2008_REDIST_X64 = '{350AA351-21FA-3270-8B7A-835434E766AD}';
  VC_2008_REDIST_IA64 = '{2B547B43-DB50-3139-9EBE-37D419E0F5FA}';
  VC_2008_SP1_REDIST_X86 = '{9A25302D-30C0-39D9-BD6F-21E6EC160475}';
  VC_2008_SP1_REDIST_X64 = '{8220EEFE-38CD-377E-8595-13398D740ACE}';
  VC_2008_SP1_REDIST_IA64 = '{5827ECE1-AEB0-328E-B813-6FC68622C1F9}';
  VC_2008_SP1_ATL_SEC_UPD_REDIST_X86 = '{1F1C2DFC-2D24-3E06-BCB8-725134ADF989}';
  VC_2008_SP1_ATL_SEC_UPD_REDIST_X64 = '{4B6C7001-C7D6-3710-913E-5BC23FCE91E6}';
  VC_2008_SP1_ATL_SEC_UPD_REDIST_IA64 = '{977AD349-C2A8-39DD-9273-285C08987C7B}';
  VC_2008_SP1_MFC_SEC_UPD_REDIST_X86 = '{9BE518E6-ECC6-35A9-88E4-87755C07200F}';
  VC_2008_SP1_MFC_SEC_UPD_REDIST_X64 = '{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}';
  VC_2008_SP1_MFC_SEC_UPD_REDIST_IA64 = '{515643D1-4E9E-342F-A75A-D1F16448DC04}';

  VC_2010_REDIST_X86 = '{196BB40D-1578-3D01-B289-BEFC77A11A1E}';
  VC_2010_REDIST_X64 = '{DA5E371C-6333-3D8A-93A4-6FD5B20BCC6E}';
  VC_2010_REDIST_IA64 = '{C1A35166-4301-38E9-BA67-02823AD72A1B}';
  VC_2010_SP1_REDIST_X86 = '{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}';
  VC_2010_SP1_REDIST_X64 = '{1D8E6291-B0D5-35EC-8441-6616F567A0F7}';
  VC_2010_SP1_REDIST_IA64 = '{88C73C1C-2DE5-3B01-AFB8-B46EF4AB41CD}';

  { Microsoft Visual C++ 2012 x86 Minimum Runtime - 11.0.61030.0 (Update 4) }
  VC_2012_REDIST_MIN_UPD4_X86 = '{BD95A8CD-1D9F-35AD-981A-3E7925026EBB}';
  VC_2012_REDIST_MIN_UPD4_X64 = '{CF2BEA3C-26EA-32F8-AA9B-331F7E34BA97}';
  { Microsoft Visual C++ 2012 x86 Additional Runtime - 11.0.61030.0 (Update 4)  }
  VC_2012_REDIST_ADD_UPD4_X86 = '{B175520C-86A2-35A7-8619-86DC379688B9}';
  VC_2012_REDIST_ADD_UPD4_X64 = '{37B8F9C7-03FB-3253-8781-2517C99D7C00}';

  { Visual C++ 2013 Redistributable 12.0.21005 }
  VC_2013_REDIST_X86_MIN = '{13A4EE12-23EA-3371-91EE-EFB36DDFFF3E}';
  VC_2013_REDIST_X64_MIN = '{A749D8E6-B613-3BE3-8F5F-045C84EBA29B}';

  VC_2013_REDIST_X86_ADD = '{F8CFEB22-A2E7-3971-9EDA-4B11EDEFC185}';
  VC_2013_REDIST_X64_ADD = '{929FBD26-9020-399B-9A7A-751D61F0B942}';

  { Visual C++ 2015 Redistributable 14.0.23026 }
  VC_2015_REDIST_X86_MIN = '{A2563E55-3BEC-3828-8D67-E5E8B9E8B675}';
  VC_2015_REDIST_X64_MIN = '{0D3E9E15-DE7A-300B-96F1-B4AF12B96488}';

  VC_2015_REDIST_X86_ADD = '{BE960C1C-7BAD-3DE6-8B1A-2616FE532845}';
  VC_2015_REDIST_X64_ADD = '{BC958BD2-5DAC-3862-BB1A-C1BE0790438D}';

  { Visual C++ 2015 Redistributable 14.0.24210 }
  VC_2015_REDIST_X86 = '{8FD71E98-EE44-3844-9DAD-9CB0BBBC603C}';
  VC_2015_REDIST_X64 = '{C0B2C673-ECAA-372D-94E5-E89440D087AD}';

function MsiQueryProductState(szProduct: string): INSTALLSTATE; 
  external 'MsiQueryProductState{#AW}@msi.dll stdcall';

function VCVersionInstalled(const ProductID: string): Boolean;
begin
  Result := MsiQueryProductState(ProductID) = INSTALLSTATE_DEFAULT;
end;

function VCRedistNeedsInstall: Boolean;
begin
  { here the Result must be True when you need to install your VCRedist }
  { or False when you don't need to, so now it's upon you how you build }
  { this statement, the following won't install your VC redist only when }
  { the Visual C++ 2010 Redist (x86) and Visual C++ 2010 SP1 Redist(x86) }
  { are installed for the current user }
  Result := not (VCVersionInstalled(VC_2010_REDIST_X86) and 
    VCVersionInstalled(VC_2010_SP1_REDIST_X86));
end;

咯咯植物更新:

添加了 VC++ 2012 产品代码。请注意,可再发行包安装了两个东西,最小运行时和附加运行时。寻找最小运行时间应该就足够了。针对 Microsoft Visual C++ 2012 Redistributable 产品代码进行测试将给出INSTALLSTATE_UNKNOWN,改用最小运行时代码。VC++ 2013 和 2015 的情况相同。

HKEY_CLASSES_ROOT\Installer\Dependencies\例如,您可以在 中找到其他 Visual Studio 版本的产品代码HKEY_CLASSES_ROOT\Installer\Dependencies\Microsoft.VS.VC_RuntimeAdditionalVSU_amd64,v14

于 2012-06-23T20:59:00.307 回答
11

这是一个使用 Microsoft 推荐的方法来确定是否安装了 VC Redistributable 的版本。我只需要 VC 2015,因此您需要为其他版本调整值和参数​​:

[Files]
Source: ".\vc-redist\vc-redist\win64\bin\vc_redist.x64.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall; Check: Is64BitInstallMode

; FlexLM requires the VC 2015 redistributables so run the installer if this 
; or a later 2015 version is not already present
[Run]
Filename: "{tmp}\vc_redist.x64.exe"; Parameters: "/install /passive"; StatusMsg: "{#VCmsg}"; Check: IsWin64 and not VCinstalled

[Code]
function VCinstalled: Boolean;
 // Function for Inno Setup Compiler
 // Returns True if same or later Microsoft Visual C++ 2015 Redistributable is installed, otherwise False.
 var
  major: Cardinal;
  minor: Cardinal;
  bld: Cardinal;
  rbld: Cardinal;
  key: String;
 begin
  Result := False;
  key := 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64';
  if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Major', major) then begin
    if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Minor', minor) then begin
      if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'Bld', bld) then begin
        if RegQueryDWordValue(HKEY_LOCAL_MACHINE, key, 'RBld', rbld) then begin
            Log('VC 2015 Redist Major is: ' + IntToStr(major) + ' Minor is: ' + IntToStr(minor) + ' Bld is: ' + IntToStr(bld) + ' Rbld is: ' + IntToStr(rbld));
            // Version info was found. Return true if later or equal to our 14.0.24212.00 redistributable
            // Note brackets required because of weird operator precendence
            Result := (major >= 14) and (minor >= 0) and (bld >= 24212) and (rbld >= 0)
        end;
      end;
    end;
  end;
 end;
于 2017-08-31T10:40:28.240 回答
8

容易得多:

#define VCmsg "Installing Microsoft Visual C++ Redistributable...."

[Run]
Filename: "vc_redist.x86.exe"; StatusMsg: "{#VCmsg}"; Check: not IsWin64 and not VCinstalled
Filename: "vc_redist.x64.exe"; StatusMsg: "{#VCmsg}"; Check: IsWin64 and not VCinstalled

[Code]
function VCinstalled: Boolean;
 // By Michael Weiner <mailto:spam@cogit.net>
 // Function for Inno Setup Compiler
 // 13 November 2015
 // Returns True if Microsoft Visual C++ Redistributable is installed, otherwise False.
 // The programmer may set the year of redistributable to find; see below.
 var
  names: TArrayOfString;
  i: Integer;
  dName, key, year: String;
 begin
  // Year of redistributable to find; leave null to find installation for any year.
  year := '';
  Result := False;
  key := 'Software\Microsoft\Windows\CurrentVersion\Uninstall';
  // Get an array of all of the uninstall subkey names.
  if RegGetSubkeyNames(HKEY_LOCAL_MACHINE, key, names) then
   // Uninstall subkey names were found.
   begin
    i := 0
    while ((i < GetArrayLength(names)) and (Result = False)) do
     // The loop will end as soon as one instance of a Visual C++ redistributable is found.
     begin
      // For each uninstall subkey, look for a DisplayName value.
      // If not found, then the subkey name will be used instead.
      if not RegQueryStringValue(HKEY_LOCAL_MACHINE, key + '\' + names[i], 'DisplayName', dName) then
       dName := names[i];
      // See if the value contains both of the strings below.
      Result := (Pos(Trim('Visual C++ ' + year),dName) * Pos('Redistributable',dName) <> 0)
      i := i + 1;
     end;
   end;
 end;
于 2015-11-13T14:45:35.060 回答
5

我知道这是一个非常古老的问题,但我遇到了这种情况,因为我无法进行 winregistry 检查,所以我采用了这种方法,

基于此文件列表:https ://matthew-brett.github.io/pydagogue/_sources/python_msvc.rst.txt

我能够检查文件是否存在,例如 VCRedist 2015/2013 x86/x64:

2015

C:/Windows/System32/msvcp140.dll- x64

C:/Windows/SysWOW64/msvcp140.dll"- x86

2013

C:/Windows/System32/msvcp120.dll- x64

C:/Windows/SysWOW64/msvcp120.dll"- x86

于 2018-07-06T13:34:37.363 回答
1

我正在处理 Visual C++ 2015-2019 可再发行包和 64 位操作系统上可能的 32 位安装。

我修改了user3433200解决方案如下:

function VCinstalled(const regKey: string): Boolean;
 { Function for Inno Setup Compiler }
 { Returns True if same or later Microsoft Visual C++ 2015 Redistributable is installed, otherwise False. }
 var
  major: Cardinal;
  minor: Cardinal;
  bld: Cardinal;
  rbld: Cardinal;
 begin
  Result := False;

  if RegQueryDWordValue(HKEY_LOCAL_MACHINE, regKey, 'Major', major) then begin
    if RegQueryDWordValue(HKEY_LOCAL_MACHINE, regKey, 'Minor', minor) then begin
      if RegQueryDWordValue(HKEY_LOCAL_MACHINE, regKey, 'Bld', bld) then begin
        if RegQueryDWordValue(HKEY_LOCAL_MACHINE, regKey, 'RBld', rbld) then begin
            Log('VC 2015-2019 Redist Major is: ' + IntToStr(major) + ' Minor is: ' + IntToStr(minor) + ' Bld is: ' + IntToStr(bld) + ' Rbld is: ' + IntToStr(rbld));
            { Version info was found. Return true if later or equal to our 14.23.27820.0 redistributable }
            { Note brackets required because of weird operator precendence }
            Result := (major >= 14) and (minor >= 23) and (bld >= 27820) and (rbld >= 0)
        end;
      end;
    end;
  end;
 end;

function VCRedistNeedsInstall: Boolean;
begin
 if NOT IsWin64 then 
  Result := not (VCinstalled('SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X86'))
 else if Is64BitInstallMode then
  Result := not (VCinstalled('SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x64'))
 else
  Result := not (VCinstalled('SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86'));  
end;

在 Win 7 32 位和 Win10 64 位上测试。

于 2019-12-13T09:45:37.403 回答
0

Comsci 的答案马丁的答案改编)很接近,但没有正确执行版本检查。(例如,如果次要版本中有一个凸起并且内部版本号重置为零,它将失败。)这是该答案的更正版本,适用于 32 位和 64 位 Visual Studio 2015-2019 软件包。

我发现当前的 64 位软件包如果已经安装会破坏运行时,所以在安装之前检查是必要的(直到微软修复了这个问题)。编辑:这可能已在 Visual Studio 16.10(发行说明)中修复。

与原始答案一样,这是基于Microsoft 推荐的确定是否已安装 VC Redistributable 的方法

[Files]
Source: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\v142\vcredist_x86.exe; DestDir: {tmp}; Flags: deleteafterinstall ignoreversion
Source: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Redist\MSVC\v142\vcredist_x64.exe; DestDir: {tmp}; Flags: deleteafterinstall ignoreversion; Check: IsWin64

[Run]
Filename: {tmp}\vcredist_x86.exe; Parameters: /quiet /norestart; StatusMsg: "{#VCmsg32}"; Check: not VCRuntime32Installed
Filename: {tmp}\vcredist_x64.exe; Parameters: /quiet /norestart; StatusMsg: "{#VCmsg64}"; Check: IsWin64 and not VCRuntime64Installed

[Code]
function VCRuntime32Installed: Boolean;
 var
  required_major: Cardinal;
  required_minor: Cardinal;
  required_bld: Cardinal;
  required_rbld: Cardinal;
  major: Cardinal;
  minor: Cardinal;
  bld: Cardinal;
  rbld: Cardinal;
  key: String;
 begin
  required_major := 14;
  required_minor := 29;
  required_bld := 30037;
  required_rbld := 0;
  Result := False;
  key := 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X86';
  if RegQueryDWordValue(HKLM32, key, 'Major', major) then begin
    if RegQueryDWordValue(HKLM32, key, 'Minor', minor) then begin
      if RegQueryDWordValue(HKLM32, key, 'Bld', bld) then begin
        if RegQueryDWordValue(HKLM32, key, 'Rbld', rbld) then begin
            Log('vcruntime (x86) version: ' + IntToStr(major) + '.' + IntToStr(minor) + '.' + IntToStr(bld) + '.' + IntToStr(rbld));
            Result := (major > required_major) or ((major = required_major) and ((minor > required_minor) or ((minor = required_minor) and ((bld > required_bld) or ((bld = required_bld) and (rbld >= required_rbld))))))
        end;
      end;
    end;
  end;
 end;
function VCRuntime64Installed: Boolean;
 var
  required_major: Cardinal;
  required_minor: Cardinal;
  required_bld: Cardinal;
  required_rbld: Cardinal;
  major: Cardinal;
  minor: Cardinal;
  bld: Cardinal;
  rbld: Cardinal;
  key: String;
 begin
  required_major := 14;
  required_minor := 29;
  required_bld := 30037;
  required_rbld := 0;
  Result := False;
  key := 'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\X64';
  if RegQueryDWordValue(HKLM64, key, 'Major', major) then begin
    if RegQueryDWordValue(HKLM64, key, 'Minor', minor) then begin
      if RegQueryDWordValue(HKLM64, key, 'Bld', bld) then begin
        if RegQueryDWordValue(HKLM64, key, 'Rbld', rbld) then begin
            Log('vcruntime (x64) version: ' + IntToStr(major) + '.' + IntToStr(minor) + '.' + IntToStr(bld) + '.' + IntToStr(rbld));
            Result := (major > required_major) or ((major = required_major) and ((minor > required_minor) or ((minor = required_minor) and ((bld > required_bld) or ((bld = required_bld) and (rbld >= required_rbld))))))
        end;
      end;
    end;
  end;
 end;
于 2021-06-29T12:12:04.167 回答