找到 DLL,但无法从当前工作目录加载



我正在运行以下代码:

def PATH():
return "n"+"n".join(os.environ["PATH"].split(os.pathsep))
def syspath():
return "n"+"n".join(sys.path)
def test_haha():
logger.info(f"CWD: {os.getcwd()}")
logger.info(f"sys.path: {syspath()}")
logger.info(f"PATH: {PATH()}")
logger.info(f"Found? {str(util.find_library('PCANBasic'))}")
windll.LoadLibrary("PCANBasic")
# pcanbasic_path = str(Path(os.getcwd()) / "PCANBasic.dll")

我的PCANBasic.dll坐在我的工作目录中。我正在使用窗口 10。

如果我从命令行运行 python,一切正常。

但是,我有一个用pyqt编写并与PyInstaller捆绑在一起的IDE。该 IDE 具有运行 python 文件的函数(在运行与我手动运行的相同命令的批处理文件中调用 QProcess(,在这种情况下,它失败并显示以下内容:

def test_haha():
logger.info(f"CWD: {os.getcwd()}")
logger.info(f"sys.path: {syspath()}")
logger.info(f"PATH: {PATH()}")
logger.info(f"Found? {str(util.find_library('PCANBasic'))}")
>       windll.LoadLibrary("PCANBasic")
demo_testtest_dll.py:23: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:Usersmyuserpython3_portablelibctypes__init__.py:434: in LoadLibrary
return self._dlltype(name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <WinDLL 'PCANBasic', handle 0 at 0x1e9e6480668>, name = 'PCANBasic'
mode = 0, handle = None, use_errno = False, use_last_error = False
def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False,
use_last_error=False):
self._name = name
flags = self._func_flags_
if use_errno:
flags |= _FUNCFLAG_USE_ERRNO
if use_last_error:
flags |= _FUNCFLAG_USE_LASTERROR
if _sys.platform.startswith("aix"):
"""When the name contains ".a(" and ends with ")",
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
archive(member) syntax for dlopen(), and the mode is adjusted.
Otherwise, name is presented to dlopen() as a file argument.
"""
if name and name.endswith(")") and ".a(" in name:
mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
class _FuncPtr(_CFuncPtr):
_flags_ = flags
_restype_ = self._func_restype_
self._FuncPtr = _FuncPtr
if handle is None:
>           self._handle = _dlopen(self._name, mode)
E           OSError: [WinError 126] The specified module could not be found

cwd,sys.path是相同的,PATH基本相同(IDE版本具有PyQt5 bin文件夹(。

总之,问题是:

1 - 在一种情况下,我能够从当前工作目录加载 dll,而在另一种情况下则不能,是什么导致了这种行为差异?

2 - 在任何情况下,如果 dll 位于 PATH 中的任何目录中,它都可以工作。也许依赖工作目录中的 dll 并将它们正确安装在某个地方是一种不好的做法?

谢谢!

我能够按照使用进程监视器和过滤的教程进行操作:

  • 操作CreateFile
  • 路径包含PCANBasic

我能够看到 PyInstaller 捆绑包具有与直接命令不同的搜索路径。

然后我发现了这个问题,它提到 PyInstaller 使用SetDllDirectoryA调用将捆绑包自己的文件夹添加到 DLL 搜索路径,但副作用是删除当前目录。

最新更新