如何以编程方式检测 Visual Studio 版本?

如何以编程方式检测 Visual Studio 版本?

我想通过编程检测已安装的 Visual Studio 版本。我已经尝试过但我在注册表中找不到该密钥vs。我尝试在 Visual Studio Community 2017 上进行操作。

有什么帮助吗?

答案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

https://docs.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2019

如果您需要以编程方式执行此操作,祝您好运! 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 开始存在,但不能保证早期版本也存在该密钥。

相关内容