From f85913fa088f03532ac791735c24d25937b93c7b Mon Sep 17 00:00:00 2001 From: Niyas Sait Date: Mon, 11 Apr 2022 16:30:51 +0100 Subject: VS: Add support for enumerating VS instances with vswhere --- Source/cmVSSetupHelper.cxx | 58 ++++++++++++++++++++++++++++++++++++++++++++-- Source/cmVSSetupHelper.h | 2 ++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx index 49ad441..1a3e72e 100644 --- a/Source/cmVSSetupHelper.cxx +++ b/Source/cmVSSetupHelper.cxx @@ -4,6 +4,11 @@ #include +#if !defined(CMAKE_BOOTSTRAP) +# include +# include +#endif + #include "cmsys/Encoding.hxx" #include "cmsys/FStream.hxx" @@ -295,6 +300,54 @@ bool cmVSSetupAPIHelper::IsEWDKEnabled() return false; } +bool cmVSSetupAPIHelper::EnumerateVSInstancesWithVswhere( + std::vector& VSInstances) +{ +#if !defined(CMAKE_BOOTSTRAP) + // Construct vswhere command to get installed VS instances in JSON format + std::string vswhereExe = getenv("ProgramFiles(x86)") + + std::string(R"(\Microsoft Visual Studio\Installer\vswhere.exe)"); + std::vector vswhereCmd = { vswhereExe, "-format", "json" }; + + // Execute vswhere command and capture JSON output + std::string json_output; + int retVal = 1; + if (!cmSystemTools::RunSingleCommand(vswhereCmd, &json_output, &json_output, + &retVal, nullptr, + cmSystemTools::OUTPUT_NONE)) { + return false; + } + + // Parse JSON output and iterate over elements + Json::CharReaderBuilder builder; + auto jsonReader = std::unique_ptr(builder.newCharReader()); + Json::Value json; + std::string error; + + if (!jsonReader->parse(json_output.data(), + json_output.data() + json_output.size(), &json, + &error)) { + return false; + } + + for (const auto& item : json) { + VSInstanceInfo instance; + instance.Version = item["installationVersion"].asString(); + instance.VSInstallLocation = item["installationPath"].asString(); + instance.IsWin10SDKInstalled = true; + instance.IsWin81SDKInstalled = false; + cmSystemTools::ConvertToUnixSlashes(instance.VSInstallLocation); + if (LoadVSInstanceVCToolsetVersion(instance)) { + VSInstances.push_back(instance); + } + } + return true; +#else + static_cast(VSInstances); + return false; +#endif +} + bool cmVSSetupAPIHelper::EnumerateVSInstancesWithCOM( std::vector& VSInstances) { @@ -371,8 +424,9 @@ bool cmVSSetupAPIHelper::EnumerateAndChooseVSInstance() std::vector vecVSInstancesAll; - // Enumerate VS instances with COM interface - if (!EnumerateVSInstancesWithCOM(vecVSInstancesAll)) { + // Enumerate VS instances with either COM interface or Vswhere + if (!EnumerateVSInstancesWithCOM(vecVSInstancesAll) && + !EnumerateVSInstancesWithVswhere(vecVSInstancesAll)) { return false; } diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h index e7a276e..a16f00b 100644 --- a/Source/cmVSSetupHelper.h +++ b/Source/cmVSSetupHelper.h @@ -118,6 +118,8 @@ private: int ChooseVSInstance(const std::vector& vecVSInstances); bool EnumerateAndChooseVSInstance(); bool LoadSpecifiedVSInstanceFromDisk(); + bool EnumerateVSInstancesWithVswhere( + std::vector& VSInstances); bool EnumerateVSInstancesWithCOM(std::vector& VSInstances); unsigned int Version; -- cgit v0.12