首页 > 解决方案 > 错误:从 python3 exe 子进程运行 Maya 时,“模块使用 python37.dll 与此版本的 Python 冲突”

问题描述

我无法从捆绑的 .exe 程序 (Python 37) 启动 Maya 2020 (Python 27)。我使用 pyinstaller 来捆绑 exe。

如果我从 IDE 启动我的工具,它会很好地启动 Maya。当我从 .exe 启动工具时,模块中的几个 Maya python 出现此错误:

# Error: line 1: ImportError: file C:\Program Files\Autodesk\Maya2020\bin\python27.zip\ctypes\__init__.py line 10: Module use of python37.dll conflicts with this version of Python. # 

我已经尝试了这篇文章中的建议,但我不确定我做错了什么。

我的代码如下。如果更容易,我也可以通过电子邮件发送我的设置的 zip:

launch_maya.py(主文件):

import os
import sys
import subprocess

from PySide2 import QtWidgets



class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Widget, self).__init__(parent)

        # GUI
        btn_launch = QtWidgets.QPushButton('launch maya')
        btn_launch.clicked.connect(self.on_launch)

        # Layout
        main_layout = QtWidgets.QHBoxLayout(self)
        main_layout.addWidget(btn_launch)
        self.setLayout(main_layout)

        # Root path exe vs ide
        if getattr(sys, 'frozen', False):
            self.root_path = sys._MEIPASS
        else:
            self.root_path = os.path.join(os.path.dirname(os.path.realpath(__file__)))

    def _set_app_envs(self):

        _envs = os.environ.copy()
        _envs['MAYA_SCRIPT_PATH'] = os.path.join(self.root_path).replace('\\', '/')
        _envs['QT_PREFERRED_BINDING'] = 'PySide2'

        # Python path envs
        _python_path_list = [
            os.path.join('C:', os.sep, 'Program Files', 'Autodesk', 'Maya2020', 'bin', 'mayapy.exe'),  # insert mayapy here????
            os.path.join(self.root_path).replace('\\', '/')  # userSetup.py dir
        ]

        # PYTHONPATH exe vs ide
        if getattr(sys, 'frozen', False):
            # There is no PYTHONPATH to add so, so I create it here (Do I need this? Is there a diff way?)
            _envs['PYTHONPATH'] = os.pathsep + os.pathsep.join(_python_path_list)

        # Insert mayapy.exe into front of PATH
        sys_path_ = _envs['PATH']
        maya_py_path = os.path.join('C:', os.sep, 'Program Files', 'Autodesk', 'Maya2020', 'bin', 'mayapy.exe')
        sys_path = maya_py_path + os.pathsep + sys_path_
        _envs['PATH'] = sys_path

        else:
            _envs['PYTHONPATH'] += os.pathsep + os.pathsep.join(_python_path_list)

        # Insert mayapy???????
        # sys.path.insert(0, os.path.join('C:', os.sep, 'Program Files', 'Autodesk', 'Maya2020', 'bin', 'mayapy.exe'))

        return _envs

    def on_launch(self):


        # Maya file path
        file_path_abs = '{}/scenes/test.mb'.format(self.root_path).replace('\\', '/')
        print(file_path_abs)
        app_exe = r'C:/Program Files/Autodesk/Maya2020/bin/maya.exe'

        _envs = self._set_app_envs()

        if os.path.exists(file_path_abs):
            proc = subprocess.Popen(
                [app_exe, file_path_abs],
                env=_envs,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
            )


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = Widget()
    window.resize(400, 400)
    window.show()
    sys.exit(app.exec_())

用户设置.py:

import os
import maya.cmds as mc

print('hey')
def tweak_launch(*args):

    print('Startup sequence running...')
    os.environ['mickey'] = '--------ebae--------'
    print(os.environ['mickey'])


mc.evalDeferred("tweak_launch()")

捆绑规范:

# -*- mode: python ; coding: utf-8 -*-
block_cipher = None

added_files = [
         ('./scenes', 'scenes')
         ]

a = Analysis(['launch_maya.py'],
             pathex=[
             'D:/GitStuff/mb-armada/example_files/exe_bundle',
             'D:/GitStuff/mb-armada/dependencies/Qt.py',
             'D:/GitStuff/mb-armada/venv/Lib/site-packages'
             ],
             binaries=[],
             datas=added_files,
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='bundle',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               upx_exclude=[],
               name='bundle')

标签: pythonpyinstallermayapyside2

解决方案


到目前为止,这似乎可行:我将 PYTHONHOME 和 PYTHONPATH 设置为 Maya 在默认设置中想要的目录。确保这些目录在列表中的第一位,否则当前的虚拟环境仍将覆盖 Maya 的 python。

#.....

# Python path envs
_python_path_list = [
    'C:\\Program Files\\Autodesk\\Maya2020\\Python\\Lib\\site-packages',
    'C:\\Program Files\\Autodesk\\Maya2020\\Python\\DLLs',
    os.path.join(self.root_path, 'scripts').replace('\\', '/'),
    os.path.join(self.root_path, 'sourcessss', 'main_app')
]

# PYTHONPATH exe vs ide
if getattr(sys, 'frozen', False):

    _envs['PYTHONPATH'] = os.pathsep.join(_python_path_list)
    _envs['PYTHONHOME'] = 'C:\\Program Files\\Autodesk\\Maya2020\\bin'

#.....

推荐阅读