【发布时间】:2010-09-07 00:39:38
【问题描述】:
我知道有一个指示安装目录的注册表项,但我不记得它是什么。
我目前对 Visual Studio 2008 安装目录感兴趣,但列出其他目录以供将来参考也无妨。
【问题讨论】:
标签: visual-studio
我知道有一个指示安装目录的注册表项,但我不记得它是什么。
我目前对 Visual Studio 2008 安装目录感兴趣,但列出其他目录以供将来参考也无妨。
【问题讨论】:
标签: visual-studio
我用这个方法找到Visual Studio 2010的安装路径:
private string GetVisualStudioInstallationPath()
{
string installationPath = null;
if (Environment.Is64BitOperatingSystem)
{
installationPath = (string)Registry.GetValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\10.0\\",
"InstallDir",
null);
}
else
{
installationPath = (string)Registry.GetValue(
"HKEY_LOCAL_MACHINE\\SOFTWARE \\Microsoft\\VisualStudio\\10.0\\",
"InstallDir",
null);
}
return installationPath;
}
【讨论】:
我确定也有一个注册表项,但我无法轻松找到它。您也可以使用 VS90COMNTOOLS 环境变量。
【讨论】:
我建议查询注册表以获取此信息。这提供了实际安装目录,无需组合路径,它也适用于快速版本。这可能是一个重要的区别,具体取决于您需要做什么(例如,模板安装到不同的目录,具体取决于 Visual Studio 的版本)。注册表位置如下(注意 Visual Studio 是一个 32 位程序,将安装到 x64 机器上注册表的 32 位部分):
其中 Major 是主要版本号,Minor 是次要版本号,冒号后面的文本是注册表值的名称。例如,Visual Studio 2008 Professional 的安装目录将位于 HKLM\SOFTWARE\Microsoft\Visual Studio\9.0 键的 InstallDir 值中。
这是一个打印几个版本的 Visual Studio 和 Visual C# Express 的安装目录的代码示例:
string visualStudioRegistryKeyPath = @"SOFTWARE\Microsoft\VisualStudio";
string visualCSharpExpressRegistryKeyPath = @"SOFTWARE\Microsoft\VCSExpress";
List<Version> vsVersions = new List<Version>() { new Version("10.0"), new Version("9.0"), new Version("8.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) ? visualCSharpExpressRegistryKeyPath : visualStudioRegistryKeyPath, version.Major, version.Minor));
if (vsVersionRegistryKey == null) { continue; }
Console.WriteLine(vsVersionRegistryKey.GetValue("InstallDir", string.Empty).ToString());
}
Visual Studio 的非 express 版本也写了一个环境变量,你可以检查,但它给出了公共工具目录的位置,而不是安装目录,所以你必须做一些路径组合。环境变量的格式是 VS*COMNTOOLS 其中 * 是主要和次要版本号。例如,Visual Studio 2010 的环境变量是 VS100COMNTOOLS 并包含类似 C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools 的值。
下面是一些示例代码,用于打印多个 Visual Studio 版本的环境变量:
List<Version> vsVersions = new List<Version>() { new Version("10.0"), new Version("9.0"), new Version("8.0") };
foreach (var version in vsVersions)
{
Console.WriteLine(Path.Combine(Environment.GetEnvironmentVariable(string.Format("VS{0}{1}COMNTOOLS", version.Major, version.Minor)), @"..\IDE"));
}
【讨论】:
VSxxxCOMNTOOLS 变量。我想知道没有注册表是否还有另一种方法。
环境:感谢 Zeb 和 Sam 对 VS*COMNTOOLS 环境变量的建议。在 PowerShell 中访问 IDE:
$vs = Join-Path $env:VS90COMNTOOLS '..\IDE\devenv.exe'
注册表: 看起来注册表位置是HKLM\Software\Microsoft\VisualStudio,每次安装都有特定于版本的子项。在 PowerShell 中:
$vsRegPath = 'HKLM:\Software\Microsoft\VisualStudio\9.0'
$vs = (Get-ItemProperty $vsRegPath).InstallDir + 'devenv.exe'
[改编自here]
【讨论】:
对于 Visual Studio 2017 和 Visual Studio 2019,有 Microsoft 的 Setup API。
在C#中,只需添加NuGet包“Microsoft.VisualStudio.Setup.Configuration.Interop”,这样使用即可:
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)
Console.WriteLine(instances[0].GetInstallationPath());
}
while (fetched > 0);
return 0;
}
catch (COMException ex) when (ex.HResult == REGDB_E_CLASSNOTREG) {
Console.WriteLine("The query API is not registered. Assuming no instances are installed.");
return 0;
}
您可以找到更多适用于 VC、C# 和 VB 的示例here。
【讨论】:
@Dim-Ka 有一个很好的答案。如果您对如何在批处理脚本中实现这一点感到好奇,这就是方法。
@echo off
:: BATCH doesn't have logical or, otherwise I'd use it
SET platform=
IF /I [%PROCESSOR_ARCHITECTURE%]==[amd64] set platform=true
IF /I [%PROCESSOR_ARCHITEW6432%]==[amd64] set platform=true
:: default to VS2012 = 11.0
:: the Environment variable VisualStudioVersion is set by devenv.exe
:: if this batch is a child of devenv.exe external tools, we know which version to look at
if not defined VisualStudioVersion SET VisualStudioVersion=11.0
if defined platform (
set VSREGKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%VisualStudioVersion%
) ELSE (
set VSREGKEY=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%VisualStudioVersion%
)
for /f "skip=2 tokens=2,*" %%A in ('reg query "%VSREGKEY%" /v InstallDir') do SET VSINSTALLDIR=%%B
echo %VSINSTALLDIR%
【讨论】:
真正的问题是所有 Visual Studio 版本都有自己的位置。所以这里提出的解决方案不是通用的。然而,微软已经免费提供了一个实用程序(包括源代码)来解决这个问题(即烦恼)。它被称为vswhere.exe,您可以从here 下载它。我对它非常满意,希望它也适用于未来的版本。它使此页面上的整个讨论变得多余。
【讨论】:
啊,64 位机器部分是问题所在。事实证明,我需要确保在 syswow64 目录下运行 PowerShell.exe 才能获取 x86 注册表项。
现在这不是很有趣。
【讨论】:
使用Environment.GetEnvironmentVariable("VS90COMNTOOLS");。
在 64 位环境中,它也适用于我。
【讨论】:
您可以读取 VSINSTALLDIR 环境变量。
【讨论】:
这是始终获取最新版本路径的解决方案:
$vsEnvVars = (dir Env:).Name -match "VS[0-9]{1,3}COMNTOOLS"
$latestVs = $vsEnvVars | Sort-Object | Select -Last 1
$vsPath = Get-Content Env:\$latestVs
【讨论】:
现在,我使用以下 PowerShell 命令获取 Visual Studio 2017/2019 路径(此处带有 Common7\IDE 后缀,因此它模仿了 DevEnvDir 属性):
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
如果你想从 cmd.exe 执行它,命令应该是这样的:
powershell.exe -ExecutionPolicy Bypass -Command "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"
我在一个 C# 项目中使用它,我使用 Rider 而不是 Visual Studio 作为我的 IDE(当然我也可以在 Rider 的设置中手动设置 DevEnvDir 属性):
<Target Name="MyTarget" BeforeTargets="Build">
<Exec Condition="'$(DevEnvDir)' == '' Or '$(DevEnvDir)' == '*Undefined*' Or !Exists('$(DevEnvDir)')"
Command="powershell.exe -ExecutionPolicy Bypass -Command "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""
ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="DevEnvDir" />
</Exec>
</Target>
我使用它来获取 VS 命令提示符批处理文件的路径(例如 vcvars64.bat 或 vcvarsall.bat),因此我可以在调用 MIDL.exe 之前调用它们来为我的 IDL 文件生成类型库,所以我的当通过regsvr32.exe 注册comhost.dll 时,.NET 5 COM 类可以为自己注册一个类型库。
【讨论】:
请注意,如果您使用的是 Visual Studio Express 或 Visual C++ Express,则键名分别包含 WDExpress 或 VCExpress,而不是 VisualStudio。
【讨论】:
没有环境设置吗?
我有 VCToolkitInstallDir 和 VS71COMNTOOLS 虽然我使用的是 Visual Studio 2003,但我不知道以后的版本是否会改变。在命令行输入“set V”,看看有没有。
【讨论】:
这是我多年来一直在更新的内容...(用于 CudaPAD)
用法示例:
var vsPath = VS_Tools.GetVSPath(avoidPrereleases:true, requiredWorkload:"NativeDesktop");
var vsPath = VS_Tools.GetVSPath();
var vsPath = VS_Tools.GetVSPath(specificVersion:"15");
插件功能:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.Setup.Configuration;
using System.IO;
using Microsoft.Win32;
static class VS_Tools
{
public static string GetVSPath(string specificVersion = "", bool avoidPrereleases = true, string requiredWorkload = "")
{
string vsPath = "";
// Method 1 - use "Microsoft.VisualStudio.Setup.Configuration.SetupConfiguration" method.
// Note: This code has is a heavily modified version of Heath Stewart's code.
// original source: (Heath Stewart, May 2016) https://github.com/microsoft/vs-setup-samples/blob/80426ad4ba10b7901c69ac0fc914317eb65deabf/Setup.Configuration.CS/Program.cs
try
{
var e = new SetupConfiguration().EnumAllInstances();
int fetched;
var instances = new ISetupInstance[1];
do
{
e.Next(1, instances, out fetched);
if (fetched > 0)
{
var instance2 = (ISetupInstance2)instances[0];
var state = instance2.GetState();
// Let's make sure this install is complete.
if (state != InstanceState.Complete)
continue;
// If we have a version to match lets make sure to match it.
if (!string.IsNullOrWhiteSpace(specificVersion))
if (!instances[0].GetInstallationVersion().StartsWith(specificVersion))
continue;
// If instances[0] is null then skip
var catalog = instances[0] as ISetupInstanceCatalog;
if (catalog == null)
continue;
// If there is not installation path lets skip
if ((state & InstanceState.Local) != InstanceState.Local)
continue;
// Let's make sure it has the required workload - if one was given.
if (!string.IsNullOrWhiteSpace(requiredWorkload))
{
if ((state & InstanceState.Registered) == InstanceState.Registered)
{
if (!(from package in instance2.GetPackages()
where string.Equals(package.GetType(), "Workload", StringComparison.OrdinalIgnoreCase)
where package.GetId().Contains(requiredWorkload)
orderby package.GetId()
select package).Any())
{
continue;
}
}
else
{
continue;
}
}
// Let's save the installation path and make sure it has a value.
vsPath = instance2.GetInstallationPath();
if (string.IsNullOrWhiteSpace(vsPath))
continue;
// If specified, avoid Pre-release if possible
if (avoidPrereleases && catalog.IsPrerelease())
continue;
// We found the one we need - lets get out of here
return vsPath;
}
}
while (fetched > 0);
}
catch (Exception){ }
if (string.IsNullOrWhiteSpace(vsPath))
return vsPath;
// Fall-back Method: Find the location of visual studio (%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat)
// Note: This code has is a heavily modified version of Kevin Kibler's code.
// source: (Kevin Kibler, 2014) http://stackoverflow.com/questions/30504/programmatically-retrieve-visual-studio-install-directory
List<Version> vsVersions = new List<Version>() { new Version("15.0"), new Version("14.0"),
new Version("13.0"), new Version("12.0"), new Version("11.0") };
foreach (var version in vsVersions)
{
foreach (var isExpress in new bool[] { false, true })
{
RegistryKey registryBase32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
RegistryKey vsVersionRegistryKey = registryBase32.OpenSubKey(
string.Format(@"{0}\{1}.{2}",
(isExpress) ? @"SOFTWARE\Microsoft\VCSExpress" : @"SOFTWARE\Microsoft\VisualStudio",
version.Major, version.Minor));
if (vsVersionRegistryKey == null) { continue; }
string path = vsVersionRegistryKey.GetValue("InstallDir", string.Empty).ToString();
if (!string.IsNullOrEmpty(path))
{
path = Directory.GetParent(path).Parent.Parent.FullName;
if (File.Exists(path + @"\VC\bin\cl.exe") && File.Exists(path + @"\VC\vcvarsall.bat"))
{
vsPath = path;
break;
}
}
}
if (!string.IsNullOrWhiteSpace(vsPath))
break;
}
return vsPath;
}
}
【讨论】:
这是我提供的最简单的解决方案。它适用于 x86 和 x64,无论 VS 版本如何:
采用
Environment.GetEnvironmentVariable("VSAPPIDDIR")
获取IDE文件夹,如:
"C:\Program Files\Microsoft Visual Studio\2019\Community\Common7\IDE\" 在 x86 机器上。
您可以使用它转到您想要的任何其他目录,例如:
Dim x = Environment.GetEnvironmentVariable("VSAPPIDDIR").Trim("\"c, "/"c)
x = System.IO.Path.GetDirectoryName(x)
Dim XsdFile = IO.Path.Combine(x, "Packages\Schemas\html\html_5.xsd")
在 x64 机器中 XsdFile 将引用: "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Packages\Schemas\html\html_5.xsd"
注意:这似乎仅适用于社区版!
【讨论】: