答案1
似乎最安全的方法是使用 WMI,快速、简单,返回所需的所有信息。
ManagementObjectSearcher searcher = new ManagementObjectSearcher();
searcher.Query = new SelectQuery("MSFT_VSInstance ", "", new[] { "Caption", "Version", "ProductLocation" });
ManagementObjectCollection collection = searcher.Get();
ManagementObjectCollection.ManagementObjectEnumerator em = collection.GetEnumerator();
while (em.MoveNext())
{
ManagementBaseObject baseObj = em.Current;
if (baseObj.Properties["Version"].Value != null)
{
Debug.WriteLine(baseObj.Properties["Caption"].Value.ToString());
Debug.WriteLine(baseObj.Properties["Version"].Value.ToString());
Debug.WriteLine(baseObj.Properties["ProductLocation"].Value.ToString());
}
}
选择所有感兴趣的属性,在 powershell 中执行“Get-CimInstance MSFT_VSInstance”,您就会看到所有可用的信息。
答案2
如果您需要以编程方式执行此操作,祝您好运! API 在版本之间并不稳定。 我做了一个 C# 解决方案来检测 VS2017,并将版本从 15.0 增加到 16.0 会出现错误 1054。
上面的链接向你展示了多种不同的查找版本的方法,我建议尝试在你的程序或安装中使用它,而不是自己开发解决方案,因为当涉及到 API 兼容性时,MS 会用它最不常用的、最不显眼的 API 把开发人员抛到一边,至少根据我的经验,当涉及到 Visual Studio 主要版本之间的 Visual Studio API 时是这样。
更详细地说,如果您希望检测 Vs2017 和 VS2019,则需要检测 VSWhere.exe 的存在,它将是 Visual Studio 安装程序的标准配置。
我相信这个位置不会改变:%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\Vswhere.exe
您可以通过以下链接找到有关 vswhere 所需的所有信息: https://github.com/microsoft/vswhere 如果您正在使用安装程序,这可能是当前找出 Visual Studio 安装位置的最佳方法。
如果您确实需要一种以编程方式查找安装程序,这是一个我过去用于查找 VS2017 的 COM 实现,但由于某种原因,它无法找到 VS2019。当我将版本增加到 16 时,它对我来说失败了。我可以在代码示例中为您提供这么多,但我不能花时间帮助您让它工作。
_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
_COM_SMARTPTR_TYPEDEF(ISetupInstance2, __uuidof(ISetupInstance2));
_COM_SMARTPTR_TYPEDEF(IEnumSetupInstances, __uuidof(IEnumSetupInstances));
_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
_COM_SMARTPTR_TYPEDEF(ISetupConfiguration2, __uuidof(ISetupConfiguration2));
_COM_SMARTPTR_TYPEDEF(ISetupHelper, __uuidof(ISetupHelper));
_COM_SMARTPTR_TYPEDEF(ISetupPackageReference, __uuidof(ISetupPackageReference));
module_ptr GetQuery(_Outptr_result_maybenull_ ISetupConfiguration** ppQuery);
UINT __stdcall GetVS2017Path(MSIHANDLE hModule)
{
TraceOut(hModule, _T("In GetVS2017Path"), 1);
try
{
int version = 15;
const wstring VCCompilerType(L"Component");
const wstring VCCompilerID(L"Microsoft.VisualStudio.Component.VC.Tools.x86.x64");
CoInitializer init;
ISetupConfigurationPtr query;
auto lib = GetQuery(&query);
ISetupConfiguration2Ptr query2(query);
IEnumSetupInstancesPtr e;
checkResult(query2->EnumAllInstances(&e));
ISetupHelperPtr helper(query);
ISetupInstance* pInstances[1] = { nullptr };
auto hr = e->Next(1, pInstances, nullptr);
while (S_OK == hr)
{
// Wrap instance without AddRef'ing.
ISetupInstancePtr instance(pInstances[0], false);
bstr_t bstrVersion;
checkResult(instance->GetInstallationVersion(bstrVersion.GetAddress()));
ULONGLONG ullVersion;
checkResult(helper->ParseVersion(bstrVersion, &ullVersion));
// get the major version number
ullVersion >>= 48L;
if (ullVersion == version)
{
ISetupInstance2Ptr instance2(instance);
LPSAFEARRAY psa = NULL;
checkResult(instance2->GetPackages(&psa));
safearray_ptr psa_ptr(&psa);
// Lock the SAFEARRAY to get the raw pointer array.
checkResult(::SafeArrayLock(psa));
auto rgpPackages = reinterpret_cast<ISetupPackageReference**>(psa->pvData);
auto cPackages = psa->rgsabound[0].cElements;
if (0 != cPackages)
{
vector< ISetupPackageReference* > packages(rgpPackages, rgpPackages + cPackages);
for (auto pPackage : packages)
{
bstr_t bstrType;
checkResult(pPackage->GetType(bstrType.GetAddress()));
bstr_t bstrID;
checkResult(pPackage->GetId(bstrID.GetAddress()));
if (VCCompilerType == wstring(bstrType) && VCCompilerID == wstring(bstrID))
{
bstr_t bstrInstallationPath;
instance2->GetInstallationPath(bstrInstallationPath.GetAddress());
return ERROR_SUCCESS;
}
}
}
}
hr = e->Next(1, pInstances, NULL);
}
if (FAILED(hr))
{
throw win32_exception(hr, "failed to enumerate all instances");
}
}
catch (win32_exception)
{
return ERROR_INSTALL_FAILURE;
}
catch (exception)
{
return ERROR_INSTALL_FAILURE;
}
return ERROR_INSTALL_FAILURE;
}
void checkResult(HRESULT hr)
{
if (FAILED(hr))
{
throw win32_exception(hr, "call failed");
}
}
答案3
Visual Studio 版本位于注册表项下方
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\<version>
。
上述子项下的名称将定义已安装的 Visual Studio 版本,如下所示:
Visual Studio 6 - 6.0
Visual Studio .NET (2002) - 7.0
Visual Studio .NET 2003 - 7.1
Visual Studio 2005 - 8.0
Visual Studio 2008 - 9.0
Visual Studio 2010 - 10.0
Visual Studio 2012 - 11.0
Visual Studio 2013 - 12.0
Visual Studio 2015 - 14.0
Visual Studio 2017 - 15.0
Visual Studio 2019 - 16.0
根据我的经验,这些是您会找到的版本号,但某些 VS 版本可能在该点后面添加了子版本号。
我可以验证该密钥从 Visual Studio 2008 开始存在,但不能保证早期版本也存在该密钥。