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

<p>I am currently interested in Visual&nbsp;Studio&nbsp;2008 install directory, though it wouldn't hurt to list others for future reference.</p>

[{'answer_id': 30512, 'author': 'ZebZiggle', 'author_id': 2587612, 'author_profile': 'https://Stackoverflow.com/users/2587612', 'pm_score': 4, 'selected': True, 'text': "<p>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.</p>\n"}, {'answer_id': 30524, 'author': 'Emperor XLII', 'author_id': 2495, 'author_profile': 'https://Stackoverflow.com/users/2495', 'pm_score': 3, 'selected': False, 'text': '<p><em>Environment:</em> Thanks to Zeb and Sam for the <code>VS*COMNTOOLS</code> environment variable suggestion. To get to the IDE in PowerShell:</p>\n\n<pre><code>$vs = Join-Path $env:VS90COMNTOOLS \'..\\IDE\\devenv.exe\'\n</code></pre>\n\n<hr>\n\n<p><em>Registry:</em> Looks like the registry location is <code>HKLM\\Software\\Microsoft\\VisualStudio</code>, with version-specific subkeys for each install. In PowerShell:</p>\n\n<pre><code>$vsRegPath = \'HKLM:\\Software\\Microsoft\\VisualStudio\\9.0\'\n$vs = (Get-ItemProperty $vsRegPath).InstallDir + \'devenv.exe\'\n</code></pre>\n\n<p>[Adapted from <a href="http://irfanyar.wordpress.com/2008/06/07/locate-the-installation-directory-of-visual-studio-net-or-any-other-installed-software/" rel="noreferrer">here</a>]</p>\n'}, {'answer_id': 30528, 'author': 'Sam Hasler', 'author_id': 2541, 'author_profile': 'https://Stackoverflow.com/users/2541', 'pm_score': 0, 'selected': False, 'text': '<p>Aren\'t there environment settings?</p>\n\n<p>I have <code>VCToolkitInstallDir</code> and <code>VS71COMNTOOLS</code> although I\'m using Visual&nbsp;Studio&nbsp;2003, I don\'t know if that changed for later versions. Type "set V" at the command line and see if you have them.</p>\n'}, {'answer_id': 387363, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': "<p>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. </p>\n\n<p>Now that wasn't very fun.</p>\n"}, {'answer_id': 2460746, 'author': 'peter', 'author_id': 295486, 'author_profile': 'https://Stackoverflow.com/users/295486', 'pm_score': 2, 'selected': False, 'text': '<p>Use <code>Environment.GetEnvironmentVariable("VS90COMNTOOLS");</code>.</p>\n\n<p>Also in a 64-bit environment, it works for me.</p>\n'}, {'answer_id': 7363241, 'author': 'Dim_Ka', 'author_id': 936971, 'author_profile': 'https://Stackoverflow.com/users/936971', 'pm_score': 4, 'selected': False, 'text': '<p>I use this method to find the installation path of Visual Studio 2010:</p>\n\n<pre><code>    private string GetVisualStudioInstallationPath()\n    {\n        string installationPath = null;\n        if (Environment.Is64BitOperatingSystem)\n        {\n            installationPath = (string)Registry.GetValue(\n               "HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Wow6432Node\\\\Microsoft\\\\VisualStudio\\\\10.0\\\\",\n                "InstallDir",\n                null);\n        }\n        else\n        {\n            installationPath = (string)Registry.GetValue(\n       "HKEY_LOCAL_MACHINE\\\\SOFTWARE  \\\\Microsoft\\\\VisualStudio\\\\10.0\\\\",\n              "InstallDir",\n              null);\n        }\n        return installationPath;\n\n    }\n</code></pre>\n'}, {'answer_id': 8579591, 'author': 'Kevin Kibler', 'author_id': 56739, 'author_profile': 'https://Stackoverflow.com/users/56739', 'pm_score': 3, 'selected': False, 'text': '<h2>Registry Method</h2>\n\n<p>I recommend querying the registry for this information. This gives the actual installation directory without the need for combining paths, and it works for express editions as well. This could be an important distinction depending on what you need to do (e.g. templates get installed to different directories depending on the edition of Visual Studio). The registry locations are as follows (note that Visual Studio is a 32-bit program and will be installed to the 32-bit section of the registry on x64 machines):</p>\n\n<ul>\n<li>Visual Studio: HKLM\\SOFTWARE\\Microsoft\\Visual Studio\\Major.Minor:InstallDir</li>\n<li>Visual C# Express: HKLM\\SOFTWARE\\Microsoft\\VCSExpress\\Major.Minor:InstallDir</li>\n<li>Visual Basic Express: HKLM\\SOFTWARE\\Microsoft\\VBExpress\\Major.Minor:InstallDir</li>\n<li>Visual C++ Express: HKLM\\SOFTWARE\\Microsoft\\VCExpress\\Major.Minor:InstallDir</li>\n</ul>\n\n<p>where Major is the major version number, Minor is the minor version number, and the text after the colon is the name of the registry value. For example, the installation directory of Visual Studio 2008 Professional would be located at the <strong>HKLM\\SOFTWARE\\Microsoft\\Visual Studio\\9.0</strong> key, in the <strong>InstallDir</strong> value.</p>\n\n<p>Here\'s a code example that prints the installation directory of several versions of Visual Studio and Visual C# Express:</p>\n\n<pre><code>string visualStudioRegistryKeyPath = @"SOFTWARE\\Microsoft\\VisualStudio";\nstring visualCSharpExpressRegistryKeyPath = @"SOFTWARE\\Microsoft\\VCSExpress";\n\nList&lt;Version&gt; vsVersions = new List&lt;Version&gt;() { new Version("10.0"), new Version("9.0"), new Version("8.0") };\nforeach (var version in vsVersions)\n{\n    foreach (var isExpress in new bool[] { false, true })\n    {\n        RegistryKey registryBase32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);\n        RegistryKey vsVersionRegistryKey = registryBase32.OpenSubKey(\n            string.Format(@"{0}\\{1}.{2}", (isExpress) ? visualCSharpExpressRegistryKeyPath : visualStudioRegistryKeyPath, version.Major, version.Minor));\n        if (vsVersionRegistryKey == null) { continue; }\n        Console.WriteLine(vsVersionRegistryKey.GetValue("InstallDir", string.Empty).ToString());\n    }\n</code></pre>\n\n<h2>Environment Variable Method</h2>\n\n<p>The non-express editions of Visual Studio also write an environment variable that you could check, but it gives the location of the common tools directory, not the installation directory, so you\'ll have to do some path combining. The format of the environment variable is <strong>VS*COMNTOOLS</strong> where * is the major and minor version number. For example, the environment variable for Visual Studio 2010 is <strong>VS100COMNTOOLS</strong> and contains a value like <strong>C:\\Program Files\\Microsoft Visual Studio 10.0\\Common7\\Tools</strong>.</p>\n\n<p>Here\'s some example code to print the environment variable for several versions of Visual Studio:</p>\n\n<pre><code>List&lt;Version&gt; vsVersions = new List&lt;Version&gt;() { new Version("10.0"), new Version("9.0"), new Version("8.0") };\nforeach (var version in vsVersions)\n{\n    Console.WriteLine(Path.Combine(Environment.GetEnvironmentVariable(string.Format("VS{0}{1}COMNTOOLS", version.Major, version.Minor)), @"..\\IDE"));\n}\n</code></pre>\n'}, {'answer_id': 23328706, 'author': 'Stefan Cepcik', 'author_id': 3579195, 'author_profile': 'https://Stackoverflow.com/users/3579195', 'pm_score': 2, 'selected': False, 'text': '<p>Here\'s a solution to always get the path for the latest version:</p>\n\n<pre><code>$vsEnvVars = (dir Env:).Name -match "VS[0-9]{1,3}COMNTOOLS"\n$latestVs = $vsEnvVars | Sort-Object | Select -Last 1\n$vsPath = Get-Content Env:\\$latestVs\n</code></pre>\n'}, {'answer_id': 26874379, 'author': 'JJS', 'author_id': 26877, 'author_profile': 'https://Stackoverflow.com/users/26877', 'pm_score': 2, 'selected': False, 'text': '<p>@Dim-Ka has a great answer. If you were curious how you\'d implement this in a batch script, this is how.</p>\n\n<pre><code>@echo off\n:: BATCH doesn\'t have logical or, otherwise I\'d use it\nSET platform=\nIF /I [%PROCESSOR_ARCHITECTURE%]==[amd64] set platform=true\nIF /I [%PROCESSOR_ARCHITEW6432%]==[amd64] set platform=true\n\n:: default to VS2012 = 11.0\n:: the Environment variable VisualStudioVersion is set by devenv.exe\n:: if this batch is a child of devenv.exe external tools, we know which version to look at\nif not defined VisualStudioVersion SET VisualStudioVersion=11.0\n\nif defined platform (\nset VSREGKEY=HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\%VisualStudioVersion%\n)  ELSE (\nset VSREGKEY=HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\%VisualStudioVersion%\n)\nfor /f "skip=2 tokens=2,*" %%A in (\'reg query "%VSREGKEY%" /v InstallDir\') do SET VSINSTALLDIR=%%B\n\necho %VSINSTALLDIR%\n</code></pre>\n'}, {'answer_id': 28021605, 'author': 'cniggeler', 'author_id': 4096837, 'author_profile': 'https://Stackoverflow.com/users/4096837', 'pm_score': 0, 'selected': False, 'text': "<p>Note that if you're using Visual Studio Express or Visual C++ Express the keynames contain WDExpress or VCExpress, respectively, instead of VisualStudio.</p>\n"}, {'answer_id': 37842604, 'author': 'eXe', 'author_id': 3962116, 'author_profile': 'https://Stackoverflow.com/users/3962116', 'pm_score': 1, 'selected': False, 'text': '<p>You can read the VSINSTALLDIR environment variable.</p>\n'}, {'answer_id': 55049214, 'author': 'vik_78', 'author_id': 5148765, 'author_profile': 'https://Stackoverflow.com/users/5148765', 'pm_score': 2, 'selected': False, 'text': '<p>For Visual&nbsp;Studio&nbsp;2017 and Visual&nbsp;Studio&nbsp;2019 there is the Setup API from Microsoft.</p>\n\n<p>In C#, just add the NuGet package "Microsoft.VisualStudio.Setup.Configuration.Interop", and use it in this way:</p>\n\n<pre><code>    try {\n        var query = new SetupConfiguration();\n        var query2 = (ISetupConfiguration2)query;\n        var e = query2.EnumAllInstances();\n\n        var helper = (ISetupHelper)query;\n\n        int fetched;\n        var instances = new ISetupInstance[1];\n        do {\n            e.Next(1, instances, out fetched);\n            if (fetched &gt; 0)\n                Console.WriteLine(instances[0].GetInstallationPath());\n        }\n        while (fetched &gt; 0);\n        return 0;\n    }\n    catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG) {\n        Console.WriteLine("The query API is not registered. Assuming no instances are installed.");\n        return 0;\n    }\n</code></pre>\n\n<p>You can find more samples for VC, C#, and VB <a href="https://github.com/Microsoft/vs-setup-samples" rel="nofollow noreferrer">here</a>.</p>\n'}, {'answer_id': 55910148, 'author': 'HanT', 'author_id': 10375413, 'author_profile': 'https://Stackoverflow.com/users/10375413', 'pm_score': 2, 'selected': False, 'text': '<p>It is a real problem that all Visual Studio versions have their own location. So the solutions here proposed are not generic. However, Microsoft has made a utility available for free (including the source code) that solved this problem (i.e. annoyance). It is called <code>vswhere.exe</code> and you can download it from <a href="https://github.com/Microsoft/vswhere/releases/" rel="nofollow noreferrer">here</a>. I am very happy with it, and hopefully it will also do for future releases. It makes the whole discussion on this page redundant.</p>\n'}, {'answer_id': 56410974, 'author': 'SunsetQuest', 'author_id': 2352507, 'author_profile': 'https://Stackoverflow.com/users/2352507', 'pm_score': 1, 'selected': False, 'text': '<p>Here is something I have been updating over the years... (for CudaPAD)</p>\n\n<p><strong>Usage examples:</strong></p>\n\n<pre><code>var vsPath = VS_Tools.GetVSPath(avoidPrereleases:true, requiredWorkload:"NativeDesktop");\nvar vsPath = VS_Tools.GetVSPath();\nvar vsPath = VS_Tools.GetVSPath(specificVersion:"15");\n</code></pre>\n\n<p><strong>The drop-in function:</strong></p>\n\n<pre><code>using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.VisualStudio.Setup.Configuration;\nusing System.IO;\nusing Microsoft.Win32;\n\nstatic class VS_Tools\n{\n    public static string GetVSPath(string specificVersion = "", bool avoidPrereleases = true, string requiredWorkload = "")\n    {\n        string vsPath = "";\n        // Method 1 - use "Microsoft.VisualStudio.Setup.Configuration.SetupConfiguration" method.\n\n        // Note: This code has is a heavily modified version of Heath Stewart\'s code.\n        // original source: (Heath Stewart, May 2016) https://github.com/microsoft/vs-setup-samples/blob/80426ad4ba10b7901c69ac0fc914317eb65deabf/Setup.Configuration.CS/Program.cs\n        try\n        {\n            var e = new SetupConfiguration().EnumAllInstances();\n\n            int fetched;\n            var instances = new ISetupInstance[1];\n            do\n            {\n                e.Next(1, instances, out fetched);\n                if (fetched &gt; 0)\n                {\n                    var instance2 = (ISetupInstance2)instances[0];\n                    var state = instance2.GetState();\n\n                    // Let\'s make sure this install is complete.\n                    if (state != InstanceState.Complete)\n                        continue;\n\n                    // If we have a version to match lets make sure to match it.\n                    if (!string.IsNullOrWhiteSpace(specificVersion))\n                        if (!instances[0].GetInstallationVersion().StartsWith(specificVersion))\n                            continue;\n\n                    // If instances[0] is null then skip\n                    var catalog = instances[0] as ISetupInstanceCatalog;\n                    if (catalog == null)\n                        continue;\n\n                    // If there is not installation path lets skip\n                    if ((state &amp; InstanceState.Local) != InstanceState.Local)\n                        continue;\n\n                    // Let\'s make sure it has the required workload - if one was given.\n                    if (!string.IsNullOrWhiteSpace(requiredWorkload))\n                    {\n                        if ((state &amp; InstanceState.Registered) == InstanceState.Registered)\n                        {\n                            if (!(from package in instance2.GetPackages()\n                                    where string.Equals(package.GetType(), "Workload", StringComparison.OrdinalIgnoreCase)\n                                    where package.GetId().Contains(requiredWorkload)\n                                    orderby package.GetId()\n                                    select package).Any())\n                            {\n                                continue;\n                            }\n                        }\n                        else\n                        {\n                            continue;\n                        }\n                    }\n\n                    // Let\'s save the installation path and make sure it has a value.\n                    vsPath = instance2.GetInstallationPath();\n                    if (string.IsNullOrWhiteSpace(vsPath))\n                        continue;\n\n                    // If specified, avoid Pre-release if possible\n                    if (avoidPrereleases &amp;&amp; catalog.IsPrerelease())\n                        continue;\n\n                    // We found the one we need - lets get out of here\n                    return vsPath;\n                }\n            }\n            while (fetched &gt; 0);\n        }\n        catch (Exception){ }\n\n        if (string.IsNullOrWhiteSpace(vsPath))\n            return vsPath;\n\n        // Fall-back Method: Find the location of visual studio (%VS90COMNTOOLS%\\..\\..\\vc\\vcvarsall.bat)\n        // Note: This code has is a heavily modified version of Kevin Kibler\'s code.\n        // source: (Kevin Kibler, 2014) http://stackoverflow.com/questions/30504/programmatically-retrieve-visual-studio-install-directory\n        List&lt;Version&gt; vsVersions = new List&lt;Version&gt;() { new Version("15.0"), new Version("14.0"),\n            new Version("13.0"), new Version("12.0"), new Version("11.0") };\n        foreach (var version in vsVersions)\n        {\n            foreach (var isExpress in new bool[] { false, true })\n            {\n                RegistryKey registryBase32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);\n                RegistryKey vsVersionRegistryKey = registryBase32.OpenSubKey(\n                    string.Format(@"{0}\\{1}.{2}",\n                    (isExpress) ? @"SOFTWARE\\Microsoft\\VCSExpress" : @"SOFTWARE\\Microsoft\\VisualStudio",\n                    version.Major, version.Minor));\n                if (vsVersionRegistryKey == null) { continue; }\n                string path = vsVersionRegistryKey.GetValue("InstallDir", string.Empty).ToString();\n                if (!string.IsNullOrEmpty(path))\n                {\n                    path = Directory.GetParent(path).Parent.Parent.FullName;\n                    if (File.Exists(path + @"\\VC\\bin\\cl.exe") &amp;&amp; File.Exists(path + @"\\VC\\vcvarsall.bat"))\n                    {\n                        vsPath = path;\n                        break;\n                    }\n                }\n            }\n            if (!string.IsNullOrWhiteSpace(vsPath))\n                break;\n        }\n        return vsPath;\n    }\n}\n</code></pre>\n'}, {'answer_id': 60920478, 'author': 'Eng. M.Hamdy', 'author_id': 8179345, 'author_profile': 'https://Stackoverflow.com/users/8179345', 'pm_score': 0, 'selected': False, 'text': '<p>This is the easiest solution I came with. It works for x86 and x64, regardless of VS version:\nUse \n<code>Environment.GetEnvironmentVariable("VSAPPIDDIR")</code>\nTo get the IDE folder, such as:\n"C:\\Program Files\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE\\" On x86 machine.</p>\n\n<p>You can use that to go to any other directory you want, such as:</p>\n\n<pre><code>Dim x = Environment.GetEnvironmentVariable("VSAPPIDDIR").Trim("\\"c, "/"c)\nx = System.IO.Path.GetDirectoryName(x)\nDim XsdFile = IO.Path.Combine(x, "Packages\\Schemas\\html\\html_5.xsd")\n</code></pre>\n\n<p>In x64 machine XsdFile will refer to:\n"C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\Packages\\Schemas\\html\\html_5.xsd"</p>\n\n<p>Caution: This sems to work with Community edition only!  </p>\n'}, {'answer_id': 65869986, 'author': 'lauxjpn', 'author_id': 2618319, 'author_profile': 'https://Stackoverflow.com/users/2618319', 'pm_score': 1, 'selected': False, 'text': '<p>Nowadays, I use the following <strong>PowerShell</strong> command to get the Visual Studio 2017/2019 path (here with the <code>Common7\\IDE</code> suffix, so it mimics the <code>DevEnvDir</code> property):</p>\n<p><code>Get-ChildItem HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall | foreach { Get-ItemProperty $_.PsPath } | where { $_.DisplayName -like \'*Visual Studio*\' -and $_.InstallLocation.Length -gt 0 } | sort InstallDate -Descending | foreach { (Join-Path $_.InstallLocation \'Common7\\IDE\') } | where { Test-Path $_ } | select -First 1</code></p>\n<p>If you want to execute it from <strong>cmd.exe</strong>, the command would look like this:</p>\n<p><code>powershell.exe -ExecutionPolicy Bypass -Command &quot;Get-ChildItem HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall | foreach { Get-ItemProperty $_.PsPath } | where { $_.DisplayName -like \'*Visual Studio*\' -and $_.InstallLocation.Length -gt 0 } | sort InstallDate -Descending | foreach { (Join-Path $_.InstallLocation \'Common7\\IDE\') } | where { Test-Path $_ } | select -First 1&quot;</code></p>\n<p>I am using it in a C# project, where I use <strong>Rider</strong> instead of Visual Studio as my IDE (of course I could have also just manually setup the <code>DevEnvDir</code> property in Rider\'s settings):</p>\n<pre class="lang-xml prettyprint-override"><code>&lt;Target Name=&quot;MyTarget&quot; BeforeTargets=&quot;Build&quot;&gt;\n  &lt;Exec Condition=&quot;\'$(DevEnvDir)\' == \'\' Or \'$(DevEnvDir)\' == \'*Undefined*\' Or !Exists(\'$(DevEnvDir)\')&quot;\n        Command=&quot;powershell.exe -ExecutionPolicy Bypass -Command &amp;quot;Get-ChildItem HKLM:\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall | foreach { Get-ItemProperty $_.PsPath } | where { $_.DisplayName -like \'*Visual Studio*\' -and $_.InstallLocation.Length -gt 0 } | sort InstallDate -Descending | foreach { (Join-Path $_.InstallLocation \'Common7\\IDE\') } | where { Test-Path $_ } | select -First 1&amp;quot;&quot;\n        ConsoleToMSBuild=&quot;true&quot;&gt;\n    &lt;Output TaskParameter=&quot;ConsoleOutput&quot; PropertyName=&quot;DevEnvDir&quot; /&gt;\n  &lt;/Exec&gt;\n&lt;/Target&gt;\n</code></pre>\n<p>I use it to get the path to the VS command prompt batch files (like <code>vcvars64.bat</code> or <code>vcvarsall.bat</code>), so I can invoke them before calling <code>MIDL.exe</code> to generate a type library for my IDL file, so my .NET 5 COM classes can register a type library for themselves when the <code>comhost.dll</code> is being registered via <code>regsvr32.exe</code>.</p>\n'}]
['https://Stackoverflow.com/questions/30504', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2495/']