You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本转exe后出现ImportError:导入win32gui时DLL加载失败

问题

我编写了一款可修改系统光标的Python脚本,直接运行.py文件时一切正常,但打包为exe文件后运行,出现如下错误:

ImportError: DLL load failed while importing win32gui: Die angegebene Prozedur wurde nicht gefunden
(德语翻译:导入win32gui时DLL加载失败:找不到指定的程序)

我能理解是程序无法找到win32gui相关依赖,但为什么win32con能成功导入呢?以下是我的代码:

import ctypes
from time import sleep
import win32con
import win32gui
import os, sys

def resource_path(relative_path):
   try:
      base_path = sys._MEIPASS
   except Exception:
      base_path = os.path.abspath(".")

   return os.path.join(base_path, relative_path)

path = resource_path("./test.cur")
sleeptime = 30

cursor_value = {
    32650: "OCR_APPSTARTING",
    32512: "OCR_NORMAL",
    32515: "OCR_CROSS",
    32649: "OCR_HAND",
    32651: "OCR_HELP",
    32513: "OCR_IBEAM",
    32648: "OCR_NO",
    32646: "OCR_SIZEALL",
    32643: "OCR_SIZENESW",
    32645: "OCR_SIZENS",
    32642: "OCR_SIZENWSE",
    32644: "OCR_SIZEWE",
    32516: "OCR_UP",
    32514: "OCR_WAIT"
}

original_cursor = {}

def load_original_cursor(Values):
    for k, v in Values.items():
        hold = win32gui.LoadImage(0, k, win32con.IMAGE_CURSOR, 0, 0, win32con.LR_SHARED)
        hsave = ctypes.windll.user32.CopyImage(hold, win32con.IMAGE_CURSOR, 0, 0, win32con.LR_COPYFROMRESOURCE)
        original_cursor[k] = hsave
    print(original_cursor)

def set_fake_cursor(path, Values):
    for k, v in Values.items():
        hnew = win32gui.LoadImage(0, path, win32con.IMAGE_CURSOR, 0, 0, win32con.LR_LOADFROMFILE)
        ctypes.windll.user32.SetSystemCursor(hnew, k)

def set_original_cursor(Original_Values):
    for k, v in Original_Values.items():
        ctypes.windll.user32.SetSystemCursor(v, k)

if __name__ == "__main__":
    load_original_cursor(cursor_value)
    set_fake_cursor(path, cursor_value)
    sleep(sleeptime)
    set_original_cursor(original_cursor)
    sys.exit(-1)
解决方案

原因分析

win32con和win32gui的导入逻辑本质不同:

  • win32con是纯常量定义模块,仅包含Windows API的常量映射,不需要依赖外部DLL就能完成导入,打包时会被直接包含进exe。
  • win32gui是Windows GUI API封装模块,依赖pywin32_system32目录下的pywintypesXX.dll、pythoncomXX.dll等系统级DLL,打包工具(如PyInstaller)默认可能未正确收集这些依赖,或打包后DLL加载路径异常。

修复步骤

  1. 重装并注册pywin32
    先卸载旧版本,再安装适配当前Python版本的最新版:

    pip uninstall pywin32 -y
    pip install pywin32 --upgrade
    

    安装完成后必须执行注册脚本,确保系统DLL被正确识别:

    python -m pywin32_postinstall.py -install
    
  2. 调整PyInstaller打包参数
    打包时显式指定依赖,强制收集pywin32相关文件:

    # 基础打包命令,强制导入win32gui依赖
    pyinstaller --onefile --hidden-import win32gui your_script.py
    # 若仍有问题,添加全量收集参数
    pyinstaller --onefile --collect-all pywin32 your_script.py
    
  3. 用ctypes替代win32gui调用(可选)
    既然已使用ctypes调用user32.dll,可直接替换win32gui的LoadImage方法,彻底规避pywin32的打包问题:

    # 替换win32gui.LoadImage的ctypes实现
    user32 = ctypes.windll.user32
    user32.LoadImageW.argtypes = [ctypes.c_void_p, ctypes.c_wchar_p, ctypes.c_uint, ctypes.c_int, ctypes.c_int, ctypes.c_uint]
    user32.LoadImageW.restype = ctypes.c_void_p
    
    # 加载系统光标
    hold = user32.LoadImageW(0, k, win32con.IMAGE_CURSOR, 0, 0, win32con.LR_SHARED)
    # 加载自定义光标
    hnew = user32.LoadImageW(0, path, win32con.IMAGE_CURSOR, 0, 0, win32con.LR_LOADFROMFILE)
    

验证方式

打包完成后,若为非单文件打包,检查exe目录是否包含pywintypesXX.dll和pythoncomXX.dll;运行exe后观察是否仍出现DLL加载错误。

内容的提问来源于stack exchange,提问作者Drip Narix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:25:20