Como detectar a edição do Visual Studio programaticamente?
772
Desejo detectar programaticamente a versão do Visual Studio instalado. Eu já tentei isso e isso , mas não consigo encontrar a chave vsno registro. Eu tentei no Visual Studio Community 2017.
Se você precisa fazer isso programaticamente, boa sorte! As APIs não são estáveis entre as versões. Fiz uma solução C# para detectar o VS2017 e incrementar a versão de 15.0 para 16.0 dá o erro 1054.
O link acima mostra várias maneiras diferentes de encontrar as versões disponíveis e eu recomendo tentar usar isso para o seu programa ou instalação, em vez de criar uma solução caseira, porque quando se trata de compatibilidade de API, o MS meio que joga os desenvolvedores aos lobos com é mais discreto, não é muito usado API's Pelo menos na minha experiência quando se trata de APIs do Visual Studio entre a versão principal do Visual Studio.
Para ser mais elaborado, se você deseja detectar o Vs2017 e o VS2019, é necessário detectar a existência do VSWhere.exe, que virá como padrão do instalador do Visual Studio.
Acredito que este local não mude: %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\Vswhere.exe
você pode encontrar todas as informações necessárias sobre vswhere através deste link:
https://github.com/microsoft/vswhere
Se você estiver usando um instalador, esta é provavelmente a melhor maneira atual de descobrir a localização das instalações do Visual Studio.
Se você realmente precisa de uma maneira programática de encontrar o instalador, esta é uma implementação COM que usei no passado para localizar o VS2017, mas isso falha ao encontrar o VS2019 por algum motivo para mim. Quando incremento a versão para 16, ela falha para mim. Posso oferecer a você isso em um exemplo de código, mas não posso perder tempo ajudando você a fazer isso funcionar.
_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");
}
}
A edição do Visual Studio está localizada abaixo da chave do registro HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\<version>.
O nome da(s) subchave(s) abaixo definirá(ão) a(s) edição(ões) do Visual Studio instalada(s), da seguinte forma:
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
Na minha experiência, esses são os números de versão que você encontrará, mas é sempre possível que alguma versão do VS tenha adicionado um número de subversão após o ponto.
Pude verificar se essa chave existe a partir do Visual Studio 2008, mas não posso garantir isso para versões anteriores.
https://docs.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2019
Se você precisa fazer isso programaticamente, boa sorte! As APIs não são estáveis entre as versões. Fiz uma solução C# para detectar o VS2017 e incrementar a versão de 15.0 para 16.0 dá o erro 1054.
O link acima mostra várias maneiras diferentes de encontrar as versões disponíveis e eu recomendo tentar usar isso para o seu programa ou instalação, em vez de criar uma solução caseira, porque quando se trata de compatibilidade de API, o MS meio que joga os desenvolvedores aos lobos com é mais discreto, não é muito usado API's Pelo menos na minha experiência quando se trata de APIs do Visual Studio entre a versão principal do Visual Studio.
Para ser mais elaborado, se você deseja detectar o Vs2017 e o VS2019, é necessário detectar a existência do VSWhere.exe, que virá como padrão do instalador do Visual Studio.
Acredito que este local não mude: %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\Vswhere.exe
você pode encontrar todas as informações necessárias sobre vswhere através deste link: https://github.com/microsoft/vswhere Se você estiver usando um instalador, esta é provavelmente a melhor maneira atual de descobrir a localização das instalações do Visual Studio.
Se você realmente precisa de uma maneira programática de encontrar o instalador, esta é uma implementação COM que usei no passado para localizar o VS2017, mas isso falha ao encontrar o VS2019 por algum motivo para mim. Quando incremento a versão para 16, ela falha para mim. Posso oferecer a você isso em um exemplo de código, mas não posso perder tempo ajudando você a fazer isso funcionar.
A edição do Visual Studio está localizada abaixo da chave do registro
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DevDiv\vs\Servicing\<version>
.O nome da(s) subchave(s) abaixo definirá(ão) a(s) edição(ões) do Visual Studio instalada(s), da seguinte forma:
Na minha experiência, esses são os números de versão que você encontrará, mas é sempre possível que alguma versão do VS tenha adicionado um número de subversão após o ponto.
Pude verificar se essa chave existe a partir do Visual Studio 2008, mas não posso garantir isso para versões anteriores.