如果尚未安装,如何重新安装vcredist_x86?

时间:2012-06-21 11:44:46

标签: inno-setup msvcrt

在我的inno设置RUN选择中,我强制安装MSVCRT。我想知道如果尚未安装它,如何安装它?

这就是我现在所说的:

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

6 个答案:

答案 0 :(得分:88)

由于您不想告诉您需要哪个最小版本的Visual C ++可再发行组件包,因此您可以使用自己的代码示例来构建它。请注意,我不知道哪些版本与哪些版本兼容,以及必须安装哪些较低版本,我会保留给您。

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

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

  1. How to detect the presence of the VC 8.0 runtime redistributable package
  2. How to detect the presence of the VC 9.0 runtime redistributable package
  3. How to detect the presence of the VC 2010 runtime redistributable package
  4. 由于kobik's idea to use the conditional define,以下代码应与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;
    

    chuckleplant更新:

    添加了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

答案 1 :(得分: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;

答案 2 :(得分:7)

这是一个使用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;

答案 3 :(得分:1)

我知道这是一个很老的问题,但是我遇到了这种情况,由于我无法进行winregistry检查,所以我采用了这种方法,

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

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

2015

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

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

2013

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

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

答案 4 :(得分:1)

我正在处理Visual C ++ 2015-2019可再发行组件包以及在64位OS上可能的32位安装。

我对user3433200 solution进行了如下修改:

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位上测试。

答案 5 :(得分:0)

Comsci's answerMartin's answer 改编)很接近,但没有正确执行版本检查。 (例如,如果次要版本中存在碰撞并且内部版本号重置为零,它将失败。)这是该答案的更正版本,适用于 32 位和 64 位 Visual Studio 2015-2019 程序包。

我发现当前的 64 位软件包如果已经安装会破坏运行时,因此在安装之前进行检查是必要的(直到 Microsoft 修复此问题)。

与原始答案一样,这是基于 Microsoft recommended way of determining whether the VC Redistributable is installed

[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;