python - 找到但无法从当前工作目录加载的 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
坐在我的工作目录中。我正在使用 Windows 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_test\test_dll.py:23:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Users\myuser\python3_portable\lib\ctypes\__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
cwdsys.path
是相同的并且PATH
大部分是相同的(IDE 版本有 PyQt5 bin 文件夹)。
总而言之,问题是:
1 - 什么可能导致这种行为差异,在一种情况下我能够从当前工作目录加载 dll,而在另一种情况下我不能?
2 - 无论如何,如果 dll 在 PATH 的任何目录中,它都可以工作。也许依赖工作目录中的 dll 并将它们正确安装在某个地方是一种不好的做法?
谢谢!
解决方案
我能够按照教程使用 Process Monitor 和过滤:
- 操作是
CreateFile
- 路径包含
PCANBasic
我能够看到 PyInstaller 包的搜索路径与直接命令不同。
然后我发现这个问题提到 PyInstaller 使用SetDllDirectoryA
调用将包自己的文件夹添加到 DLL 搜索路径,但具有删除当前目录的副作用。
推荐阅读
- python - 尝试使用 python 发送带有 xlsx 附件的电子邮件
- r - R 中的 sample() 问题
- django - 鹡鸰在上传期间设置自动焦点
- reactjs - React admin 自定义导出按钮 - 服务器端
- flutter - 在 Flutter 中将无状态小部件从一个屏幕传递到另一个屏幕
- python - 如何在字符串中搜索关键字,提取该字符串并将其放入新列中?
- android - Firestore 查询 StartAt(DocumentReference) 没有给出正确的结果
- android - RecyclerView addOnScrollListener 与 FirebaseRecyclerAdapter
- excel - 从另一个现有工作簿中获取数据
- excel - SUMIF 向下行和跨列