Programmatically retrieve Visual Studio install di

2020-02-09 06:44发布

I know there is a registry key indicating the install directory, but I don't remember what it is off-hand.

I am currently interested in Visual Studio 2008 install directory, though it wouldn't hurt to list others for future reference.

14条回答
戒情不戒烟
2楼-- · 2020-02-09 07:39

Here is something I have been updating over the years... (for CudaPAD)

Usage examples:

var vsPath = VS_Tools.GetVSPath(avoidPrereleases:true, requiredWorkload:"NativeDesktop");
var vsPath = VS_Tools.GetVSPath();
var vsPath = VS_Tools.GetVSPath(specificVersion:"15");

The drop-in function:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Setup.Configuration;
using System.IO;
using Microsoft.Win32;

static class VS_Tools
{
    public static string GetVSPath(string specificVersion = "", bool avoidPrereleases = true, string requiredWorkload = "")
    {
        string vsPath = "";
        // Method 1 - use "Microsoft.VisualStudio.Setup.Configuration.SetupConfiguration" method.

        // Note: This code has is a heavily modified version of Heath Stewart's code.
        // original source: (Heath Stewart, May 2016) https://github.com/microsoft/vs-setup-samples/blob/80426ad4ba10b7901c69ac0fc914317eb65deabf/Setup.Configuration.CS/Program.cs
        try
        {
            var e = new SetupConfiguration().EnumAllInstances();

            int fetched;
            var instances = new ISetupInstance[1];
            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    var instance2 = (ISetupInstance2)instances[0];
                    var state = instance2.GetState();

                    // Let's make sure this install is complete.
                    if (state != InstanceState.Complete)
                        continue;

                    // If we have a version to match lets make sure to match it.
                    if (!string.IsNullOrWhiteSpace(specificVersion))
                        if (!instances[0].GetInstallationVersion().StartsWith(specificVersion))
                            continue;

                    // If instances[0] is null then skip
                    var catalog = instances[0] as ISetupInstanceCatalog;
                    if (catalog == null)
                        continue;

                    // If there is not installation path lets skip
                    if ((state & InstanceState.Local) != InstanceState.Local)
                        continue;

                    // Let's make sure it has the required workload - if one was given.
                    if (!string.IsNullOrWhiteSpace(requiredWorkload))
                    {
                        if ((state & InstanceState.Registered) == InstanceState.Registered)
                        {
                            if (!(from package in instance2.GetPackages()
                                    where string.Equals(package.GetType(), "Workload", StringComparison.OrdinalIgnoreCase)
                                    where package.GetId().Contains(requiredWorkload)
                                    orderby package.GetId()
                                    select package).Any())
                            {
                                continue;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }

                    // Let's save the installation path and make sure it has a value.
                    vsPath = instance2.GetInstallationPath();
                    if (string.IsNullOrWhiteSpace(vsPath))
                        continue;

                    // If specified, avoid Pre-release if possible
                    if (avoidPrereleases && catalog.IsPrerelease())
                        continue;

                    // We found the one we need - lets get out of here
                    return vsPath;
                }
            }
            while (fetched > 0);
        }
        catch (Exception){ }

        if (string.IsNullOrWhiteSpace(vsPath))
            return vsPath;

        // Fall-back Method: Find the location of visual studio (%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat)
        // Note: This code has is a heavily modified version of Kevin Kibler's code.
        // source: (Kevin Kibler, 2014) http://stackoverflow.com/questions/30504/programmatically-retrieve-visual-studio-install-directory
        List<Version> vsVersions = new List<Version>() { new Version("15.0"), new Version("14.0"),
            new Version("13.0"), new Version("12.0"), new Version("11.0") };
        foreach (var version in vsVersions)
        {
            foreach (var isExpress in new bool[] { false, true })
            {
                RegistryKey registryBase32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
                RegistryKey vsVersionRegistryKey = registryBase32.OpenSubKey(
                    string.Format(@"{0}\{1}.{2}",
                    (isExpress) ? @"SOFTWARE\Microsoft\VCSExpress" : @"SOFTWARE\Microsoft\VisualStudio",
                    version.Major, version.Minor));
                if (vsVersionRegistryKey == null) { continue; }
                string path = vsVersionRegistryKey.GetValue("InstallDir", string.Empty).ToString();
                if (!string.IsNullOrEmpty(path))
                {
                    path = Directory.GetParent(path).Parent.Parent.FullName;
                    if (File.Exists(path + @"\VC\bin\cl.exe") && File.Exists(path + @"\VC\vcvarsall.bat"))
                    {
                        vsPath = path;
                        break;
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(vsPath))
                break;
        }
        return vsPath;
    }
}
查看更多
Deceive 欺骗
3楼-- · 2020-02-09 07:41

I use this method to find the installation path of Visual Studio 2010:

    private string GetVisualStudioInstallationPath()
    {
        string installationPath = null;
        if (Environment.Is64BitOperatingSystem)
        {
            installationPath = (string)Registry.GetValue(
               "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\",
                "InstallDir",
                null);
        }
        else
        {
            installationPath = (string)Registry.GetValue(
       "HKEY_LOCAL_MACHINE\\SOFTWARE  \\Microsoft\\VisualStudio\\10.0\\",
              "InstallDir",
              null);
        }
        return installationPath;

    }
查看更多
冷血范
4楼-- · 2020-02-09 07:43

I'm sure there's a registry entry as well but I couldn't easily locate it. There is the VS90COMNTOOLS environment variable that you could use as well.

查看更多
别忘想泡老子
5楼-- · 2020-02-09 07:43

Here's a solution to always get the path for the latest version:

$vsEnvVars = (dir Env:).Name -match "VS[0-9]{1,3}COMNTOOLS"
$latestVs = $vsEnvVars | Sort-Object | Select -Last 1
$vsPath = Get-Content Env:\$latestVs
查看更多
一纸荒年 Trace。
6楼-- · 2020-02-09 07:45

@Dim-Ka has a great answer. If you were curious how you'd implement this in a batch script, this is how.

@echo off
:: BATCH doesn't have logical or, otherwise I'd use it
SET platform=
IF /I [%PROCESSOR_ARCHITECTURE%]==[amd64] set platform=true
IF /I [%PROCESSOR_ARCHITEW6432%]==[amd64] set platform=true

:: default to VS2012 = 11.0
:: the Environment variable VisualStudioVersion is set by devenv.exe
:: if this batch is a child of devenv.exe external tools, we know which version to look at
if not defined VisualStudioVersion SET VisualStudioVersion=11.0

if defined platform (
set VSREGKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%VisualStudioVersion%
)  ELSE (
set VSREGKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%VisualStudioVersion%
)
for /f "skip=2 tokens=2,*" %%A in ('reg query "%VSREGKEY%" /v InstallDir') do SET VSINSTALLDIR=%%B

echo %VSINSTALLDIR%
查看更多
戒情不戒烟
7楼-- · 2020-02-09 07:46

Ah, the 64-bit machine part was the issue. It turns out I need to make sure I'm running the PowerShell.exe under the syswow64 directory in order to get the x86 registry keys.

Now that wasn't very fun.

查看更多
登录 后发表回答