mhammond / pywin32

Python for Windows (pywin32) Extensions
5.04k stars 796 forks source link

PyIDispatch issue when running script built with PyInstaller #1893

Closed MikelAyani closed 2 years ago

MikelAyani commented 2 years ago

Hi, I have created the script bellow to connect to an OPC-DA Server using a COM object. The code bellow works well running it directly on python 3.8.10 32bit, using pywin32 304. The problem is that when I use PyInstaller to build an executable I get the next exception:

Traceback (most recent call last): File "<frozen importlib._bootstrap>", line 991, in _find_and_load File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked ModuleNotFoundError: No module named 'win32timezone' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "drivers\opcda_client\main.py", line 50, in <module> File "<COMObject Add>", line 3, in SyncRead File "win32com\client\dynamic.py", line 368, in _ApplyTypes_ SystemError: <built-in method InvokeTypes of PyIDispatch object at 0x077FB28C> returned a result with an error set [5416] Failed to execute script 'main' due to unhandled exception!

It only happens, as far as I have been able to test, when I call methods that return a TimeStamp, which I believe returns a pywintypes.datetime object. The COM object is dispatched without issues and all other methods work well, as expected. I read that there has been issues around this before, but I cannot figure out how to solve it.

This is the script:

`import win32com.client import win32com.server.util import random import pythoncom

OPC_CLASS = 'Graybox.OPC.DAWrapper.1;OPC.Automation;RSI.OPCAutomation;Matrikon.OPC.Automation.1;HSCOPC.Automation' OPC_CLIENT = 'Simumatik' OPC_SERVER = 'Matrikon.OPC.Simulation.1' SOURCE_CACHE = 1 SOURCE_DEVICE = 2

pythoncom.CoInitialize()

_connection = None for c in OPC_CLASS.split(';'): try: _connection = win32com.client.Dispatch(c, 0) break except Exception as e: print(e, c)

servers = _connection.GetOPCServers('localhost') print(f"Available servers: {servers}")

_connection.Connect(OPC_SERVER, 'localhost') _connection.ClientName = OPC_CLIENT

_connection.OPCGroups.DefaultGroupUpdateRate = -1

read_group = _connection.OPCGroups.Add('READ') read_group.IsSubscribed = 0 read_group.IsActive = 1

write_group = _connection.OPCGroups.Add('WRITE') write_group.IsSubscribed = 0 write_group.IsActive = 1

server_handles, errors = write_group.OPCItems.AddItems(1, [0, '.test_write_var'], [0, 1]) value = random.randint(0, 100) errors = write_group.SyncWrite(1, [0, server_handles[0]], [0, value]) print("Write results:", value, errors)

server_handles, errors = read_group.OPCItems.AddItems(1, [0, '.test_read_var'], [0, 2]) values, errors, qualities, timestamps = read_group.SyncRead(SOURCE_DEVICE, 1, [0, server_handles[0]]) print("Read results:", values, errors, qualities, timestamps)

_connection.OPCGroups.Remove('WRITE') _connection.OPCGroups.Remove('READ') _connection.Disconnect()`

mhammond commented 2 years ago

ModuleNotFoundError: No module named 'win32timezone'

So it looks like PyInstaller failed to package/install that module.

MikelAyani commented 2 years ago

Thanks! For the record, adding win32timezone to hiddenimports in the pyinstaller spec file solved the problem.