Photometrics / PyVCAM

Python3.X wrapper for Photometrics and QImaging PVCAM based cameras
MIT License
36 stars 17 forks source link

Issues Building with PyInstaller #41

Closed SebastianVivoverse closed 6 months ago

SebastianVivoverse commented 9 months ago

On Windows 11, version 3.10.1.1 of PVCAM and PVCAM-SDK. I have successfully built the pyvcam wrapper and can run my application from Pycharm. Python 3.11. My PVCAM_SDK_PATH environment variable is set.

Build command:

pyinstaller main.py -F --paths "C:\Program Files\Photometrics\PVCamSDK\Lib\amd64" --paths "C:\Program Files\Photometrics\PVCam\Drivers"

When trying to run built executable:

Traceback (most recent call last):
  File "main.py", line 11, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "main_window.py", line 10, in <module>
  File "PyInstaller\loader\pyimod02_importers.py", line 391, in exec_module
  File "serial_classes\camera.py", line 406, in <module>
ImportError: DLL load failed while importing pvc: The specified module could not be found.
[21552] Failed to execute script 'main' due to unhandled exception!

PyInstaller does not complain about missing PVCAM DLL's during compile stage. Is there another environment variable that I am missing? Is there a dependency that I need to add?

I realize this question includes another library (pyinstaller) but the dependency is PVCAM-related. Any help would be appreciated, thanks!

tomhanak commented 9 months ago

The PVCAM_SDK_PATH env. variable and access to .lib files on that path are needed only to build the application that links with PVCAM. Building and installing PyVCAM adapter is that application here.

To execute the application, no env. variable is needed. PVCAM libraries are installed in standard system location (c:/Windows/System32).

However, based on the description of PyInstaller, it is not possible to bundle your application to single package that includes PVCAM. PVCAM consists of libraries, drivers and a service, that need elevated rights to install and correctly 'hook' to the system. PVCAM runtime must be installed with Photometrics installer only.

SebastianVivoverse commented 9 months ago

Ok I see, thank you. So it sounds like the executable built from PyInstaller needs to reference PVCAM at runtime. That is out of scope for normal PVCAM usage so I will close this issue. Thanks for the quick response!

SebastianVivoverse commented 9 months ago

Reopening because I am completely lost. I have followed all of PyInstaller's conventions for linking DLLs but no success. Has anyone on your team succeeded at building an executable file that used PyVCAM?

I guess it would help me to better understand what PyVCAM is doing under the hood. When importing pvc from pyvcam in python, what is happening specifically? I am under the impression that the pvcam64.dll from System32 is being loaded as pvc.

tomhanak commented 9 months ago

If you install PyVCAM as recommended, it builds a pvc module that dynamically links with pvcam64.dll. When your Python application tries to import pvc module for first time, it fails either because whole pyvcam cannot be found, or because of the dynamic dependencies of pvc cannot be resolved.

Unfortunately, we don't have any experience with PyInstaller. It seems it copies all dependencies for your application to one folder and creates an archive that you can distribute to others. They just extract the archive and run your application from extracted folder. I didn't find any info whether PyInstaller does some kind of sandboxing or isolation of that folder to ensure your application doesn't touch outside the folder...

It cannot work this way with PVCAM because of all its components mentioned above (forgot to mention also registry records and installation of C/C++ Runtime Redistributable) that must be installed with PVCAM installer, not just copied somewhere.

Sure, you could find all PVCAM libraries in system folder, copy them to your folder and distribute PyInstaller bundle, but another computer where you plan to use the bundle won't see any camera because of missing drivers and all the stuff PVCAM installer creates...

SebastianVivoverse commented 9 months ago

Ok, so it sounds like the pyvcam library should be able to link the pvcam64.dll file without needing to bundle it, since pyinstaller works with other libraries that I assume are using dll files.

A difference I notice is that when building the executable, I can import pyvcam just fine, but not pvc. Even though the output folder contains pvc.cpp311-win_amd64.pyd, so it should have a reference to pvc.

Have you ever built an executable application with pyvcam, or do you usually just run it in a script? I can ship python scripts but I would like to have some code obfuscation/bundling the python interpreter, which pyinstaller provides.

tomhanak commented 9 months ago

Unfortunately, we don't develop anything in Python. PyVCAM is an exception just to allow customers to work with our cameras from Python.

However, feel free to fork this project and tweak the setup configuration to fulfil PyInstaller requirements. If the changes will be compatible with current setup, we can merge it via pull request...

leominami777 commented 8 months ago

Hi,I have the same problem. Do you have any solution? Thank you.

leominami777 commented 8 months ago

I think I've fixed the issue. version of my Computer: Windows 11 Python 3.8_x64 Pyinstaller 5.13.0 PVCAM and PVCAM SDK 3.10.1.1

I use D:\Python-3.8-x64\Scripts\pyinstaller.exe -F live_mode.py The example can be successfully published. Can run the exe on my computer and It can also be run on other computers(Windows 10 64bit) with PVCAM and PVCAM SDK.

When I use PyInstaller of Python 32bit. Running the exe.There was the same error as yours. Maybe you should check your Python and Pyinstaller version.They have to be 64bit . Hope this helps you.

SebastianVivoverse commented 8 months ago

@leominami777 would you mind sharing your specfile with me? I am running Python 3.11 64-bit, but still have this error.

I am surprised you didn't have to manually add the pyvcam wrapper to your PyInstaller command.

leominami777 commented 8 months ago

I didn't make any other modifications to the specfile and example. live_mode.zip Here are my files and you can try to run them. If you need the exe is published, you can send me an email address, the file is too big to share here.

SebastianVivoverse commented 8 months ago

Thanks! Is there a reason why your script is inside of the venv folder?

leominami777 commented 8 months ago

I created a new project and created a new virtual environment.The script and Lib inside the venv folder.

SebastianVivoverse commented 6 months ago

Closing this out. There was no issue with pvcam, the issue was another dll for TinyTIFF that I completely forgot about. For future readers, you shouldn't need to do anything special with the pvcam dll, however if you swap LibTIFF out for TinyTIFF you will need to bundle the TinyTIFF dll file.