46

In my inno setup RUN selection I force silent install of MSVCRT. I wonder how to make it install itself only if not yet installed?

This is what I call now:

Filename: {tmp}\vcredist_x86.exe; Parameters: "/passive /Q:a /c:""msiexec /qb /i vcredist.msi"" "; StatusMsg: Installing 2010 RunTime...
myWallJSON
  • 9,110
  • 22
  • 78
  • 149
  • 1
    Something similar has been asked [`here`](http://stackoverflow.com/q/10982468/960757) however I don't agree with the answer since it installs the framework when the wizard starts, but IMO it should be run when you press the final *Next* button and the installation begins. I'll try to find the registry entries needed for this check. In the meantime take a look at [`this post`](http://stackoverflow.com/a/10111173/960757). You need to use [`Check`](http://www.jrsoftware.org/ishelp/topic_scriptcheck.htm) parameter for this. – TLama Jun 22 '12 at 12:45

6 Answers6

94

Since you don't want to tell what minimal version of Visual C++ redistributable package you require, here you have the code sample from which you can build this by your own. Please notice that I have no clue, what versions are compatible with what and what lower versions must be installed, I'll keep this upon you.

The only thing I can tell you is that you should definitely use Check conditional parameter, the solutions attempting to install the framework or runtime libraries when the wizard is being opened are wrong. This conditional parameter works as when you return True to it, the file is being installed, if False it is skipped. So you need to return True to VCRedistNeedsInstall function when you want to install your runtime libraries, False if not. The helper function VCVersionInstalled which uses constants beginning with the VC_ here returns True when the package is installed, False otherwise.

As the source of this I've used the following sources:

  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

The following code should be compatible with Unicode and ANSI versions of Inno Setup thanks to kobik's idea to use the conditional define.

Here is the code:

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

Update by chuckleplant:

Added VC++ 2012 product codes. Notice that the redistributable package installs two things, the minimum runtime and the additional runtime. It should be enough for you to look for the minimum runtime. Testing against the Microsoft Visual C++ 2012 Redistributable product code will give INSTALLSTATE_UNKNOWN, use the Minimum Runtime codes instead. It's the same situation for VC++ 2013 and 2015.

You can find product codes for other Visual Studio versions in HKEY_CLASSES_ROOT\Installer\Dependencies\, for example HKEY_CLASSES_ROOT\Installer\Dependencies\Microsoft.VS.VC_RuntimeAdditionalVSU_amd64,v14

Community
  • 1
  • 1
TLama
  • 75,147
  • 17
  • 214
  • 392
  • 2
    Thank you so wary much for such a grate answer! – myWallJSON Jun 23 '12 at 23:37
  • 2
    Note that sometimes even when the OS includes the "VC++ runtimes" it's not sufficient for your application; occasionally service packs or hotfixes get installed on your dev PCs which end up requiring a later version of the runtime than was originally shipped with the OS. As a consequence, don't forget to always test your app on a "clean" PC/VM after installing updates on your dev/build PCs. – Miral Jun 23 '12 at 23:43
  • @TLama : this code is working for 'VC_2008_REDIST_X86' but not working for 'VC_2008_SP1_REDIST_X86'. it is all time installing VVisual C++ 2008 SP1 Redistributable Package (x86). can you please help me ? – Shoshi May 03 '13 at 19:42
  • @Shoshi, could you please check the value of the `MsiQueryProductState` result by running [`this InnoSetup script`](http://pastebin.com/45JZLHVw) ? Also, could you tell on which OS did you encounter this problem ? There were [`some troubles around this topic`](http://stackoverflow.com/a/2880309/960757). – TLama May 03 '13 at 20:04
  • i am extremely sorry.the fault was mine. i was using different version. then i just download the exact version which link is given in your preferred site (link 2). now problem is gone. thank you. @TLama – Shoshi May 03 '13 at 20:49
  • The comment before: `not(VCVersionInstalled(VC_2010_REDIST_X86))` **and** `not(VCVersionInstalled(VC_2010_SP1_REDIST_X86))` must be read with care ... was willing just to test for one or the other distribution to be installed and took me some time to figure out why just copy/paste was not working ... – CitizenInsane May 16 '13 at 09:33
  • @CitizenInsane, sorry, I don't get your last comment. That statement has doubled parentheses like `not ((Condition1) and (Condition2))` so I can't see a problem. – TLama May 16 '13 at 09:41
  • @TLama I was just willing to test either for `VC_2010_REDIST_X86` **OR** `VC_2010_SP1_REDIST_X86` to be already installed to skip installation of redistributables. As coded in your sample with doubled parentheses `VCRedistNeedsInstall` requires both `REDIST_X86` **and** `SP1_REDIST_x86` to be installed to skip redistributables installation ... so it was a bit confusing for my case... – CitizenInsane May 16 '13 at 11:37
  • 2
    @TLama Would you be so nice to update your answer for VC_REDIST_2012 (http://www.microsoft.com/de-de/download/details.aspx?id=30679)? I think the regkey is "{8e70e4e1-06d7-470b-9f74-a51bef21088e}". Untested. – Jens A. Koch Oct 02 '14 at 10:24
  • 1
    "Note that since Windows Vista the Visual C++ 8.0 (Visual C++ 2005) is installed as a part of the OS" ==> Just found to be false. I have a couple of cases with Win 7 Pro SP1 without Visual C++ 8.0 redist.... :( However, very nice solution. – J_Zar Feb 11 '15 at 11:30
  • @J_Zar, I'm sorry for that. I took that information from the linked article with no further investigation; MS [`itself says`](http://support.microsoft.com/kb/326922/en-us) that *the CRT DLL is no longer considered a system file, therefore, distribute the CRT DLL with any application that relies on it.* I'll remove that note. Thanks for pointing this out! – TLama Feb 11 '15 at 11:37
  • It works perfectly. But it should check one case only, VC_2010_SP1_REDIST_X86, in last pieces of code. `Result := not VCVersionInstalled(VC_2010_SP1_REDIST_X86);` – Hill Jun 07 '16 at 06:37
  • 6
    MS has an official way to detect if VC++ is installed by checking `HKEY_LOCAL_MACHINE\SOFTWARE[\Wow6432Node]\Microsoft\DevDiv\vc\Servicing\14.0\RuntimeMinimum` : https://msdn.microsoft.com/en-us/library/ms235299.aspx?f=255&MSPPError=-2147217396 – thomasb Nov 28 '16 at 14:09
  • 3
    Just in case if anyone wants GUIDs for VC++ 2017 // Visual C++ 2017 Redistributable 14.10.25 VC_2017_REDIST_X86_MIN = '{029DA848-1A80-34D3-BFC1-A6447BFC8E7F}'; VC_2017_REDIST_X64_MIN = '{8D50D8C6-1E3D-3BAB-B2B7-A5399EA1EBD1}'; VC_2017_REDIST_X86_ADD = '{568CD07E-0824-3EEB-AEC1-8FD51F3C85CF}'; VC_2017_REDIST_X64_ADD = '{C668F044-4825-330D-8F9F-3CBFC9F2AB89}'; – Gautam Jain Aug 24 '18 at 12:13
  • @GautamJain Can you add { Visual C++ 2017 Redistributable 14.11.25325 } ? – tmighty Feb 22 '19 at 16:43
  • any GUID for VC++ 2019? – acegs Jan 13 '20 at 07:04
  • 1
    VC ++ 2019 : x64, display version: 14.26.28720 VC_2019_X64_ADD : '{CB4A0FDE-1126-4AE2-97C6-A243692C3D95}' VC_2019_X64_MIN : '{DD1EC0FD-3F0A-4740-A05E-1DCD14A6B0D1}' – DVELPR Jun 06 '20 at 08:49
12

Here's a version that uses the Microsoft recommended way of determining whether the VC Redistributable is installed. I only needed VC 2015 so you will need to adapt values and parameters for other versions:

[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;
Comsci
  • 211
  • 3
  • 6
10

Much easier:

#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;
Michael Weiner
  • 109
  • 1
  • 3
  • It seems latest msvc 2015 redist are labelled "Microsoft Visual C++ 2015 x64 Minimum Runtime - 14.0.23026" so the word "Redistributable" does not appear in the string. – Julien M Aug 30 '16 at 16:10
  • I liked the simplicity of this answer - and decided to use it. I incorporated Julien M's idea (see the comment above) so that the logic checks for both Redistributable and Runtime to make it more flexible. Thanks! – MCone May 15 '23 at 18:13
5

I know is very old question but i encounter this situation and since i couldn't do winregistry checking i did this approach,

based on this list of files : https://matthew-brett.github.io/pydagogue/_sources/python_msvc.rst.txt

i was able to just check if the file exist , for example 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

Jose De Gouveia
  • 994
  • 1
  • 14
  • 33
1

I'm dealing with the Visual C++ 2015-2019 redistributable package and with possible 32bit installations on 64bit OS.

I modified user3433200 solution as follows:

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;

Tested on Win 7 32bit and Win10 64bit.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Nikzeno
  • 116
  • 8
1

Comsci's answer (which Martin's answer adapted) is close but doesn't perform the version check correctly. (It will fail if there is a bump in the minor version and the build number resets to zero, for example.) Here's a corrected version of that answer, for both the 32-bit and 64-bit Visual Studio 2015-2019 packages.

I've found that the current 64-bit package breaks the runtime if it is already installed, so checking before installing it is necessary (until this is fixed by Microsoft). Edit: This was probably fixed in Visual Studio 16.10 (release notes).

As in the original answer, this is based on the 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;