python - 错误:从 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. #
我已经尝试了这篇文章中的建议,但我不确定我做错了什么。
- 我在我的工具中使用 PySide2 和 Python37
- 我的全局 PATH 中没有任何版本的 Python(我正在使用虚拟环境)
- 我尝试在 subprocess.Popen 启动期间添加 sys.insert 或创建 PYTHONPATH 变量并编辑环境变量,但似乎没有任何效果。
我的代码如下。如果更容易,我也可以通过电子邮件发送我的设置的 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')
解决方案
到目前为止,这似乎可行:我将 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'
#.....
推荐阅读
- haskell - 在 Haskell 中计算近似值的生成器、选择器模式
- excel - Excel 以千为单位复制百分比...为什么?
- iterm2 - 更改 cygwin mintty/Mac iTerm/Unix xterm 的前景色和背景色的 ANSI 序列
- javascript - 从 JS 中的两个(或更多)内置对象(Map、EventTarget)继承
- bash - 从 bash 中的 yaml 数组中获取值
- html - HTML:如何在每次单击 html 中的选项卡时刷新页面/文档?
- c# - 一个 RGB 设置为 255 的随机颜色生成
- c# - 如何从数据库中获取数组中的数据?
- python - 在字符串 python 中查找带有额外字符的名称
- c++ - 如何确定相对于 x 轴像素范围的像素强度?