6

As the title says, I currently cannot find any answers for this problem.

I'm currently using C# to do the checking.

Mostly answers are for version 2013 and below.

If you guys have any suggestion, do share.

Thanks.

Ahmad Syahir
  • 69
  • 1
  • 5
  • Do you have a single-file requirement, or would you consider having a C++/CLI mixed-mode assembly? If you can load the assembly, the redist is there. If it throws an exception, you're missing something. – Ben Voigt Oct 26 '18 at 02:13
  • 2
    Just never ever do this. It is the job of the vcredist installer to do this. You need it anyway when you'd find out that it isn't present, so just always run it. – Hans Passant Oct 26 '18 at 02:18
  • If you look at any game in steam, you will find a folder "_CommonRedist", containing both the VC Redist (2010) and DX 9 June 2010 installers. And they are dilligently executed on the first start of the programm. Do the same thing as everyone else: Always have the setups and always run them as part of the instaler with Admin rights. And if that should fail, there is nothing you could do about it anyway :) – Christopher Oct 26 '18 at 02:24
  • 1
    Try this answer: https://stackoverflow.com/a/51211615/533242. The better way though is to just run the installer in unattended mode. If the computer doesn't need it, it won't be installed. – SameOldNick Oct 26 '18 at 02:38

4 Answers4

3

The basic answer is: Do not bother if it is there at runtime. Put it into your installer. Let it be executed as part of the normal "Elevated Rights required" Installation process.

If it was already there, the Installer will just do nothing.

If it was not there, it will now run under Administrator rights and be there afterwards.

If it was damaged, hopefully the installer will fix the installation.

If that somehow did not work, there is nothing your puny usercode can do to fix it at runtime. It is the administrators job.

Every installer does that, not the least of which are the Visual Studio and SQL Server ones. The only slight modification I know off is Steam, which runs those installers under Elevated rights before a program is executed for the first time. But that is just "making certain it is there" from a slightly different angle.

I only know one kind of programmer that does not do that: The one never tested his program on a freshly installed Windows (Virtual Machines work) and thus is not aware the requirements even exists (because every other program installs VC Redist and current DX versions).

Taylor Hx
  • 2,815
  • 23
  • 36
Christopher
  • 9,634
  • 2
  • 17
  • 31
3

It is hard to get all registry values for VC 2015 so I have written a small function which will go through all dependencies and match on specified version(C++ 2015 x86)

public static bool IsVC2015x86Installed()
{
    string dependenciesPath = @"SOFTWARE\Classes\Installer\Dependencies";

    using (RegistryKey dependencies = Registry.LocalMachine.OpenSubKey(dependenciesPath))
    {
        if (dependencies == null) return false;

        foreach (string subKeyName in dependencies.GetSubKeyNames().Where(n => !n.ToLower().Contains("dotnet") && !n.ToLower().Contains("microsoft")))
        {
            using (RegistryKey subDir = Registry.LocalMachine.OpenSubKey(dependenciesPath + "\\" + subKeyName))
            {
                var value = subDir.GetValue("DisplayName")?.ToString() ?? null;
                if (string.IsNullOrEmpty(value)) continue;

                if (Regex.IsMatch(value, @"C\+\+ 2015.*\(x86\)")) //here u can specify your version.
                {
                    return true;
                }
            }
        }
    }

    return false;
}

Dependencies:

using System;
using System.Text.RegularExpressions;
using Microsoft.Win32;

EDIT:

C++ 2017 is valid replacement for C++ 2015 so if you want to check it as well edit the regex like this:

Regex.IsMatch(value, @"C\+\+ (2015|2017).*\(x86\)")
Kebechet
  • 1,461
  • 15
  • 31
2

As mentioned in comments and answer, one way is to let the installer run and see if a more recent version is installed. The installer will display an error and quit. If the installer is run with /quiet flag, then no error is being displayed. Other way is to simply check the registry values:

HKEY_LOCAL_MACHINE\SOFTWARE[\Wow6432Node]\Microsoft\VisualStudio\vs-version\VC\Runtimes\{x86|x64|ARM} key

Here vs-version is the version of Visual Studio (14.0 for Visual Studio 2015 and 2017) The key is ARM, x86 or x64 depending upon the platform.

The version number is stored in the REG_SZ string value Version. If the package being installed is less than the version of the installed, then no need to install.

More info here: https://learn.microsoft.com/en-us/cpp/ide/redistributing-visual-cpp-files?view=vs-2017

Gauravsa
  • 6,330
  • 2
  • 21
  • 30
1

I modified @ssamko 's Version to check for x64 and x86 redistributables. Hope it will help someone:

public static bool IsVC2015Installed()
{
    string dependenciesPath = @"SOFTWARE\Classes\Installer\Dependencies";

    using (RegistryKey dependencies = Registry.LocalMachine.OpenSubKey(dependenciesPath))
    {
        if (dependencies == null) return false;

        foreach (string subKeyName in dependencies.GetSubKeyNames().Where(n => !n.ToLower().Contains("dotnet") && !n.ToLower().Contains("microsoft")))
        {
            using (RegistryKey subDir = Registry.LocalMachine.OpenSubKey(dependenciesPath + "\\" + subKeyName))
            {
                var value = subDir.GetValue("DisplayName")?.ToString() ?? null;
                if (string.IsNullOrEmpty(value))
                {
                    continue;
                }
                if (Environment.Is64BitOperatingSystem)
                {
                    if (Regex.IsMatch(value, @"C\+\+ 2015.*\((x64|x86)\)"))
                    {
                        return true;
                    }
                }
                else
                {
                    if (Regex.IsMatch(value, @"C\+\+ 2015.*\(x86\)"))
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

Dependencies:

using System;
using System.Text.RegularExpressions;
using Microsoft.Win32;
Phyti1
  • 31
  • 1
  • 6
  • I am not sure if this is a good addition. Because you can have installed just C++ 2015 x86 on x64 machine without problem to run certain apps(which wont run with use of C++ 2015 x64). In case you would like to just check both version anyway I would merge those regexes to: `C\+\+ 2015.*\((x64|x86)\)` – Kebechet Jun 23 '20 at 10:46
  • Thank you for that comment, I applied this addition to my response – Phyti1 Jun 24 '20 at 08:23