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

PyInstaller打包后导入winrt模块报Cannot change thread mode错误如何解决

报错原因

这个错误是WinRT模块的COM线程模型要求与PyInstaller的默认启动逻辑冲突导致的:

  • PyInstaller的控制台程序加载器在进程启动时会默认将主线程的COM模式设置为MTA(多线程单元)
  • winrt模块在导入时会尝试将当前线程的COM模式设置为STA(单线程单元)
  • Windows规定线程的COM模式一旦设置就无法修改,因此触发了Cannot change thread mode after it is set的运行时错误
  • PyCharm运行时不会提前设置COM线程模式,winrt可以正常完成初始化,因此不会出现报错
解决方法

以下三种方案任选其一即可:

  • 方案一:打包时添加窗口程序参数
    打包时添加-w或--windowed参数生成无控制台的窗口程序,这类程序默认会初始化STA线程模式,和winrt的要求匹配,打包命令示例:

    pyinstaller -F -w notification.py
    

    其中-F表示打包为单EXE文件,可根据自身需求调整参数。

  • 方案二:代码开头手动设置COM线程模式
    在所有导入语句的最开头,先手动将COM线程模式设置为STA,之后再导入winrt相关模块:

    import pythoncom
    pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
    
    # 后续再导入winrt相关模块
    import winrt.windows.ui.notifications as notifications
    import winrt.windows.data.xml.dom as dom
    

    如果运行提示找不到pythoncom,先执行pip install pywin32安装依赖即可。

  • 方案三:将winrt逻辑放到独立线程运行
    新建独立线程执行所有winrt相关逻辑,新线程默认没有设置COM模式,winrt导入时可正常完成初始化:

    import threading
    
    def toast_logic():
        # 所有winrt相关导入和逻辑都放到这个函数内
        import winrt.windows.ui.notifications as notifications
        import winrt.windows.data.xml.dom as dom
        # 此处编写你的通知业务代码
    
    if __name__ == "__main__":
        t = threading.Thread(target=toast_logic)
        t.start()
        t.join()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:15:03