nss3.dll是链接到以下DLL的,它们都位于Firefox目录中:nssutil3.dll、plc4.dll、plds4.dll、nspr4.dll和mozcrt19.dll。系统库加载器在进程的DLL搜索路径中查找这些文件,包括应用程序目录、系统目录、当前目录以及在PATH
环境变量中列出的每个目录。
最简单的解决方法是将当前目录更改为DLL Firefox目录。但是,这不是线程安全的,因此我不会通常依赖它。另一种选择是将Firefox目录附加到PATH
环境变量中,这就是我在我的答案的原始版本中建议的做法。但是,这与修改当前目录没有太大区别。
新版本的Windows(NT 6.0+ KB2533623更新)允许通过SetDefaultDllDirectories
、AddDllDirectory
和RemoveDllDirectory
以线程安全的方式更新DLL搜索路径。但在这里使用这种方法有点过头了。
在本例中,为了简单起见并与旧版本的Windows兼容,调用带有标志LOAD_WITH_ALTERED_SEARCH_PATH
的LoadLibraryEx
即可。你需要使用绝对路径来加载DLL,否则行为未定义。为了方便,我们可以子类化ctypes.CDLL
和ctypes.WinDLL
来调用LoadLibraryEx
而不是LoadLibrary
。
import os
import ctypes
if os.name == 'nt':
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
def check_bool(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.LoadLibraryExW.errcheck = check_bool
kernel32.LoadLibraryExW.restype = wintypes.HMODULE
kernel32.LoadLibraryExW.argtypes = (wintypes.LPCWSTR,
wintypes.HANDLE,
wintypes.DWORD)
class CDLLEx(ctypes.CDLL):
def __init__(self, name, mode=0, handle=None,
use_errno=True, use_last_error=False):
if os.name == 'nt' and handle is None:
handle = kernel32.LoadLibraryExW(name, None, mode)
super(CDLLEx, self).__init__(name, mode, handle,
use_errno, use_last_error)
class WinDLLEx(ctypes.WinDLL):
def __init__(self, name, mode=0, handle=None,
use_errno=False, use_last_error=True):
if os.name == 'nt' and handle is None:
handle = kernel32.LoadLibraryExW(name, None, mode)
super(WinDLLEx, self).__init__(name, mode, handle,
use_errno, use_last_error)
以下是所有可用的LoadLibraryEx
标志:
DONT_RESOLVE_DLL_REFERENCES = 0x00000001
LOAD_LIBRARY_AS_DATAFILE = 0x00000002
LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008
LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010
LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020
LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100
LOAD_LIBRARY_SEARCH_APPLICATION_DIR = 0x00000200
LOAD_LIBRARY_SEARCH_USER_DIRS = 0x00000400
LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
例如:
firefox_path = r'F:\Softwares\Mozilla Firefox'
nss3 = CDLLEx(os.path.join(firefox_path, 'nss3.dll'),
LOAD_WITH_ALTERED_SEARCH_PATH)
nss3.NSS_GetVersion.restype = c_char_p
>>> nss3.NSS_GetVersion()
'3.13.5.0 Basic ECC'
cdll.LoadLibrary
吗? - g.d.d.c