summaryrefslogtreecommitdiffstats
path: root/src/mspdb.cpp
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2021-10-29 11:37:37 (GMT)
committerJohannes Schindelin <johannes.schindelin@gmx.de>2021-11-03 13:51:32 (GMT)
commit88eca5e86458b72180c0ba011542274e9b7ca48a (patch)
tree942ba8684eed2a86b2251a0e656571061f6e1da7 /src/mspdb.cpp
parent9c0e83fc59829902c37c5b296f3a96c5bc098d57 (diff)
downloadcv2pdb-88eca5e86458b72180c0ba011542274e9b7ca48a.zip
cv2pdb-88eca5e86458b72180c0ba011542274e9b7ca48a.tar.gz
cv2pdb-88eca5e86458b72180c0ba011542274e9b7ca48a.tar.bz2
Allow the mspdb DLL to be found via vswhere.exe
The incredibly useful `vswhere.exe` tool can be used to abstract away all the nitty-gritty details of figuring out where Visual Studio is installed. This patch adds support for making use of that tool. Since spawning a process is pretty expensive compared to looking at the registry, we only fall back on this tool (if it exists) if the other methods to find the DLL have failed. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Diffstat (limited to 'src/mspdb.cpp')
-rw-r--r--src/mspdb.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/mspdb.cpp b/src/mspdb.cpp
index 4267ac8..9f23d15 100644
--- a/src/mspdb.cpp
+++ b/src/mspdb.cpp
@@ -9,6 +9,8 @@
#include <comdef.h>
#include <windows.h>
#include "packages/Microsoft.VisualStudio.Setup.Configuration.Native.1.16.30/lib/native/include/Setup.Configuration.h"
+#include <fstream>
+#include <string>
_COM_SMARTPTR_TYPEDEF(ISetupConfiguration, __uuidof(ISetupConfiguration));
_COM_SMARTPTR_TYPEDEF(ISetupInstance, __uuidof(ISetupInstance));
@@ -165,6 +167,69 @@ bool tryLoadMsPdbVS2017(const char* mspdb, const char* path = 0)
return modMsPdb != 0;
}
+inline std::string& rtrim(std::string& s, const char* t = "\t\n\r ")
+{
+ s.erase(s.find_last_not_of(t) + 1);
+ return s;
+}
+
+bool tryLoadMsPdbVSWhere(const char* mspdb)
+{
+ HANDLE read;
+ HANDLE write;
+
+ SECURITY_ATTRIBUTES securityAttributes = { 0 };
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ securityAttributes.lpSecurityDescriptor = NULL;
+ securityAttributes.bInheritHandle = TRUE;
+ if(!CreatePipe(&read, &write, &securityAttributes, 0) ||
+ !SetHandleInformation(read, HANDLE_FLAG_INHERIT, 0))
+ return false;
+
+ STARTUPINFOA startupInfo = { 0 };
+ startupInfo.cb = sizeof(startupInfo);
+ startupInfo.dwFlags = STARTF_USESTDHANDLES;
+ startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ startupInfo.hStdOutput = write;
+ startupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+ PROCESS_INFORMATION processInformation = { 0 };
+ ZeroMemory(&processInformation, sizeof(PROCESS_INFORMATION));
+
+ std::string vsPath;
+ char buffer[1024] = "";
+ char commandLine[] = "vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath";
+ if(CreateProcessA("C:\\Program Files (x86)\\Microsoft Visual Studio\\Installer\\vswhere.exe", commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &startupInfo, &processInformation))
+ {
+ CloseHandle(processInformation.hProcess);
+ CloseHandle(processInformation.hThread);
+
+ DWORD length;
+ if (ReadFile(read, buffer, sizeof(buffer) - 1, &length, NULL))
+ {
+ buffer[length] = '\0';
+ vsPath += buffer;
+ }
+ }
+ CloseHandle(read);
+ CloseHandle(write);
+ rtrim(vsPath);
+ if (vsPath.empty())
+ return false;
+
+ // Read the version
+ std::ifstream versionFile(vsPath + "\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
+ if (versionFile.fail())
+ return false;
+ std::string contents;
+ contents.assign(std::istreambuf_iterator<char>(versionFile), std::istreambuf_iterator<char>());
+ versionFile.close();
+ rtrim(contents);
+
+ std::string dllPath = vsPath + "\\VC\\Tools\\MSVC\\" + contents + "\\bin\\" + (sizeof(void*) == 8 ? "Hostx64\\x64\\" : "Hostx86\\x86\\") + mspdb;
+ tryLoadLibrary(dllPath.c_str());
+ return modMsPdb != 0;
+}
+
#ifdef _M_X64
#define BIN_DIR_GE_VS12 "..\\..\\VC\\bin\\amd64\\"
#define BIN_DIR_LT_VS12 BIN_DIR_GE_VS12
@@ -247,6 +312,8 @@ void tryLoadMsPdb140(bool throughPath)
tryLoadMsPdb("VisualStudio\\14.0", mspdb140_dll, BIN_DIR_GE_VS12);
if (!modMsPdb && !throughPath)
tryLoadMsPdb("VSWinExpress\\14.0", mspdb140_dll, BIN_DIR_GE_VS12);
+ if (!modMsPdb && !throughPath)
+ tryLoadMsPdbVSWhere(mspdb140_dll);
if (modMsPdb)
mspdb::vsVersion = 14;
}