cmVSSetupHelper.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #ifndef cmVSSetupHelper_h
  4. #define cmVSSetupHelper_h
  5. #ifndef NOMINMAX
  6. #define NOMINMAX // Undefine min and max defined by windows.h
  7. #endif
  8. // Published by Visual Studio Setup team
  9. #include "cmvssetup/Setup.Configuration.h"
  10. #include <string>
  11. #include <vector>
  12. #include <windows.h>
  13. template <class T>
  14. class SmartCOMPtr
  15. {
  16. public:
  17. SmartCOMPtr() { ptr = NULL; }
  18. SmartCOMPtr(T* p)
  19. {
  20. ptr = p;
  21. if (ptr != NULL)
  22. ptr->AddRef();
  23. }
  24. SmartCOMPtr(const SmartCOMPtr<T>& sptr)
  25. {
  26. ptr = sptr.ptr;
  27. if (ptr != NULL)
  28. ptr->AddRef();
  29. }
  30. T** operator&() { return &ptr; }
  31. T* operator->() { return ptr; }
  32. T* operator=(T* p)
  33. {
  34. if (*this != p) {
  35. ptr = p;
  36. if (ptr != NULL)
  37. ptr->AddRef();
  38. }
  39. return *this;
  40. }
  41. operator T*() const { return ptr; }
  42. template <class I>
  43. HRESULT QueryInterface(REFCLSID rclsid, I** pp)
  44. {
  45. if (pp != NULL) {
  46. return ptr->QueryInterface(rclsid, (void**)pp);
  47. } else {
  48. return E_FAIL;
  49. }
  50. }
  51. HRESULT CoCreateInstance(REFCLSID clsid, IUnknown* pUnknown,
  52. REFIID interfaceId, DWORD dwClsContext = CLSCTX_ALL)
  53. {
  54. HRESULT hr = ::CoCreateInstance(clsid, pUnknown, dwClsContext, interfaceId,
  55. (void**)&ptr);
  56. return hr;
  57. }
  58. ~SmartCOMPtr()
  59. {
  60. if (ptr != NULL)
  61. ptr->Release();
  62. }
  63. private:
  64. T* ptr;
  65. };
  66. class SmartBSTR
  67. {
  68. public:
  69. SmartBSTR() { str = NULL; }
  70. SmartBSTR(const SmartBSTR& src)
  71. {
  72. if (src.str != NULL) {
  73. str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
  74. } else {
  75. str = ::SysAllocStringByteLen(NULL, 0);
  76. }
  77. }
  78. SmartBSTR& operator=(const SmartBSTR& src)
  79. {
  80. if (str != src.str) {
  81. ::SysFreeString(str);
  82. if (src.str != NULL) {
  83. str = ::SysAllocStringByteLen((char*)str, ::SysStringByteLen(str));
  84. } else {
  85. str = ::SysAllocStringByteLen(NULL, 0);
  86. }
  87. }
  88. return *this;
  89. }
  90. operator BSTR() const { return str; }
  91. BSTR* operator&() throw() { return &str; }
  92. ~SmartBSTR() throw() { ::SysFreeString(str); }
  93. private:
  94. BSTR str;
  95. };
  96. struct VSInstanceInfo
  97. {
  98. std::wstring InstanceId;
  99. std::wstring VSInstallLocation;
  100. std::wstring Version;
  101. ULONGLONG ullVersion;
  102. bool IsWin10SDKInstalled;
  103. bool IsWin81SDKInstalled;
  104. VSInstanceInfo()
  105. {
  106. InstanceId = VSInstallLocation = Version = L"";
  107. ullVersion = 0;
  108. IsWin10SDKInstalled = IsWin81SDKInstalled = false;
  109. }
  110. std::string GetInstallLocation() const;
  111. };
  112. class cmVSSetupAPIHelper
  113. {
  114. public:
  115. cmVSSetupAPIHelper();
  116. ~cmVSSetupAPIHelper();
  117. bool SetVSInstance(std::string const& vsInstallLocation);
  118. bool IsVS2017Installed();
  119. bool GetVSInstanceInfo(std::string& vsInstallLocation);
  120. bool IsWin10SDKInstalled();
  121. bool IsWin81SDKInstalled();
  122. private:
  123. bool Initialize();
  124. bool GetVSInstanceInfo(SmartCOMPtr<ISetupInstance2> instance2,
  125. VSInstanceInfo& vsInstanceInfo);
  126. bool CheckInstalledComponent(SmartCOMPtr<ISetupPackageReference> package,
  127. bool& bWin10SDK, bool& bWin81SDK);
  128. int ChooseVSInstance(const std::vector<VSInstanceInfo>& vecVSInstances);
  129. bool EnumerateAndChooseVSInstance();
  130. // COM ptrs to query about VS instances
  131. SmartCOMPtr<ISetupConfiguration> setupConfig;
  132. SmartCOMPtr<ISetupConfiguration2> setupConfig2;
  133. SmartCOMPtr<ISetupHelper> setupHelper;
  134. // used to indicate failure in Initialize(), so we don't have to call again
  135. bool initializationFailure;
  136. // indicated if COM initialization is successful
  137. HRESULT comInitialized;
  138. // current best instance of VS selected
  139. VSInstanceInfo chosenInstanceInfo;
  140. std::string SpecifiedVSInstallLocation;
  141. };
  142. #endif