0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 8.2.2211: MS-Windows: can't load Python dll if not in the path

Problem:    MS-Windows: can't load Python dll if not in the path.
Solution:   Use the InstallPath registry entry. (Kelvin Lee, closes #7540)
This commit is contained in:
Bram Moolenaar
2020-12-25 13:52:37 +01:00
parent 3868f59466
commit b2f9e0e2c5
2 changed files with 75 additions and 0 deletions

View File

@@ -671,6 +671,65 @@ py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature)
# define PyType_HasFeature(t,f) py3_PyType_HasFeature(t,f)
# endif
# ifdef MSWIN
/*
* Look up the library "libname" using the InstallPath registry key.
* Return NULL when failed. Return an allocated string when successful.
*/
static char *
py3_get_system_libname(const char *libname)
{
const char *cp = libname;
char subkey[128];
HKEY hKey;
char installpath[MAXPATHL];
LONG len = sizeof(installpath);
LSTATUS rc;
size_t sysliblen;
char *syslibname;
while (*cp != '\0')
{
if (*cp == ':' || *cp == '\\' || *cp == '/')
{
// Bail out if "libname" contains path separator, assume it is
// an absolute path.
return NULL;
}
++cp;
}
vim_snprintf(subkey, sizeof(subkey),
# ifdef _WIN64
"Software\\Python\\PythonCore\\%d.%d\\InstallPath",
# else
"Software\\Python\\PythonCore\\%d.%d-32\\InstallPath",
# endif
PY_MAJOR_VERSION, PY_MINOR_VERSION);
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_QUERY_VALUE, &hKey)
!= ERROR_SUCCESS)
return NULL;
rc = RegQueryValueA(hKey, NULL, installpath, &len);
RegCloseKey(hKey);
if (ERROR_SUCCESS != rc)
return NULL;
cp = installpath + len;
// Just in case registry value contains null terminators.
while (cp > installpath && *(cp-1) == '\0')
--cp;
// Remove trailing path separators.
while (cp > installpath && (*(cp-1) == '\\' || *(cp-1) == '/'))
--cp;
// Ignore if InstallPath is effectively empty.
if (cp <= installpath)
return NULL;
sysliblen = (cp - installpath) + 1 + STRLEN(libname) + 1;
syslibname = alloc(sysliblen);
vim_snprintf(syslibname, sysliblen, "%.*s\\%s",
(int)(cp - installpath), installpath, libname);
return syslibname;
}
# endif
/*
* Load library and get all pointers.
* Parameter 'libname' provides name of DLL.
@@ -701,6 +760,20 @@ py3_runtime_link_init(char *libname, int verbose)
return OK;
hinstPy3 = load_dll(libname);
# ifdef MSWIN
if (!hinstPy3)
{
// Attempt to use the path from InstallPath as stored in the registry.
char *syslibname = py3_get_system_libname(libname);
if (syslibname != NULL)
{
hinstPy3 = load_dll(syslibname);
vim_free(syslibname);
}
}
# endif
if (!hinstPy3)
{
if (verbose)