# HG changeset patch # User zooba # Date 1394574753 25200 # Tue Mar 11 14:52:33 2014 -0700 # Node ID 622e53934ae852241ec76f9150a073766f21fdd4 # Parent 16384988a52681ceafb489caab4203d5b566953f #20883 Add architecture-specific install path registry keys on Windows. Update py.exe launcher to inspect new keys. diff --git a/PC/launcher.c b/PC/launcher.c --- a/PC/launcher.c +++ b/PC/launcher.c @@ -157,8 +157,8 @@ static size_t num_installed_pythons = 0; -/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPath */ -#define IP_BASE_SIZE 40 +/* to hold SOFTWARE\Python\PythonCore\X.Y\InstallPathXY */ +#define IP_BASE_SIZE 42 #define IP_SIZE (IP_BASE_SIZE + MAX_VERSION_SIZE) #define CORE_PATH L"SOFTWARE\\Python\\PythonCore" @@ -185,6 +185,13 @@ return result; } +static wchar_t * ip_formats[] = { + L"%s\\%s\\InstallPath", + L"%s\\%s\\InstallPath32", + L"%s\\%s\\InstallPath64", + NULL +}; + static void locate_pythons_for_key(HKEY root, REGSAM flags) { @@ -197,6 +204,7 @@ DWORD type, data_size, attrs; INSTALLED_PYTHON * ip, * pip; wchar_t ip_path[IP_SIZE]; + wchar_t ** ip_formatp; wchar_t * check; wchar_t ** checkp; wchar_t *key_name = (root == HKEY_LOCAL_MACHINE) ? L"HKLM" : L"HKCU"; @@ -218,89 +226,91 @@ break; } else { - _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, - L"%s\\%s\\InstallPath", CORE_PATH, ip->version); - status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); - if (status != ERROR_SUCCESS) { - winerror(status, message, MSGSIZE); - // Note: 'message' already has a trailing \n - debug(L"%s\\%s: %s", key_name, ip_path, message); - continue; - } - data_size = sizeof(ip->executable) - 1; - status = RegQueryValueExW(ip_key, NULL, NULL, &type, - (LPBYTE)ip->executable, &data_size); - RegCloseKey(ip_key); - if (status != ERROR_SUCCESS) { - winerror(status, message, MSGSIZE); - debug(L"%s\\%s: %s\n", key_name, ip_path, message); - continue; - } - if (type == REG_SZ) { - data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ - if (ip->executable[data_size - 1] == L'\\') - --data_size; /* reg value ended in a backslash */ - /* ip->executable is data_size long */ - for (checkp = location_checks; *checkp; ++checkp) { - check = *checkp; - _snwprintf_s(&ip->executable[data_size], - MAX_PATH - data_size, - MAX_PATH - data_size, - L"%s%s", check, PYTHON_EXECUTABLE); - attrs = GetFileAttributesW(ip->executable); - if (attrs == INVALID_FILE_ATTRIBUTES) { - winerror(GetLastError(), message, MSGSIZE); - debug(L"locate_pythons_for_key: %s: %s", - ip->executable, message); - } - else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { - debug(L"locate_pythons_for_key: '%s' is a \ + for (ip_formatp = ip_formats; *ip_formatp; ++ip_formatp) { + _snwprintf_s(ip_path, IP_SIZE, _TRUNCATE, + *ip_formatp, CORE_PATH, ip->version); + status = RegOpenKeyExW(root, ip_path, 0, flags, &ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + // Note: 'message' already has a trailing \n + debug(L"%s\\%s: %s", key_name, ip_path, message); + continue; + } + data_size = sizeof(ip->executable) - 1; + status = RegQueryValueExW(ip_key, NULL, NULL, &type, + (LPBYTE)ip->executable, &data_size); + RegCloseKey(ip_key); + if (status != ERROR_SUCCESS) { + winerror(status, message, MSGSIZE); + debug(L"%s\\%s: %s\n", key_name, ip_path, message); + continue; + } + if (type == REG_SZ) { + data_size = data_size / sizeof(wchar_t) - 1; /* for NUL */ + if (ip->executable[data_size - 1] == L'\\') + --data_size; /* reg value ended in a backslash */ + /* ip->executable is data_size long */ + for (checkp = location_checks; *checkp; ++checkp) { + check = *checkp; + _snwprintf_s(&ip->executable[data_size], + MAX_PATH - data_size, + MAX_PATH - data_size, + L"%s%s", check, PYTHON_EXECUTABLE); + attrs = GetFileAttributesW(ip->executable); + if (attrs == INVALID_FILE_ATTRIBUTES) { + winerror(GetLastError(), message, MSGSIZE); + debug(L"locate_pythons_for_key: %s: %s", + ip->executable, message); + } + else if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + debug(L"locate_pythons_for_key: '%s' is a \ directory\n", - ip->executable, attrs); - } - else if (find_existing_python(ip->executable)) { - debug(L"locate_pythons_for_key: %s: already \ + ip->executable, attrs); + } + else if (find_existing_python(ip->executable)) { + debug(L"locate_pythons_for_key: %s: already \ found: %s\n", ip->executable); - } - else { - /* check the executable type. */ - ok = GetBinaryTypeW(ip->executable, &attrs); - if (!ok) { - debug(L"Failure getting binary type: %s\n", - ip->executable); } else { - if (attrs == SCS_64BIT_BINARY) - ip->bits = 64; - else if (attrs == SCS_32BIT_BINARY) - ip->bits = 32; - else - ip->bits = 0; - if (ip->bits == 0) { - debug(L"locate_pythons_for_key: %s: \ -invalid binary type: %X\n", - ip->executable, attrs); + /* check the executable type. */ + ok = GetBinaryTypeW(ip->executable, &attrs); + if (!ok) { + debug(L"Failure getting binary type: %s\n", + ip->executable); } else { - if (wcschr(ip->executable, L' ') != NULL) { - /* has spaces, so quote */ - n = wcslen(ip->executable); - memmove(&ip->executable[1], - ip->executable, n * sizeof(wchar_t)); - ip->executable[0] = L'\"'; - ip->executable[n + 1] = L'\"'; - ip->executable[n + 2] = L'\0'; + if (attrs == SCS_64BIT_BINARY) + ip->bits = 64; + else if (attrs == SCS_32BIT_BINARY) + ip->bits = 32; + else + ip->bits = 0; + if (ip->bits == 0) { + debug(L"locate_pythons_for_key: %s: \ +invalid binary type: %X\n", + ip->executable, attrs); } - debug(L"locate_pythons_for_key: %s \ + else { + if (wcschr(ip->executable, L' ') != NULL) { + /* has spaces, so quote */ + n = wcslen(ip->executable); + memmove(&ip->executable[1], + ip->executable, n * sizeof(wchar_t)); + ip->executable[0] = L'\"'; + ip->executable[n + 1] = L'\"'; + ip->executable[n + 2] = L'\0'; + } + debug(L"locate_pythons_for_key: %s \ is a %dbit executable\n", - ip->executable, ip->bits); - ++num_installed_pythons; - pip = ip++; - if (num_installed_pythons >= - MAX_INSTALLED_PYTHONS) - break; - /* Copy over the attributes for the next */ - *ip = *pip; + ip->executable, ip->bits); + ++num_installed_pythons; + pip = ip++; + if (num_installed_pythons >= + MAX_INSTALLED_PYTHONS) + break; + /* Copy over the attributes for the next */ + *ip = *pip; + } } } } diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -1298,6 +1298,8 @@ prefix = r"Software\%sPython\PythonCore\%s" % (testprefix, short_version) add_data(db, "Registry", [("InstallPath", -1, prefix+r"\InstallPath", "", "[TARGETDIR]", "REGISTRY"), + ("InstallPathArch", -1, prefix+r"\InstallPath"+("64" if msilib.Win64 else "32"), + "", "[TARGETDIR]", "REGISTRY"), ("InstallGroup", -1, prefix+r"\InstallPath\InstallGroup", "", "Python %s" % short_version, "REGISTRY"), ("PythonPath", -1, prefix+r"\PythonPath", "",