mayapy.exe working differently in VSCode and Freeze(exe)

101 views
Skip to first unread message

kohy...@gmail.com

unread,
Jun 20, 2020, 4:15:34 PM6/20/20
to Python Programming for Autodesk Maya
Hello group!

I am currently building a scene creator/opener app for Maya.
I am using Python(3.6.8) and PyQt5(5.15.0) for GUI stuff,
and "fbs(0.8.6)" to freeze my app to an exe file.

Everything works fine when I run my app in visual studio code by executing "(venv) fbs run", "maya_create.bat" calls "mayapy.exe" and "maya_create.py" without any problems...

But once I freeze the app "(venv) fbs freeze", and run the same bat file it gives me an error :(
```
Traceback (most recent call last):
  File "C:\Users\hko\chaos\target\Chaos\command\maya_create.py", line 3, in <module>
    from maya import standalone
ImportError: DLL load failed:
```

I've been struggling days with this problem...
Hope someone can help me out!!!

Thanks in advance :)


-------- 

``` maya_create.bat
chcp 65001
start "" "C:\Program Files\Autodesk\Maya2018\bin\mayapy"  "%~dp0maya_create.py" "%1"
```

``` maya_create.py
import os
import sys
from maya import standalone
from maya import cmds
from maya import mel

args = sys.argv[1:]
if len(args) != 1:
print("accept only one argument")
scene = args[0]

standalone.initialize(name='python')

cmds.file(rename=scene)
cmds.file(save=True)
```

Justin Israel

unread,
Jun 20, 2020, 4:45:36 PM6/20/20
to python_in...@googlegroups.com
It's been a long time since I have package python apps into frozen executables. I use to do it with pyinstaller and py2app. So I imagine your issue is with the pyinstaller layer that fbs is built upon. If I remember correctly, I didn't try and freeze Maya into the package. I would just rely on it being in the system path and starting a subprocess as needed from my frozen app. Otherwise if you were trying to freeze mayapy you would need to bundle the entire Maya distribution to make it portable. Is that your goal? Or are you just trying to bundle your app code and resources but still run the system Maya? If it's the latter then the error implies a possible path issue in your environment (disclaimer I don't know much about this for windows). Mayapy is usually a wrapper script to set env vars to point at the Maya bundled python interpreter. So you may need to customise your pyinstaller configuration based on that to make sure it can bootstrap properly to run against the external PYTHONHOME. That implies that you need to freeze against the right version of python for your Maya version. Sorry I can't be much more helpful than this. 

Seems like it's a hard task to accomplish:

https://stackoverflow.com/questions/59131615/pyinstaller-error-while-run-maya-standalone



--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/19b28e9a-6062-44ee-bdd0-fc53d3809b28o%40googlegroups.com.

Stefan Tapper

unread,
Jun 21, 2020, 8:57:40 AM6/21/20
to Python Programming for Autodesk Maya
One other way to work around this would be to use pynsist instead of fbs. It creates a Nullsoft installer that contains your python interpreter of choice and your application as plain py files. The end user will have an Link *.lnk in his Start menu and desktop. So it will appear like an executable to the end user. This will work well with mayapy in a subprocess.

https://pynsist.readthedocs.io/en/latest/

One downside I found is that the Nullsoft installer will not clear the install directory prior to installation which might cause headaches with updates. But I guess one could easily customize the installer script to do that.
Another downside -could- be that you need compiled wheels of the external packages you use which are not always provided on PYPI.

kohy...@gmail.com

unread,
Jun 21, 2020, 6:21:51 PM6/21/20
to Python Programming for Autodesk Maya
Thanks for the reply :)

I can see that all this python freezing thing can get very complicated very quickly...
Even though I find a workaround to accomplish this, it would be a nightmare to maintain it...!!

I've been looking for other solutions(even other programming languages), that does not have any conflict problems with python and easier to maintain.
Have you had any luck with writing Desktop apps with golang?
Since I am familiar with the Qt framework therecipe/qt(https://github.com/therecipe/qt) seems like a good option for me.


2020년 6월 21일 일요일 오전 5시 45분 36초 UTC+9, Justin Israel 님의 말:
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
Jun 21, 2020, 10:21:15 PM6/21/20
to python_in...@googlegroups.com
On Mon, Jun 22, 2020 at 10:21 AM <kohy...@gmail.com> wrote:
Thanks for the reply :)

I can see that all this python freezing thing can get very complicated very quickly...
Even though I find a workaround to accomplish this, it would be a nightmare to maintain it...!!

I've been looking for other solutions(even other programming languages), that does not have any conflict problems with python and easier to maintain.
Have you had any luck with writing Desktop apps with golang?
Since I am familiar with the Qt framework therecipe/qt(https://github.com/therecipe/qt) seems like a good option for me.

I've been developing in Go for years now and its a fantastic language that should become more popular in vfx and pipeline. Normally I use it for writing services, command line tooling, and apis. And I have also done some work where I start an embedded python interpreter to run py code, or export a Go module as a python compiled extension. One thing I haven't used it much for is desktop gui apps. Having a lot of Qt experience my first instinct was to reach for therecipe/qt. The downside is that it has a heavy provisioning process for each project, where you have to generate the bindings and make sure it links to the Qt libraries. Once you get it going, it does work. There are other GUI options depending on your needs.  
There are more listed here: https://awesome-go.com/#gui

If you do manage to solve your problems with Go, the deployment process becomes so much more simple.

To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/d11f7cbd-2838-4464-9feb-4d3f594c9473o%40googlegroups.com.

kohy...@gmail.com

unread,
Jul 8, 2020, 9:12:22 AM7/8/20
to Python Programming for Autodesk Maya
Thank you Stefan,

I've managed to fix the issue by using pynsist, mayapy.exe work's great but files sizes are huge :0... PyQt5...
And I can already see the future me having a hard time managing releases...

Still looking for better solutions :)


2020년 6월 21일 일요일 오후 9시 57분 40초 UTC+9, Stefan Tapper 님의 말:

Justin Israel

unread,
Jul 8, 2020, 4:27:13 PM7/8/20
to python_in...@googlegroups.com


On Thu, Jul 9, 2020, 1:12 AM <kohy...@gmail.com> wrote:
Thank you Stefan,

I've managed to fix the issue by using pynsist, mayapy.exe work's great but files sizes are huge :0... PyQt5...
And I can already see the future me having a hard time managing releases...

Still looking for better solutions :)

Learn a compiled language? :) 
Write it in C++ with Qt and then you don't have to worry about freezing python packages. 



2020년 6월 21일 일요일 오후 9시 57분 40초 UTC+9, Stefan Tapper 님의 말:
One other way to work around this would be to use pynsist instead of fbs. It creates a Nullsoft installer that contains your python interpreter of choice and your application as plain py files. The end user will have an Link *.lnk in his Start menu and desktop. So it will appear like an executable to the end user. This will work well with mayapy in a subprocess.

https://pynsist.readthedocs.io/en/latest/

One downside I found is that the Nullsoft installer will not clear the install directory prior to installation which might cause headaches with updates. But I guess one could easily customize the installer script to do that.
Another downside -could- be that you need compiled wheels of the external packages you use which are not always provided on PYPI.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Stefan Tapper

unread,
Jul 30, 2020, 10:59:39 AM7/30/20
to Python Programming for Autodesk Maya
For managing releases. You can actually add your own NSI script. I'll post mine which is just the default pynsist one with changed default setting to "install for all users" and a command (RMDir /r "$INSTDIR") to delete the whole install directory prior to an install to make no old packages get in the way:
!define PRODUCT_NAME "[[ib.appname]]"
!define PRODUCT_VERSION "[[ib.version]]"
!define PY_VERSION "[[ib.py_version]]"
!define PY_MAJOR_VERSION "[[ib.py_major_version]]"
!define BITNESS "[[ib.py_bitness]]"
!define ARCH_TAG "[[arch_tag]]"
!define INSTALLER_NAME "[[ib.installer_name]]"
!define PRODUCT_ICON "[[icon]]"

; Marker file to tell the uninstaller that it's a user installation
!define USER_INSTALL_MARKER _user_install_marker
 
SetCompressor lzma

!define MULTIUSER_EXECUTIONLEVEL Highest
; !define MULTIUSER_INSTALLMODE_DEFAULT_CURRENTUSER
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_INSTDIR "[[ib.appname]]"
[% if ib.py_bitness == 64 %]
!define MULTIUSER_INSTALLMODE_FUNCTION correct_prog_files
[% endif %]
!include MultiUser.nsh

[% block modernui %]
; Modern UI installer stuff
!include "MUI2.nsh"
!define MUI_ABORTWARNING
!define MUI_ICON "[[icon]]"
!define MUI_UNICON "[[icon]]"

; UI pages
[% block ui_pages %]
!insertmacro MUI_PAGE_WELCOME
[% if license_file %]
!insertmacro MUI_PAGE_LICENSE [[license_file]]
[% endif %]
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
[% endblock ui_pages %]
!insertmacro MUI_LANGUAGE "English"
[% endblock modernui %]

Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
OutFile "${INSTALLER_NAME}"
ShowInstDetails show

Section -SETTINGS
  SetOutPath "$INSTDIR"
  SetOverwrite ifnewer
SectionEnd

[% block sections %]

Section "!${PRODUCT_NAME}" sec_app
  RMDir /r "$INSTDIR"
  SetRegView [[ib.py_bitness]]
  SectionIn RO
  File ${PRODUCT_ICON}
  SetOutPath "$INSTDIR\pkgs"
  File /r "pkgs\*.*"
  SetOutPath "$INSTDIR"

  ; Marker file for per-user install
  StrCmp $MultiUser.InstallMode CurrentUser 0 +3
    FileOpen $0 "$INSTDIR\${USER_INSTALL_MARKER}" w
    FileClose $0
    SetFileAttributes "$INSTDIR\${USER_INSTALL_MARKER}" HIDDEN

  [% block install_files %]
  ; Install files
  [% for destination, group in grouped_files %]
    SetOutPath "[[destination]]"
    [% for file in group %]
      File "[[ file ]]"
    [% endfor %]
  [% endfor %]
 
  ; Install directories
  [% for dir, destination in ib.install_dirs %]
    SetOutPath "[[ pjoin(destination, dir) ]]"
    File /r "[[dir]]\*.*"
  [% endfor %]
  [% endblock install_files %]
 
  [% block install_shortcuts %]
  ; Install shortcuts
  ; The output path becomes the working directory for shortcuts
  SetOutPath "%HOMEDRIVE%\%HOMEPATH%"
  [% if single_shortcut %]
    [% for scname, sc in ib.shortcuts.items() %]
    CreateShortCut "$SMPROGRAMS\[[scname]].lnk" "[[sc['target'] ]]" \
      '[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
    [% endfor %]
  [% else %]
    [# Multiple shortcuts: create a directory for them #]
    CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
    [% for scname, sc in ib.shortcuts.items() %]
    CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\[[scname]].lnk" "[[sc['target'] ]]" \
      '[[ sc['parameters'] ]]' "$INSTDIR\[[ sc['icon'] ]]"
    [% endfor %]
  [% endif %]
  SetOutPath "$INSTDIR"
  [% endblock install_shortcuts %]

  [% block install_commands %]
  [% if has_commands %]
    nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_rewrite_shebangs.py" "$INSTDIR\bin"'
    nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" add "$INSTDIR\bin"'
  [% endif %]
  [% endblock install_commands %]
 
  ; Byte-compile Python files.
  DetailPrint "Byte-compiling Python modules..."
  nsExec::ExecToLog '[[ python ]] -m compileall -q "$INSTDIR\pkgs"'
  WriteUninstaller $INSTDIR\uninstall.exe
  ; Add ourselves to Add/remove programs
  WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "DisplayName" "${PRODUCT_NAME}"
  WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "UninstallString" '"$INSTDIR\uninstall.exe"'
  WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "InstallLocation" "$INSTDIR"
  WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "DisplayIcon" "$INSTDIR\${PRODUCT_ICON}"
  [% if ib.publisher is not none %]
    WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                     "Publisher" "[[ib.publisher]]"
  [% endif %]
  WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "DisplayVersion" "${PRODUCT_VERSION}"
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "NoModify" 1
  WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
                   "NoRepair" 1

  ; Check if we need to reboot
  IfRebootFlag 0 noreboot
    MessageBox MB_YESNO "A reboot is required to finish the installation. Do you wish to reboot now?" \
                /SD IDNO IDNO noreboot
      Reboot
  noreboot:
SectionEnd

Section "Uninstall"
  SetRegView [[ib.py_bitness]]
  SetShellVarContext all
  IfFileExists "$INSTDIR\${USER_INSTALL_MARKER}" 0 +3
    SetShellVarContext current
    Delete "$INSTDIR\${USER_INSTALL_MARKER}"

  Delete $INSTDIR\uninstall.exe
  Delete "$INSTDIR\${PRODUCT_ICON}"
  RMDir /r "$INSTDIR\pkgs"

  ; Remove ourselves from %PATH%
  [% block uninstall_commands %]
  [% if has_commands %]
    nsExec::ExecToLog '[[ python ]] -Es "$INSTDIR\_system_path.py" remove "$INSTDIR\bin"'
  [% endif %]
  [% endblock uninstall_commands %]

  [% block uninstall_files %]
  ; Uninstall files
  [% for file, destination in ib.install_files %]
    Delete "[[pjoin(destination, file)]]"
  [% endfor %]
  ; Uninstall directories
  [% for dir, destination in ib.install_dirs %]
    RMDir /r "[[pjoin(destination, dir)]]"
  [% endfor %]
  [% endblock uninstall_files %]

  [% block uninstall_shortcuts %]
  ; Uninstall shortcuts
  [% if single_shortcut %]
    [% for scname in ib.shortcuts %]
      Delete "$SMPROGRAMS\[[scname]].lnk"
    [% endfor %]
  [% else %]
    RMDir /r "$SMPROGRAMS\${PRODUCT_NAME}"
  [% endif %]
  [% endblock uninstall_shortcuts %]
  RMDir $INSTDIR
  DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
SectionEnd

[% endblock sections %]

; Functions

Function .onMouseOverSection
    ; Find which section the mouse is over, and set the corresponding description.
    FindWindow $R0 "#32770" "" $HWNDPARENT
    GetDlgItem $R0 $R0 1043 ; description item (must be added to the UI)

    [% block mouseover_messages %]
    StrCmp $0 ${sec_app} "" +2
      SendMessage $R0 ${WM_SETTEXT} 0 "STR:${PRODUCT_NAME}"
   
    [% endblock mouseover_messages %]
FunctionEnd

Function .onInit
  !insertmacro MULTIUSER_INIT
FunctionEnd

Function un.onInit
  !insertmacro MULTIUSER_UNINIT
FunctionEnd

[% if ib.py_bitness == 64 %]
Function correct_prog_files
  ; The multiuser machinery doesn't know about the different Program files
  ; folder for 64-bit applications. Override the install dir it set.
  StrCmp $MultiUser.InstallMode AllUsers 0 +2
    StrCpy $INSTDIR "$PROGRAMFILES64\${MULTIUSER_INSTALLMODE_INSTDIR}"
FunctionEnd
[% endif %]
Reply all
Reply to author
Forward
0 new messages