コード例 #1
0
        public static string[] GetInstancePaths()
        {
            var instancePaths = new List <string>();

            var query = new SetupConfiguration();
            var e     = query.EnumAllInstances();
            int fetched;

            var instances = new ISetupInstance[1];

            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    instancePaths.Add(instances[0].GetInstallationPath());
                }
            } while (fetched > 0);

            return(instancePaths.ToArray());
        }
コード例 #2
0
        /// <summary>
        /// Gets the installed version
        /// </summary>
        /// <param name="configurationSuffix"></param>
        /// <returns>The  Visual Studio metadata</returns>
        public static VisualStudio GetInstalledVisualStudio(string configurationSuffix)
        {
            var query = new SetupConfiguration();

            var query2 = (ISetupConfiguration2)query;
            var e      = query2.EnumAllInstances();

            int fetched;
            var instances = new ISetupInstance[1];

            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    return(GetInstance(instances[0], configurationSuffix));
                }
            }while (fetched > 0);

            return(default(VisualStudio));
        }
コード例 #3
0
        private bool TryGetVCToolsPath(out string batchPath)
        {
            var configuration = new SetupConfiguration();
            var enumInstances = configuration.EnumInstances();
            int fetched;
            var instances = new ISetupInstance[1];

            do
            {
                enumInstances.Next(1, instances, out fetched);

                if (fetched <= 0)
                {
                    continue;
                }

                if (!(instances[0] is ISetupInstance2 instance))
                {
                    continue;
                }

                var packages = instance.GetPackages();
                foreach (var package in packages)
                {
                    if (package.GetId() != "Microsoft.VisualStudio.Component.VC.Tools.x86.x64")
                    {
                        continue;
                    }

                    var rootPath = instance.ResolvePath();
                    batchPath = Directory.GetFiles(rootPath, "VsDevCmd.bat", SearchOption.AllDirectories)
                                .FirstOrDefault();

                    return(true);
                }
            } while (fetched > 0);

            batchPath = null;
            return(false);
        }
コード例 #4
0
        public Vs2017SetupConfig()
        {
            try
            {
                _setupConfig = new SetupConfiguration();
            }
            catch (Exception ex)
            {
                throw new Exception($"Cannot create a new SetupConfiguration for Visual Studio", ex);
            }

            var setupConfig2 = (ISetupConfiguration2)_setupConfig;
            var e            = setupConfig2.EnumAllInstances();
            var helper       = (ISetupHelper)_setupConfig;

            int fetched;
            var instances = new ISetupInstance[1];

            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    var instance2    = (ISetupInstance2)instances[0];
                    var instanceInfo = new VSInstanceInfo
                    {
                        Id            = instance2.GetInstanceId(),
                        Name          = instance2.GetInstallationName(),
                        Version       = instance2.GetInstallationVersion(),
                        DispName      = instance2.GetDisplayName(),
                        Description   = instance2.GetDescription(),
                        ResPath       = instance2.ResolvePath(),
                        EnginePath    = instance2.GetEnginePath(),
                        InstalledPath = instance2.GetInstallationPath(),
                        ProductPath   = instance2.GetProductPath()
                    };
                    _instanceInfos.Add(instanceInfo);
                }
            }while (fetched > 0);
        }
コード例 #5
0
        private static string GetPathOfFirstInstalledVisualStudioInstance()
        {
            Tuple <Version, string> highestVersion = null;

            try
            {
                IEnumSetupInstances setupInstances = new SetupConfiguration().EnumAllInstances();

                ISetupInstance[] instances = new ISetupInstance[1];

                for (setupInstances.Next(1, instances, out int fetched); fetched > 0; setupInstances.Next(1, instances, out fetched))
                {
                    ISetupInstance2 instance = (ISetupInstance2)instances.First();

                    if (instance.GetState() == InstanceState.Complete)
                    {
                        string installationPath = instance.GetInstallationPath();

                        if (!string.IsNullOrWhiteSpace(installationPath) && Version.TryParse(instance.GetInstallationVersion(), out Version version))
                        {
                            if (highestVersion == null || version > highestVersion.Item1)
                            {
                                highestVersion = new Tuple <Version, string>(version, installationPath);
                            }
                        }
                    }
                }

                if (highestVersion != null)
                {
                    return(Path.Combine(highestVersion.Item2, "MSBuild", GetMSBuildVersionDirectory($"{highestVersion.Item1.Major}.0"), "Bin"));
                }
            }
            catch
            {
                // Ignored
            }

            return(null);
        }
コード例 #6
0
        /// <summary>
        /// Tries to get all vs 2017 instances.
        /// </summary>
        /// <param name="versions">Collection holding available visual studio instances</param>
        /// <returns>Success of the operation</returns>
        private static bool GetVs2017Instances(ICollection <ToolchainVersion> versions)
        {
            const int REGDB_E_CLASSNOTREG = unchecked ((int)0x80040154);

            try
            {
                var query  = new SetupConfiguration();
                var query2 = (ISetupConfiguration2)query;
                var e      = query2.EnumAllInstances();
                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    e.Next(1, instances, out fetched);
                    if (fetched > 0)
                    {
                        var instance  = (ISetupInstance2)instances[0];
                        var packages  = instance.GetPackages();
                        var toolchain = new ToolchainVersion
                        {
                            Directory = instance.GetInstallationPath() + @"\Common7\IDE",
                            Version   = Single.Parse(instance.GetInstallationVersion().Remove(2)),
                            Value     = null // Not used currently
                        };
                        versions.Add(toolchain);
                    }
                }while (fetched > 0);
            }
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
                Console.WriteLine("The query API is not registered. Assuming no instances are installed.");
                return(false);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
                return(false);
            }
            return(true);
        }
コード例 #7
0
ファイル: VisualStudioWorkloads.cs プロジェクト: nohwnd/sdk
        private static List <ISetupInstance> GetVisualStudioInstances()
        {
            List <ISetupInstance> vsInstances = new();

            try
            {
                SetupConfiguration   setupConfiguration  = new();
                ISetupConfiguration2 setupConfiguration2 = setupConfiguration;
                IEnumSetupInstances  setupInstances      = setupConfiguration2.EnumInstances();
                ISetupInstance[]     instances           = new ISetupInstance[1];
                int fetched = 0;

                do
                {
                    setupInstances.Next(1, instances, out fetched);

                    if (fetched > 0)
                    {
                        ISetupInstance2 instance = (ISetupInstance2)instances[0];

                        // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs
                        // such as community, professional, and enterprise.
                        if (Version.TryParse(instance.GetInstallationVersion(), out Version version) &&
                            version.Major >= 17 &&
                            s_visualStudioProducts.Contains(instance.GetProduct().GetId()))
                        {
                            vsInstances.Add(instances[0]);
                        }
                    }
                }while (fetched > 0);
            }
            catch (COMException e) when(e.ErrorCode == REGDB_E_CLASSNOTREG)
            {
                // Query API not registered, good indication there are no VS installations of 15.0 or later.
                // Other exceptions are passed through since that likely points to a real error.
            }

            return(vsInstances);
        }
コード例 #8
0
        private static IEnumerable <IVisualStudioInfo> DetectNewVisualStudios()
        {
            SetupConfiguration configuration;

            try
            {
                configuration = new SetupConfiguration();
            }
            catch (COMException ex)
            {
                // class not registered, no VS2017+ installations
                if ((uint)ex.HResult == 0x80040154)
                {
                    yield break;
                }

                throw;
            }
            IEnumSetupInstances e = configuration.EnumAllInstances();

            int fetched;

            ISetupInstance[] instances = new ISetupInstance[1];
            do
            {
                e.Next(1, instances, out fetched);
                if (fetched <= 0)
                {
                    continue;
                }

                ISetupInstance2 instance2 = (ISetupInstance2)instances[0];
                string          filename  = Path.Combine(instance2.GetInstallationPath(), @"Common7\IDE\devenv.exe");
                if (File.Exists(filename))
                {
                    yield return(new VisualStudio2017Info(Version.Parse(instance2.GetInstallationVersion()), instance2.GetDisplayName(), filename));
                }
            }while (fetched > 0);
        }
コード例 #9
0
        /// <summary>
        /// Returns the path to the specified version of msbuild.exe or
        /// null if it could not be found
        /// </summary>
        /// <param name="msBuildMajorVersion">MSBuild major version number e.g. 15.0</param>
        private static string GetMSBuildPath(string msBuildMajorVersion, TestContext testContext)
        {
            // Note: we're using a Microsoft component that locates instances of VS, and then
            // we're searching for an expected path under VS.
            // A more robust and flexible approach would be to use https://www.nuget.org/packages/vswhere/
            // which would allow us to search for a specific version of MSBuild directly.
            testContext.WriteLine($"Test setup: attempting to locate an MSBuild instance. Version: {msBuildMajorVersion}");
            ISetupConfiguration config = new SetupConfiguration();

            var instances  = new ISetupInstance[100];
            var enumerator = config.EnumInstances();

            enumerator.Next(100, instances, out int fetched);

            if (fetched == 0)
            {
                throw new InvalidOperationException("Test setup error: no instances of Visual Studio could be located on this machine");
            }

            string partialExePath = Path.Combine("MSBuild", msBuildMajorVersion, "Bin", "msbuild.exe");

            for (int i = 0; i < fetched; i++)
            {
                var instance = instances[i];
                testContext.WriteLine($"\t\tVS instance: {instance.GetDisplayName()}, {instance.GetInstallationVersion()}, {instance.GetInstallationPath()}");

                var candidateExePath = instance.ResolvePath(partialExePath);

                if (File.Exists(candidateExePath))
                {
                    testContext.WriteLine($"\tMSBuild exe located: {candidateExePath}");
                    return(candidateExePath);
                }
            }

            testContext.WriteLine($"Test setup: MSBuild exe could not be located");
            return(null);
        }
コード例 #10
0
ファイル: Configuration.xaml.cs プロジェクト: cswangrf/DiDiWe
        internal void GetVisualStudio()
        {
            SetupInstance tmp = new SetupInstance();

            tmp.DisplayName      = "系统默认";
            tmp.InstallationPath = this.configurationViewMode.DefaultTesthostPath;
            tmp.TestAdapterPath  = this.configurationViewMode.DefaultTestAdaptersPath;
            vs.Add(tmp);
            try
            {
                var query  = new SetupConfiguration();
                var query2 = (ISetupConfiguration2)query;
                var e      = query2.EnumAllInstances();

                var helper = (ISetupHelper)query;

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    e.Next(1, instances, out fetched);
                    if (fetched > 0)
                    {
                        tmp                  = new SetupInstance();
                        tmp.DisplayName      = instances[0].GetDisplayName();
                        tmp.InstallationPath = instances[0].GetInstallationPath() + "\\Common7\\IDE\\Extensions\\TestPlatform\\";
                        tmp.TestAdapterPath  = tmp.InstallationPath + "Extensions\\";
                        vs.Add(tmp);
                    }
                }while (fetched > 0);
            }
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
            }
            catch (Exception)
            {
            }
        }
コード例 #11
0
        private void InvokeVsixInstaller(string tempDir, string rootSuffix)
        {
            var                  process       = System.Diagnostics.Process.GetCurrentProcess();
            var                  dir           = Path.GetDirectoryName(process.MainModule.FileName);
            var                  exe           = Path.Combine(dir, "VSIXInstaller.exe");
            var                  configuration = new SetupConfiguration() as ISetupConfiguration;
            ISetupInstance       instance      = configuration.GetInstanceForCurrentProcess();
            IEnumerable <string> vsixFiles     = Directory.EnumerateFiles(tempDir, "*.vsix").Select(f => Path.GetFileName(f));

            var start = new ProcessStartInfo {
                FileName         = exe,
                Arguments        = $"{string.Join(" ", vsixFiles)} /instanceIds:{instance.GetInstanceId()}",
                WorkingDirectory = tempDir,
                UseShellExecute  = false,
            };

            if (!string.IsNullOrEmpty(rootSuffix))
            {
                start.Arguments += $" /rootSuffix:{rootSuffix}";
            }

            System.Diagnostics.Process.Start(start);
        }
コード例 #12
0
        public List <VisualStudioInstanceData> GetVisualStudioInstallations()
        {
            var visualStudioInstances = new List <VisualStudioInstanceData>();

            var query  = new SetupConfiguration();
            var query2 = (ISetupConfiguration2)query;
            var e      = query2.EnumAllInstances();

            int fetched;
            var instances = new ISetupInstance[1];

            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    var visualStudioInstance = ParseVisualStudioInstanceData(instances[0]);
                    visualStudioInstances.Add(visualStudioInstance);
                }
            }while (fetched > 0);

            return(visualStudioInstances);
        }
コード例 #13
0
        private IEnumerable <(string name, string filePath, Version version)> Enumerate()
        {
            var query  = new SetupConfiguration();
            var query2 = (ISetupConfiguration2)query;
            var e      = query2.EnumAllInstances();

            var helper = (ISetupHelper)query;

            int fetched;
            var instances = new ISetupInstance[1];

            do
            {
                e.Next(1, instances, out fetched);
                if (fetched > 0)
                {
                    if (TryGetInstance(instances[0], helper, out var instance))
                    {
                        yield return(instance);
                    }
                }
            }while (fetched > 0);
        }
コード例 #14
0
        private string GetVSInstallPath()
        {
            var vsPathOverride = Environment.GetEnvironmentVariable("SHARPGEN_VS_OVERRIDE");

            if (!string.IsNullOrEmpty(vsPathOverride))
            {
                return(vsPathOverride);
            }

            try
            {
                var query         = new SetupConfiguration();
                var enumInstances = query.EnumInstances();

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    enumInstances.Next(1, instances, out fetched);
                    if (fetched <= 0)
                    {
                        continue;
                    }

                    var instance2 = (ISetupInstance2)instances[0];
                    var state     = instance2.GetState();
                    if ((state & InstanceState.Registered) != InstanceState.Registered)
                    {
                        continue;
                    }

                    if (instance2.GetPackages().Any(Predicate))
                    {
                        return(instance2.GetInstallationPath());
                    }
                } while (fetched > 0);
コード例 #15
0
ファイル: VsSetup.cs プロジェクト: yannduran/xunit.vsix
        static IEnumerable <ISetupInstance2> EnumerateInstances()
        {
            var query     = (ISetupConfiguration2) new SetupConfiguration();
            var e         = query.EnumAllInstances();
            var helper    = (ISetupHelper)query;
            var instances = new List <ISetupInstance2>();
            var result    = new ISetupInstance[1];
            int fetched;

            do
            {
                e.Next(1, result, out fetched);
                if (fetched > 0)
                {
                    var instance = (ISetupInstance2)result[0];
                    var state    = instance.GetState();
                    if (state == InstanceState.Complete &&
                        (state & InstanceState.Local) == InstanceState.Local)
                    {
                        yield return(instance);
                    }
                }
            } while (fetched > 0);
        }
コード例 #16
0
        /// <summary>
        /// Returns all system includes of the installed VS 2017 instance.
        /// </summary>
        /// <param name="vsDir">Path to the visual studio installation (for identifying the correct instance)</param>
        /// <returns>The system includes</returns>
        private static List <string> GetSystemIncludesVS2017(string vsDir)
        {
            List <string> includes = new List <string>();
            //They includes are in a different folder
            const int REGDB_E_CLASSNOTREG = unchecked ((int)0x80040154);

            try
            {
                var query  = new SetupConfiguration();
                var query2 = (ISetupConfiguration2)query;
                var e      = query2.EnumAllInstances();

                int fetched;
                var instances            = new ISetupInstance[1];
                var regexWinSDK10Version = new Regex(@"Windows10SDK\.(\d+)\.?");
                do
                {
                    e.Next(1, instances, out fetched);
                    if (fetched > 0)
                    {
                        var instance = (ISetupInstance2)instances[0];
                        if (instance.GetInstallationPath() != vsDir)
                        {
                            continue;
                        }
                        var packages = instance.GetPackages();
                        var vc_tools = from package in packages
                                       where package.GetId().Contains("Microsoft.VisualStudio.Component.VC.Tools")
                                       orderby package.GetId()
                                       select package;

                        if (vc_tools.Any())
                        {                         // Tools found, get path
                            var path            = instance.GetInstallationPath();
                            var versionFilePath = path + @"\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt";
                            var version         = System.IO.File.ReadLines(versionFilePath).ElementAt(0).Trim();
                            includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\include");
                            includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\atlmfc\include");
                        }
                        var sdks = from package in packages
                                   where package.GetId().Contains("Windows10SDK") || package.GetId().Contains("Windows81SDK") || package.GetId().Contains("Win10SDK_10")
                                   select package;
                        var win10sdks = from sdk in sdks
                                        where sdk.GetId().Contains("Windows10SDK")
                                        select sdk;
                        var win8sdks = from sdk in sdks
                                       where sdk.GetId().Contains("Windows81SDK")
                                       select sdk;
                        if (win10sdks.Any())
                        {
                            var    sdk          = win10sdks.Last();
                            var    matchVersion = regexWinSDK10Version.Match(sdk.GetId());
                            string path;
                            if (matchVersion.Success)
                            {
                                Environment.SpecialFolder specialFolder = Environment.Is64BitOperatingSystem ?
                                                                          Environment.SpecialFolder.ProgramFilesX86 : Environment.SpecialFolder.ProgramFiles;
                                var programFiles = Environment.GetFolderPath(specialFolder);
                                path = Path.Combine(programFiles, "Windows Kits", "10", "include",
                                                    $"10.0.{matchVersion.Groups[1].Value}.0");
                            }
                            else
                            {
                                path = "<invalid>";
                            }
                            var shared = Path.Combine(path, "shared");
                            var um     = Path.Combine(path, "um");
                            var winrt  = Path.Combine(path, "winrt");
                            var ucrt   = Path.Combine(path, "ucrt");
                            Console.WriteLine(path);
                            if (Directory.Exists(shared) &&
                                Directory.Exists(um) &&
                                Directory.Exists(winrt) &&
                                Directory.Exists(ucrt))
                            {
                                includes.Add(shared);
                                includes.Add(um);
                                includes.Add(winrt);
                                includes.Add(ucrt);
                            }
                        }
                        else if (win8sdks.Any())
                        {
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\shared");
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\um");
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\winrt");
                        }

                        return(includes);                        //We've collected all information.
                    }
                }while (fetched > 0);
            }
            // a COM exception means the VS 2017 COM API (therefore VS itself) is not installed, ignore
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
            }
            return(includes);
        }
コード例 #17
0
        private static List <IDEInfo> BuildIDEInfos()
        {
            var ideInfos = new List <IDEInfo>();

            // Visual Studio 14.0 (2015)
            var localMachine32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);

            using (var subkey = localMachine32.OpenSubKey($@"SOFTWARE\Microsoft\{"VisualStudio"}\{"14.0"}"))
            {
                var path = (string)subkey?.GetValue("InstallDir");

                var vs14InstallPath = (path != null) ? Path.Combine(path, "devenv.exe") : null;
                if (vs14InstallPath != null && File.Exists(vs14InstallPath))
                {
                    var vsixInstallerPath = Path.Combine(path, "VSIXInstaller.exe");
                    if (!File.Exists(vsixInstallerPath))
                    {
                        vsixInstallerPath = null;
                    }

                    ideInfos.Add(new IDEInfo("14.0", "Visual Studio 2015", path)
                    {
                        DevenvPath = vs14InstallPath, VsixInstallerVersion = VSIXInstallerVersion.VS2015, VsixInstallerPath = vsixInstallerPath
                    });
                }
            }

            // Visual Studio 15.0 (2017) and later
            try
            {
                var configuration = new SetupConfiguration();

                var instances = configuration.EnumAllInstances();
                instances.Reset();
                var inst = new ISetupInstance[1];

                while (true)
                {
                    instances.Next(1, inst, out int pceltFetched);
                    if (pceltFetched <= 0)
                    {
                        break;
                    }

                    try
                    {
                        var inst2 = inst[0] as ISetupInstance2;
                        if (inst2 == null)
                        {
                            continue;
                        }

                        var installationPath = inst2.GetInstallationPath();
                        var buildToolsPath   = Path.Combine(installationPath, "MSBuild", "15.0", "Bin");
                        if (!Directory.Exists(buildToolsPath))
                        {
                            buildToolsPath = null;
                        }
                        var idePath    = Path.Combine(installationPath, "Common7", "IDE");
                        var devenvPath = Path.Combine(idePath, "devenv.exe");
                        if (!File.Exists(devenvPath))
                        {
                            devenvPath = null;
                        }
                        var vsixInstallerPath = Path.Combine(idePath, "VSIXInstaller.exe");
                        if (!File.Exists(vsixInstallerPath))
                        {
                            vsixInstallerPath = null;
                        }

                        var displayName = inst2.GetDisplayName();
                        // Try to append nickname (if any)
                        try
                        {
                            var nickname = inst2.GetProperties().GetValue("nickname") as string;
                            if (!string.IsNullOrEmpty(nickname))
                            {
                                displayName = $"{displayName} ({nickname})";
                            }
                        }
                        catch (COMException)
                        {
                        }

                        try
                        {
                            var minimumRequiredState = InstanceState.Local | InstanceState.Registered;
                            if ((inst2.GetState() & minimumRequiredState) != minimumRequiredState)
                            {
                                continue;
                            }
                        }
                        catch (COMException)
                        {
                            continue;
                        }

                        var ideInfo = new IDEInfo(inst2.GetInstallationVersion(), displayName, installationPath, inst2.IsComplete())
                        {
                            BuildToolsPath       = buildToolsPath,
                            DevenvPath           = devenvPath,
                            VsixInstallerVersion = VSIXInstallerVersion.VS2017AndFutureVersions,
                            VsixInstallerPath    = vsixInstallerPath
                        };

                        // Fill packages
                        foreach (var package in inst2.GetPackages())
                        {
                            ideInfo.PackageVersions[package.GetId()] = package.GetVersion();
                        }

                        ideInfos.Add(ideInfo);
                    }
                    catch (Exception)
                    {
                        // Something might have happened inside Visual Studio Setup code (had FileNotFoundException in GetInstallationPath() for example)
                        // Let's ignore this instance
                    }
                }
            }
            catch (COMException comException) when(comException.HResult == REGDB_E_CLASSNOTREG)
            {
                // COM is not registered. Assuming no instances are installed.
            }
            return(ideInfos);
        }
コード例 #18
0
        /// <summary>
        /// Uses the VS SetupConfiguration COM API to resolve a path to a version-specific executable like DevEnv.exe or MSBuild.exe.
        /// </summary>
        /// <param name="buildVersionPath">Used to build a version-specific path to try to resolve.</param>
        /// <param name="minMajorVersion">The minimum major version to look for. This defaults to <see cref="VS2017MajorVersion"/>.</param>
        /// <param name="maxMajorVersion">The maximum major version to look for. This defaults to <see cref="int.MaxValue"/>.</param>
        /// <param name="resolvedPathMustExist">Whether the resolved version-specific path must exist. This defaults to false.</param>
        /// <returns>The resolved path for the highest matched version or null if no version was matched.</returns>
        public static string?ResolvePath(
            Func <Version, string> buildVersionPath,
            int minMajorVersion        = VS2017MajorVersion,
            int maxMajorVersion        = int.MaxValue,
            bool resolvedPathMustExist = false)
        {
            string? result        = null;
            Version?resultVersion = null;

            // VS 2017 and up allow multiple side-by-side editions to be installed, and we have to use a COM API to enumerate the installed instances.
            // https://github.com/mluparu/vs-setup-samples - COM API samples
            // https://code.msdn.microsoft.com/Visual-Studio-Setup-0cedd331 - More Q&A about the COM API samples
            // https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/#comment-273625
            // https://github.com/Microsoft/vswhere - A redistributable .exe for enumerating the VS instances from the command line.
            // https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/
            const int REGDB_E_CLASSNOTREG = -2147221164;             // 0x80040154

            try
            {
                // From MS example: https://github.com/Microsoft/vs-setup-samples/blob/master/Setup.Configuration.CS/Program.cs
                SetupConfiguration configuration = new();

                IEnumSetupInstances instanceEnumerator = configuration.EnumAllInstances();
                int fetched;
                ISetupInstance[] instances = new ISetupInstance[1];
                do
                {
                    instanceEnumerator.Next(1, instances, out fetched);
                    if (fetched > 0)
                    {
                        ISetupInstance instance = instances[0];
                        if (instance != null &&
                            Version.TryParse(instance.GetInstallationVersion(), out Version? version) &&
                            version.Major >= minMajorVersion &&
                            version.Major <= maxMajorVersion)
                        {
                            InstanceState state = ((ISetupInstance2)instance).GetState();
                            if (state == InstanceState.Complete)
                            {
                                string?versionPath = buildVersionPath?.Invoke(version);
                                if (!string.IsNullOrEmpty(versionPath))
                                {
                                    string resolvedPath = instance.ResolvePath(versionPath);
                                    if ((resultVersion == null || resultVersion < version) &&
                                        (!resolvedPathMustExist || File.Exists(resolvedPath) || Directory.Exists(resolvedPath)))
                                    {
                                        result        = resolvedPath;
                                        resultVersion = version;

                                        // If we're looking for a single version, then we don't need to keep looking.
                                        if (minMajorVersion == maxMajorVersion)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }while (fetched > 0);
            }
#pragma warning disable CC0004 // Catch block cannot be empty
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
                // The SetupConfiguration API is not registered, so assume no instances are installed.
            }
            catch (Exception)
            {
                // Heath Stewart (MSFT), the author of the SetupConfiguration API, says to treat any exception as "no instances installed."
                // https://code.msdn.microsoft.com/windowsdesktop/Visual-Studio-Setup-0cedd331/view/Discussions#content
            }
#pragma warning restore CC0004 // Catch block cannot be empty

            return(result);
        }
コード例 #19
0
        public override ImmutableArray <MSBuildInstance> GetInstances()
        {
            if (PlatformHelper.IsMono)
            {
                return(NoInstances);
            }

            try
            {
                var configuration = Interop.GetSetupConfiguration();
                if (configuration == null)
                {
                    return(NoInstances);
                }

                var builder = ImmutableArray.CreateBuilder <MSBuildInstance>();

                var instanceEnum = configuration.EnumAllInstances();

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    instanceEnum.Next(1, instances, out fetched);
                    if (fetched <= 0)
                    {
                        continue;
                    }

                    var instance = (ISetupInstance2)instances[0];
                    var state    = instance.GetState();

                    if (!Version.TryParse(instance.GetInstallationVersion(), out var version))
                    {
                        continue;
                    }

                    if (state == InstanceState.Complete &&
                        instance.GetPackages().Any(package => package.GetId() == "Microsoft.VisualStudio.Component.Roslyn.Compiler"))
                    {
                        // Note: The code below will likely fail if MSBuild's version increments.
                        var toolsPath = Path.Combine(instance.GetInstallationPath(), "MSBuild", "15.0", "Bin");
                        if (Directory.Exists(toolsPath))
                        {
                            builder.Add(
                                new MSBuildInstance(
                                    instance.GetDisplayName(),
                                    toolsPath,
                                    version,
                                    DiscoveryType.VisualStudioSetup));
                        }
                    }
                }while (fetched < 0);

                return(builder.ToImmutable());
            }
            catch (COMException ex)
            {
                return(LogExceptionAndReturnEmpty(ex));
            }
            catch (DllNotFoundException ex)
            {
                // This is OK, since it probably means that VS 2017 or later isn't installed.
                // We'll log the exception for debugging though.
                return(LogExceptionAndReturnEmpty(ex));
            }
        }
コード例 #20
0
        /// <summary>
        /// Returns all system includes of the installed VS 2017 instance.
        /// </summary>
        /// <param name="vsDir">Path to the visual studio installation (for identifying the correct instance)</param>
        /// <returns>The system includes</returns>
        private static List <string> GetSystemIncludesVS2017(string vsDir)
        {
            List <string> includes = new List <string>();
            //They includes are in a different folder
            const int REGDB_E_CLASSNOTREG = unchecked ((int)0x80040154);

            try
            {
                var query  = new SetupConfiguration();
                var query2 = (ISetupConfiguration2)query;
                var e      = query2.EnumAllInstances();

                var helper = (ISetupHelper)query;

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    e.Next(1, instances, out fetched);
                    if (fetched > 0)
                    {
                        var instance = (ISetupInstance2)instances[0];
                        if (instance.GetInstallationPath() != vsDir)
                        {
                            continue;
                        }
                        var packages = instance.GetPackages();
                        var vc_tools = from package in packages
                                       where package.GetId().Contains("Microsoft.VisualStudio.Component.VC.Tools")
                                       orderby package.GetId()
                                       select package;

                        if (vc_tools.Count() > 0)
                        { // Tools found, get path
                            var path            = instance.GetInstallationPath();
                            var versionFilePath = path + @"\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt";
                            var version         = System.IO.File.ReadLines(versionFilePath).ElementAt(0).Trim();
                            includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\include");
                            includes.Add(path + @"\VC\Tools\MSVC\" + version + @"\atlmfc\include");
                        }
                        var sdks = from package in packages
                                   where package.GetId().Contains("Windows10SDK") || package.GetId().Contains("Windows81SDK") || package.GetId().Contains("Win10SDK_10")
                                   select package;
                        var win10sdks = from sdk in sdks
                                        where sdk.GetId().Contains("Windows10SDK")
                                        select sdk;
                        var win8sdks = from sdk in sdks
                                       where sdk.GetId().Contains("Windows81SDK")
                                       select sdk;
                        if (win10sdks.Count() > 0)
                        {
                            var sdk    = win10sdks.Last();
                            var path   = @"C:\Program Files (x86)\Windows Kits\10\include\" + "10.0." + sdk.GetId().Substring(46) + ".0"; //Microsoft.VisualStudio.Component.Windows10SDK. = 46 chars
                            var shared = Path.Combine(path, "shared");
                            var um     = Path.Combine(path, "um");
                            var winrt  = Path.Combine(path, "winrt");
                            var ucrt   = Path.Combine(path, "ucrt");
                            Console.WriteLine(path);
                            if (Directory.Exists(shared) &&
                                Directory.Exists(um) &&
                                Directory.Exists(winrt) &&
                                Directory.Exists(ucrt))
                            {
                                includes.Add(shared);
                                includes.Add(um);
                                includes.Add(winrt);
                                includes.Add(ucrt);
                            }
                        }
                        else if (win8sdks.Count() > 0)
                        {
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\shared");
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\um");
                            includes.Add(@"C:\Program Files (x86)\Windows Kits\8.1\include\winrt");
                        }

                        return(includes); //We've collected all information.
                    }
                }while (fetched > 0);
            }
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
                Console.WriteLine("The query API is not registered. Assuming no instances are installed.");
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
            }
            return(includes);
        }
コード例 #21
0
        /// <summary>
        ///     Query the Visual Studio setup API to get instances of Visual Studio installed
        ///     on the machine. Will not include anything before Visual Studio "15".
        /// </summary>
        /// <returns>Enumerable list of Visual Studio instances</returns>
        internal static IList <VisualStudioInstance> GetInstances()
        {
            var validInstances = new List <VisualStudioInstance>();

            try
            {
                // This code is not obvious. See the sample (link above) for reference.
                var query = (ISetupConfiguration2)GetQuery();
                var e     = query.EnumAllInstances();

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    // Call e.Next to query for the next instance (single item or nothing returned).
                    e.Next(1, instances, out fetched);
                    if (fetched <= 0)
                    {
                        continue;
                    }

                    var           instance = (ISetupInstance2)instances[0];
                    InstanceState state    = instance.GetState();

                    if (!Version.TryParse(instance.GetInstallationVersion(), out Version version))
                    {
                        continue;
                    }

                    // If the install was complete and a valid version, consider it.
                    if (state == InstanceState.Complete ||
                        (state.HasFlag(InstanceState.Registered) && state.HasFlag(InstanceState.NoRebootRequired)))
                    {
                        bool instanceHasMSBuild = false;

                        foreach (ISetupPackageReference package in instance.GetPackages())
                        {
                            if (string.Equals(package.GetId(), "Microsoft.Component.MSBuild", StringComparison.OrdinalIgnoreCase))
                            {
                                instanceHasMSBuild = true;
                                break;
                            }
                        }

                        if (instanceHasMSBuild)
                        {
                            validInstances.Add(new VisualStudioInstance(
                                                   instance.GetDisplayName(),
                                                   instance.GetInstallationPath(),
                                                   version,
                                                   DiscoveryType.VisualStudioSetup));
                        }
                    }
                } while (fetched > 0);
            }
            catch (COMException)
            {
            }
            catch (DllNotFoundException)
            {
                // This is OK, VS "15" or greater likely not installed.
            }
            return(validInstances);
        }
コード例 #22
0
        private static ISetupInstance2?GetLatestPath()
        {
            var result        = default(ISetupInstance2);
            var resultVersion = new Version(0, 0);

            try
            {
                // This code is not obvious. See the sample (link above) for reference.
                var query = (ISetupConfiguration2)GetQuery();
                var e     = query.EnumAllInstances();

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    // Call e.Next to query for the next instance (single item or nothing returned).
                    e.Next(1, instances, out fetched);
                    if (fetched <= 0)
                    {
                        continue;
                    }

                    var instance = (ISetupInstance2)instances[0];
                    var state    = instance.GetState();

                    if (!Version.TryParse(instance.GetInstallationVersion(), out var version))
                    {
                        continue;
                    }

                    // If the install was complete and a valid version, consider it.
                    if (state == InstanceState.Complete ||
                        (state.HasFlag(InstanceState.Registered) && state.HasFlag(InstanceState.NoRebootRequired)))
                    {
                        var instanceHasMSBuild = false;

                        foreach (var package in instance.GetPackages())
                        {
                            if (string.Equals(package.GetId(), "Microsoft.Component.MSBuild", StringComparison.OrdinalIgnoreCase))
                            {
                                instanceHasMSBuild = true;
                                break;
                            }
                        }

                        if (instanceHasMSBuild && instance is not null && version > resultVersion)
                        {
                            result        = instance;
                            resultVersion = version;
                        }
                    }
                }while (fetched > 0);
            }
            catch (COMException)
            {
            }
            catch (DllNotFoundException)
            {
                // This is OK, VS "15" or greater likely not installed.
            }

            return(result);
        }
コード例 #23
0
        //=====================================================================

        /// <summary>
        /// This is used to determine all installed Visual Studio instances
        /// </summary>
        /// <returns>A list of installed Visual Studio instances</returns>
        private static List <VisualStudioInstance> DetermineInstalledInstances()
        {
            var instances = new List <VisualStudioInstance>();

            try
            {
                // VS 2015 and earlier install to a single location pointed to by an environment variable
                string vsPath = Environment.ExpandEnvironmentVariables(@"%VS140COMNTOOLS%\..\IDE");

                if (!String.IsNullOrWhiteSpace(vsPath) && vsPath.IndexOf('%') == -1 &&
                    File.Exists(Path.Combine(vsPath, "devenv.exe")))
                {
                    vsPath = vsPath.Replace(@"\\..", @"\..");

                    instances.Add(new VisualStudioInstance
                    {
                        Version                 = "14.0",
                        DisplayName             = "Visual Studio 2015",
                        InstallationPath        = vsPath,
                        DevEnvPath              = Path.Combine(vsPath, "devenv.exe"),
                        VSIXInstallerPath       = Path.Combine(vsPath, "VSIXInstaller.exe"),
                        AllUsersExtensionsPath  = Path.Combine(vsPath, "Extensions"),
                        XmlSchemaCachePath      = Path.Combine(vsPath, @"..\..\Xml\Schemas"),
                        UserTemplatesBaseFolder = "Visual Studio 2015"
                    });
                }

                // VS 2017 and later install side-by-side and no longer user environment variables to point to
                // their location.  Instead, we query the list of installed versions and editions.
                var query2         = (ISetupConfiguration2) new SetupConfiguration();
                var e              = query2.EnumAllInstances();
                var setupInstances = new ISetupInstance[1];

                int fetched;

                do
                {
                    e.Next(1, setupInstances, out fetched);

                    if (fetched > 0)
                    {
                        var instance2 = (ISetupInstance2)setupInstances[0];
                        var state     = instance2.GetState();

                        if (state == InstanceState.Complete && (state & InstanceState.Local) == InstanceState.Local)
                        {
                            vsPath = instance2.GetInstallationPath();

                            string userTemplatesFolder = null;

                            if (instance2 is ISetupInstanceCatalog instanceCatalog)
                            {
                                var catalogProps = instanceCatalog.GetCatalogInfo();

                                if (catalogProps != null)
                                {
                                    var propNames = catalogProps.GetNames();

                                    if (propNames.Contains("productName") && propNames.Contains("productLineVersion"))
                                    {
                                        string productName        = (string)catalogProps.GetValue("productName"),
                                               productLineVersion = (string)catalogProps.GetValue("productLineVersion");

                                        userTemplatesFolder = $"{productName} {productLineVersion}";
                                    }
                                }
                            }

                            instances.Add(new VisualStudioInstance
                            {
                                Version                 = instance2.GetInstallationVersion(),
                                DisplayName             = instance2.GetDisplayName(),
                                InstallationPath        = vsPath,
                                DevEnvPath              = Path.Combine(vsPath, @"Common7\IDE\devenv.exe"),
                                VSIXInstallerPath       = Path.Combine(vsPath, @"Common7\IDE\VSIXInstaller.exe"),
                                AllUsersExtensionsPath  = Path.Combine(vsPath, @"Common7\IDE\Extensions"),
                                XmlSchemaCachePath      = Path.Combine(vsPath, @"Xml\Schemas"),
                                UserTemplatesBaseFolder = userTemplatesFolder
                            });
                        }
                    }
                } while(fetched > 0);
            }
            catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG)
            {
                // Ignore exceptions.  We'll just assume there are no higher versions installed.
                System.Diagnostics.Debug.WriteLine("The query API is not registered. Assuming no instances are installed.");
            }
            catch (Exception ex)
            {
                // Ignore exceptions.  We just won't list them.
                System.Diagnostics.Debug.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}");
            }

            return(instances.OrderBy(i => i.Version).ThenBy(i => i.DisplayName).ToList());
        }
コード例 #24
0
        public static string GetVSPathInfo()
        {
            string info = "";

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

                var helper = (ISetupHelper)query;

                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();
                        info += $"InstanceId: {instance2.GetInstanceId()} ({(state == InstanceState.Complete ? "Complete" : "Incomplete")})\r\n";

                        var installationVersion = instances[0].GetInstallationVersion();
                        var version             = helper.ParseVersion(installationVersion);

                        info += $"InstallationVersion: {installationVersion} ({version})\r\n";

                        if ((state & InstanceState.Local) == InstanceState.Local)
                        {
                            info += $"InstallationPath: {instance2.GetInstallationPath()}\r\n";
                        }

                        var catalog = instances[0] as ISetupInstanceCatalog;
                        if (catalog != null)
                        {
                            info += $"IsPrerelease: {catalog.IsPrerelease()}\r\n";
                        }

                        if ((state & InstanceState.Registered) == InstanceState.Registered)
                        {
                            info += $"Product: {instance2.GetProduct().GetId()}\r\n" + "Workloads:";
                            var workloads = from package in instance2.GetPackages()
                                            where string.Equals(package.GetType(), "Workload", StringComparison.OrdinalIgnoreCase)
                                            orderby package.GetId()
                                            select package;

                            foreach (var workload in workloads)
                            {
                                info += $"    {workload.GetId()}\r\n";
                            }
                        }

                        var catalogProps1 = instance2.GetProperties();
                        if (catalogProps1 != null)
                        {
                            info += "Custom properties:\r\n";
                            var catalogNames1 = from name in catalogProps1.GetNames()
                                                orderby name
                                                select new { Name = name, Value = catalogProps1.GetValue(name) };

                            foreach (var prop in catalogNames1)
                            {
                                info += $"    {prop.Name}: {prop.Value}\r\n";
                            }
                        }

                        var catalogProps2 = catalog?.GetCatalogInfo();
                        if (catalogProps2 != null)
                        {
                            Console.WriteLine("Catalog properties:");
                            var catalogNames2 = from name in catalogProps2.GetNames()
                                                orderby name
                                                select new { Name = name, Value = catalogProps2.GetValue(name) };

                            foreach (var prop in catalogNames2)
                            {
                                info += $"    {prop.Name}: {prop.Value}\r\n";
                            }
                        }
                    }
                }while (fetched > 0);
            }
            catch (COMException ex) when(Marshal.GetHRForException(ex) == unchecked ((int)0x80040154)) // check if REGDB_E_CLASSNOTREG
            {
                info = "The query API is not registered. Assuming no instances are installed.\r\n";;
            }
            catch (Exception ex)
            {
                info = $"Error 0x{Marshal.GetHRForException(ex):x8}: {ex.Message}\r\n";
            }
            return(info);
        }
コード例 #25
0
ファイル: Program.cs プロジェクト: Nan0Scho1ar/vscli
        private static bool IsPreRelease(ISetupInstance setupInstance)
        {
            ISetupInstanceCatalog setupInstanceCatalog = (ISetupInstanceCatalog)setupInstance;

            return(setupInstanceCatalog.IsPrerelease());
        }
コード例 #26
0
 /// <summary>
 /// This constructor services v15.1+ toolsets
 /// </summary>
 internal MsBuildToolset(ISetupInstance sxsToolset)
 {
     Path        = GetMsBuildDirFromVsDir(sxsToolset.GetInstallationPath());
     Version     = GetMsBuildVersionFromMsBuildDir(Path);
     InstallDate = ConvertFILETIMEToDateTime(sxsToolset.GetInstallDate());
 }
コード例 #27
0
ファイル: VisualStudioVersions.cs プロジェクト: vvvv/stride
        private static List <IDEInfo> BuildIDEInfos()
        {
            var ideInfos = new List <IDEInfo>();

            // Visual Studio 15.0 (2017) and later
            try
            {
                var configuration = new SetupConfiguration();

                var instances = configuration.EnumAllInstances();
                instances.Reset();
                var inst = new ISetupInstance[1];

                while (true)
                {
                    instances.Next(1, inst, out int pceltFetched);
                    if (pceltFetched <= 0)
                    {
                        break;
                    }

                    try
                    {
                        var inst2 = inst[0] as ISetupInstance2;
                        if (inst2 == null)
                        {
                            continue;
                        }

                        // Only deal with VS2019+
                        if (!Version.TryParse(inst2.GetInstallationVersion(), out var version) ||
                            version.Major < 15)
                        {
                            continue;
                        }

                        var installationPath = inst2.GetInstallationPath();
                        var buildToolsPath   = Path.Combine(installationPath, "MSBuild", "Current", "Bin");
                        if (!Directory.Exists(buildToolsPath))
                        {
                            buildToolsPath = null;
                        }
                        var idePath    = Path.Combine(installationPath, "Common7", "IDE");
                        var devenvPath = Path.Combine(idePath, "devenv.exe");
                        if (!File.Exists(devenvPath))
                        {
                            devenvPath = null;
                        }
                        var vsixInstallerPath = Path.Combine(idePath, "VSIXInstaller.exe");
                        if (!File.Exists(vsixInstallerPath))
                        {
                            vsixInstallerPath = null;
                        }

                        var displayName = inst2.GetDisplayName();
                        // Try to append nickname (if any)
                        try
                        {
                            var nickname = inst2.GetProperties().GetValue("nickname") as string;
                            if (!string.IsNullOrEmpty(nickname))
                            {
                                displayName = $"{displayName} ({nickname})";
                            }
                            else
                            {
                                var installationName = inst2.GetInstallationName();
                                // In case of Preview, we have:
                                // "installationName": "VisualStudioPreview/16.4.0-pre.6.0+29519.161"
                                // "channelId": "VisualStudio.16.Preview"
                                if (installationName.Contains("Preview"))
                                {
                                    displayName = displayName + " (Preview)";
                                }
                            }
                        }
                        catch (COMException)
                        {
                        }

                        try
                        {
                            var minimumRequiredState = InstanceState.Local | InstanceState.Registered;
                            if ((inst2.GetState() & minimumRequiredState) != minimumRequiredState)
                            {
                                continue;
                            }
                        }
                        catch (COMException)
                        {
                            continue;
                        }

                        var ideInfo = new IDEInfo(version, displayName, installationPath, inst2.IsComplete())
                        {
                            BuildToolsPath       = buildToolsPath,
                            DevenvPath           = devenvPath,
                            VsixInstallerVersion = VSIXInstallerVersion.VS2019AndFutureVersions,
                            VsixInstallerPath    = vsixInstallerPath,
                        };

                        // Fill packages
                        foreach (var package in inst2.GetPackages())
                        {
                            ideInfo.PackageVersions[package.GetId()] = package.GetVersion();
                        }

                        ideInfos.Add(ideInfo);
                    }
                    catch (Exception)
                    {
                        // Something might have happened inside Visual Studio Setup code (had FileNotFoundException in GetInstallationPath() for example)
                        // Let's ignore this instance
                    }
                }
            }
            catch (COMException comException) when(comException.HResult == REGDB_E_CLASSNOTREG)
            {
                // COM is not registered. Assuming no instances are installed.
            }
            return(ideInfos);
        }
コード例 #28
0
        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();

                        // Lets 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;
                        }

                        // Lets 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;
                            }
                        }

                        // Lets 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);
            }

            // Method 2 - 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);
        }
コード例 #29
0
        /// <summary>
        /// Gets the installed Visual Studio instances (the first item is the latest version).
        /// </summary>
        /// <returns>The install locations.</returns>
        public static IReadOnlyList <VisualStudioInstance> GetInstances()
        {
            if (_installDirs == null)
            {
                _installDirs = new List <VisualStudioInstance>();

                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {
                    // Visual Studio 2017-2020
                    List <VisualStudioInstance> preReleaseInstallDirs = null;
                    try
                    {
                        SetupConfiguration  setup      = new SetupConfiguration();
                        IEnumSetupInstances enumerator = setup.EnumAllInstances();

                        ISetupInstance[] instances = new ISetupInstance[1];
                        while (true)
                        {
                            enumerator.Next(1, instances, out int fetchedCount);
                            if (fetchedCount == 0)
                            {
                                break;
                            }

                            ISetupInstance2 instance = (ISetupInstance2)instances[0];
                            if ((instance.GetState() & InstanceState.Local) == InstanceState.Local)
                            {
                                VisualStudioVersion version;
                                string displayName = instance.GetDisplayName();
                                if (displayName.Contains("2019"))
                                {
                                    version = VisualStudioVersion.VisualStudio2019;
                                }
                                else if (displayName.Contains("2017"))
                                {
                                    version = VisualStudioVersion.VisualStudio2017;
                                }
                                else
                                {
                                    throw new Exception(string.Format("Unknown Visual Studio installation. Display name: {0}", displayName));
                                }

                                var vsInstance = new VisualStudioInstance
                                {
                                    Version = version,
                                    Path    = instance.GetInstallationPath(),
                                };

                                if (instance is ISetupInstanceCatalog catalog && catalog.IsPrerelease())
                                {
                                    if (preReleaseInstallDirs == null)
                                    {
                                        preReleaseInstallDirs = new List <VisualStudioInstance>();
                                    }
                                    preReleaseInstallDirs.Add(vsInstance);
                                }
                                else
                                {
                                    _installDirs.Add(vsInstance);
                                }
                            }
                        }
                    }
コード例 #30
0
        public override ImmutableArray<MSBuildInstance> GetInstances()
        {
            if (PlatformHelper.IsMono)
            {
                return NoInstances;
            }

            try
            {
                var configuration = Interop.GetSetupConfiguration();
                if (configuration == null)
                {
                    return NoInstances;
                }

                var builder = ImmutableArray.CreateBuilder<MSBuildInstance>();

                var instanceEnum = configuration.EnumAllInstances();

                int fetched;
                var instances = new ISetupInstance[1];
                do
                {
                    instanceEnum.Next(1, instances, out fetched);
                    if (fetched <= 0)
                    {
                        continue;
                    }

                    var instance = (ISetupInstance2)instances[0];
                    var state = instance.GetState();

                    var installVersion = instance.GetInstallationVersion();
                    var installPath = instance.GetInstallationPath();

                    if (!Version.TryParse(installVersion, out var version))
                    {
                        Logger.LogDebug($"Found Visual Studio installation with strange version number: {installVersion} ({installPath})");
                        continue;
                    }

                    if (state != InstanceState.Complete)
                    {
                        Logger.LogDebug($"Found incomplete Visual Studio installation ({installPath})");
                        continue;
                    }

                    if (!instance.GetPackages().Any(package => package.GetId() == "Microsoft.VisualStudio.Component.Roslyn.Compiler"))
                    {
                        Logger.LogDebug($"Found Visual Studio installation with no C# package installed ({installPath})");
                        continue;
                    }

                    var msbuildPath = Path.Combine(installPath, "MSBuild");

                    var toolsPath = FindMSBuildToolsPath(msbuildPath);
                    if (toolsPath != null)
                    {
                        builder.Add(
                            new MSBuildInstance(
                                instance.GetDisplayName(),
                                toolsPath,
                                version,
                                DiscoveryType.VisualStudioSetup));
                    }
                }
                while (fetched > 0);

                return builder.ToImmutable();
            }
            catch (COMException ex)
            {
                return LogExceptionAndReturnEmpty(ex);
            }
            catch (DllNotFoundException ex)
            {
                // This is OK, since it probably means that VS 2017 or later isn't installed.
                // We'll log the exception for debugging though.
                return LogExceptionAndReturnEmpty(ex);
            }
        }