From d8c8d51386e00c157fa77fc2792bbf86d3c6cbe3 Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sun, 14 Sep 2014 21:49:52 +0300 Subject: [PATCH] WINDOWS: Can now correctly detect 64bit and 32bit python installations on 64bit Windows. Closes #1148 #445 #795 #1708. Conflicts: src/preferences/preferences.cpp --- src/preferences/preferences.h | 99 +++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 29 deletions(-) diff --git a/src/preferences/preferences.h b/src/preferences/preferences.h index 76ed6929c..7e9d3c650 100755 --- a/src/preferences/preferences.h +++ b/src/preferences/preferences.h @@ -1223,37 +1223,17 @@ public: #ifdef Q_WS_WIN static QString getPythonPath() { - HKEY key_handle1; - long res = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Python\\PythonCore"), 0, KEY_READ, &key_handle1); - if (res == ERROR_SUCCESS) { - QStringList versions = getRegSubkeys(key_handle1); - qDebug("Python versions nb: %d", versions.size()); - versions.sort(); + QString path = pythonSearchReg(USER); + if (path.isEmpty()) + path = pythonSearchReg(SYSTEM_32BIT); + else return path; - 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'; + if (path.isEmpty()) + path = pythonSearchReg(SYSTEM_64BIT); + else return path; - res = ::RegOpenKeyEx(key_handle1, subkey, 0, KEY_READ, &key_handle2); - 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); + if (!path.isEmpty()) + return path; // Fallback: Detect python from default locations QStringList supported_versions; @@ -1402,6 +1382,8 @@ public: #ifdef Q_OS_WIN private: + enum REG_SEARCH_TYPE {USER, SYSTEM_32BIT, SYSTEM_64BIT}; + static QStringList getRegSubkeys(const HKEY &handle) { QStringList keys; DWORD subkeys_count = 0; @@ -1456,6 +1438,65 @@ private: 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 };