WINDOWS: Can now correctly detect 64bit and 32bit python installations on 64bit Windows. Closes #1148 #445 #795 #1708.

Conflicts:
	src/preferences/preferences.cpp
This commit is contained in:
sledgehammer999 2014-09-14 21:49:52 +03:00
commit d8c8d51386

View file

@ -1223,37 +1223,17 @@ public:
#ifdef Q_WS_WIN #ifdef Q_WS_WIN
static QString getPythonPath() { static QString getPythonPath() {
HKEY key_handle1; QString path = pythonSearchReg(USER);
long res = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Python\\PythonCore"), 0, KEY_READ, &key_handle1); if (path.isEmpty())
if (res == ERROR_SUCCESS) { path = pythonSearchReg(SYSTEM_32BIT);
QStringList versions = getRegSubkeys(key_handle1); else return path;
qDebug("Python versions nb: %d", versions.size());
versions.sort();
while(!versions.empty()) { if (path.isEmpty())
const QString version = versions.takeLast()+"\\InstallPath"; path = pythonSearchReg(SYSTEM_64BIT);
HKEY key_handle2; else return path;
LPTSTR subkey = new TCHAR[version.size()+1];
version.toWCharArray(subkey);
subkey[version.size()] = '\0';
res = ::RegOpenKeyEx(key_handle1, subkey, 0, KEY_READ, &key_handle2); if (!path.isEmpty())
delete[] subkey;
if (res == ERROR_SUCCESS) {
qDebug("Detected possible Python v%s location", qPrintable(version));
QString path = getRegValue(key_handle2);
::RegCloseKey(key_handle2);
if (!path.isEmpty() && QDir(path).exists("python.exe")) {
qDebug("Found python.exe at %s", qPrintable(path));
::RegCloseKey(key_handle1);
return path; return path;
}
}
else
::RegCloseKey(key_handle2);
}
}
::RegCloseKey(key_handle1);
// Fallback: Detect python from default locations // Fallback: Detect python from default locations
QStringList supported_versions; QStringList supported_versions;
@ -1402,6 +1382,8 @@ public:
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
private: private:
enum REG_SEARCH_TYPE {USER, SYSTEM_32BIT, SYSTEM_64BIT};
static QStringList getRegSubkeys(const HKEY &handle) { static QStringList getRegSubkeys(const HKEY &handle) {
QStringList keys; QStringList keys;
DWORD subkeys_count = 0; DWORD subkeys_count = 0;
@ -1456,6 +1438,65 @@ private:
return end_result; return end_result;
} }
static QString pythonSearchReg(const REG_SEARCH_TYPE type) {
HKEY key_handle1;
long res = 0;
switch (type) {
case USER:
res = ::RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Python\\PythonCore"), 0, KEY_READ, &key_handle1);
break;
case SYSTEM_32BIT:
res = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Python\\PythonCore"), 0, KEY_READ|KEY_WOW64_32KEY, &key_handle1);
break;
case SYSTEM_64BIT:
res = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Python\\PythonCore"), 0, KEY_READ|KEY_WOW64_64KEY, &key_handle1);
break;
}
if (res == ERROR_SUCCESS) {
QStringList versions = getRegSubkeys(key_handle1);
qDebug("Python versions nb: %d", versions.size());
versions.sort();
while(!versions.empty()) {
const QString version = versions.takeLast()+"\\InstallPath";
HKEY key_handle2;
LPTSTR subkey = new TCHAR[version.size()+1];
version.toWCharArray(subkey);
subkey[version.size()] = '\0';
switch (type) {
case USER:
res = ::RegOpenKeyEx(key_handle1, subkey, 0, KEY_READ, &key_handle2);
break;
case SYSTEM_32BIT:
res = ::RegOpenKeyEx(key_handle1, subkey, 0, KEY_READ|KEY_WOW64_32KEY, &key_handle2);
break;
case SYSTEM_64BIT:
res = ::RegOpenKeyEx(key_handle1, subkey, 0, KEY_READ|KEY_WOW64_64KEY, &key_handle2);
break;
}
delete[] subkey;
if (res == ERROR_SUCCESS) {
qDebug("Detected possible Python v%s location", qPrintable(version));
QString path = getRegValue(key_handle2);
::RegCloseKey(key_handle2);
if (!path.isEmpty() && QDir(path).exists("python.exe")) {
qDebug("Found python.exe at %s", qPrintable(path));
::RegCloseKey(key_handle1);
return path;
}
}
else
::RegCloseKey(key_handle2);
}
}
::RegCloseKey(key_handle1);
return QString::null;
}
#endif #endif
}; };