如何才能使vcredist_x86重新安装只有在尚未安装?

在我inno安装运行select我强制无声安装MSVCRT。 我不知道如何使它自己安装只有在尚未安装?

这就是我现在所说的:

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

由于您不想告诉您需要的Visual C ++可再发行组件包的最小版本,因此您可以在此获取可由您自己构build的代码示例。 请注意,我不知道哪个版本与哪些版本兼容,哪些版本必须安装,我会保留这个版本。

我唯一能告诉你的是你应该使用Check条件参数,当向导被打开时试图安装框架或运行库的解决scheme是错误的。 这个条件参数的作用是当你返回True时,文件正在被安装,如果False被跳过。 所以当你想安装你的运行时库时,你需要返回True到VCRedistNeedsInstall函数, VCRedistNeedsInstall返回False。 使用以VC_开头的常量的辅助函数VCVersionInstalled在安装包时返回True,否则返回False。

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

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

下面的代码应该与Unicode和ANSI版本的Inno Setup兼容,这要归功于kobik的想法来使用条件定义 。

这里是代码:

 [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产品代码进行testing将会给INSTALLSTATE_UNKNOWN ,请使用最小运行时代码。 VC ++ 2013和2015的情况也是如此。

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

更容易:

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

以下是使用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;