/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #pragma once #ifndef NOMINMAX # define NOMINMAX // Undefine min and max defined by windows.h #endif // Published by Visual Studio Setup team #include #include #include #include template class SmartCOMPtr { public: SmartCOMPtr() = default; SmartCOMPtr(T* p) { ptr = p; if (ptr) { ptr->AddRef(); } } SmartCOMPtr(const SmartCOMPtr& sptr) { ptr = sptr.ptr; if (ptr) { ptr->AddRef(); } } T** operator&() { return &ptr; } T* operator->() { return ptr; } T* operator=(T* p) { if (*this != p) { ptr = p; if (ptr) { ptr->AddRef(); } } return *this; } operator T*() const { return ptr; } template HRESULT QueryInterface(REFCLSID rclsid, I** pp) { if (pp) { return ptr->QueryInterface(rclsid, (void**)pp); } return E_FAIL; } HRESULT CoCreateInstance(REFCLSID clsid, IUnknown* pUnknown, REFIID interfaceId, DWORD dwClsContext = CLSCTX_ALL) { HRESULT hr = ::CoCreateInstance(clsid, pUnknown, dwClsContext, interfaceId, (void**)&ptr); return hr; } ~SmartCOMPtr() { if (ptr) { ptr->Release(); } } private: T* ptr = nullptr; }; class SmartBSTR { public: SmartBSTR() = default; SmartBSTR(const SmartBSTR& src) = delete; SmartBSTR& operator=(const SmartBSTR& src) = delete; operator BSTR() const { return str; } BSTR* operator&() throw() { return &str; } ~SmartBSTR() throw() { ::SysFreeString(str); } private: BSTR str = nullptr; }; struct VSInstanceInfo { std::string VSInstallLocation; std::string Version; std::string VCToolsetVersion; bool IsWin10SDKInstalled = false; bool IsWin81SDKInstalled = false; std::string GetInstallLocation() const; }; class cmVSSetupAPIHelper { public: cmVSSetupAPIHelper(unsigned int version); ~cmVSSetupAPIHelper(); bool SetVSInstance(std::string const& vsInstallLocation, std::string const& vsInstallVersion); bool IsVSInstalled(); bool GetVSInstanceInfo(std::string& vsInstallLocation); bool GetVSInstanceVersion(std::string& vsInstanceVersion); bool GetVCToolsetVersion(std::string& vsToolsetVersion); bool IsWin10SDKInstalled(); bool IsWin81SDKInstalled(); private: bool Initialize(); bool GetVSInstanceInfo(SmartCOMPtr instance2, VSInstanceInfo& vsInstanceInfo); bool CheckInstalledComponent(SmartCOMPtr package, bool& bWin10SDK, bool& bWin81SDK); int ChooseVSInstance(const std::vector& vecVSInstances); bool EnumerateAndChooseVSInstance(); bool LoadSpecifiedVSInstanceFromDisk(); bool EnumerateVSInstancesWithVswhere( std::vector& VSInstances); bool EnumerateVSInstancesWithCOM(std::vector& VSInstances); unsigned int Version; // COM ptrs to query about VS instances SmartCOMPtr setupConfig; SmartCOMPtr setupConfig2; SmartCOMPtr setupHelper; // used to indicate failure in Initialize(), so we don't have to call again bool initializationFailure = false; // indicated if COM initialization is successful HRESULT comInitialized; // current best instance of VS selected VSInstanceInfo chosenInstanceInfo; bool IsEWDKEnabled(); std::string SpecifiedVSInstallLocation; std::string SpecifiedVSInstallVersion; };