Note that there are some explanatory texts on larger screens.

plurals
  1. POpy2exe/pyinstaller and DispatchWithEvents
    primarykey
    data
    text
    <p>I have a program that uses the win32com library to control iTunes, but have been having some issues getting it to compile into an executable. The problem seems to revolve around using <code>DispatchWithEvents</code> instead of <code>Dispatch</code>. I've created a very simple program to illustrate my problem:</p> <pre><code>import win32com.client win32com.client.gencache.is_readonly = False #From py2exe wiki class ITunesEvents(object): def __init__(self): self.comEnabled = True def OnCOMCallsDisabledEvent(self, reason): self.comEnabled = False def OnCOMCallsEnabledEvent(self): self.comEnabled = True # The first line works in the exe, the second doesn't. itunes = win32com.client.Dispatch("iTunes.Application") #itunes = win32com.client.DispatchWithEvents("iTunes.Application", ITunesEvents) lib = getattr(itunes, "LibraryPlaylist") src = getattr(lib, "Source") playlists = getattr(src, "Playlists") print "Found %i playlists." % getattr(playlists, "Count") </code></pre> <p>Using <code>Dispatch</code>, the program compiles and runs correctly. Using <code>DispatchWithEvents</code>, the program runs fine when called from the command line, but produces the following error when running the exe:</p> <pre><code>Traceback (most recent call last): File "sandbox.py", line 16, in &lt;module&gt; itunes = win32com.client.DispatchWithEvents("iTunes.Application", ITunesEvents) File "win32com\client\__init__.pyc", line 252, in DispatchWithEvents File "win32com\client\gencache.pyc", line 520, in EnsureModule File "win32com\client\gencache.pyc", line 287, in MakeModuleForTypelib File "win32com\client\makepy.pyc", line 259, in GenerateFromTypeLibSpec File "win32com\client\gencache.pyc", line 141, in GetGeneratePath IOError: [Errno 2] No such file or directory: '[distDir]\\library.zip\\win32com\\gen_py\\__init__.py' </code></pre> <p>I've also tried using PyInstaller, which gives a similar error:</p> <pre><code>File "&lt;string&gt;", line 16, in &lt;module&gt; File "[outDir]/win32com.client", line 252, in DispatchWithEvents File "[outDir]/win32com.client.gencache", line 520, in EnsureModule File "[outDir]/win32com.client.gencache", line 287, in MakeModuleForTypelib File "[outDir]/win32com.client.makepy", line 286, in GenerateFromTypeLibSpec File "[outDir]/win32com.client.gencache", line 550, in AddModuleToCache File "[outDir]/win32com.client.gencache", line 629, in _GetModule File "[pyinstallerDir]\iu.py", line 455, in importHook raise ImportError, "No module named %s" % fqname ImportError: No module named win32com.gen_py.9E93C96F-CF0D-43F6-8BA8-B807A3370712x0x1x13 </code></pre> <p>I know I can manually add the typelib in my <code>setup.py</code> file, but I'd like to run the code on computers with different versions of iTunes without recompiling so I'd prefer to dynamically create it. If there's no way to do this with the setup/spec, maybe there is another way to load the events? Thanks.</p> <hr> <p>Addition:</p> <p>Thanks to Ryan, I found I could take the generated py file and after a little digging, was able to come up with the following.</p> <p>Take the generated py file (from <code>makepy.py</code>) and rename it somewhere like <code>cominterface.py</code>. Then you'll need to do the following to actually create the COM object with event handler.</p> <pre><code>import cominterface from types import ClassType from win32com.client import EventsProxy, _event_setattr_ class ItunesEvents: '''iTunes events class. See cominterface for details.''' def OnPlayerPlayEvent(self, t):print "Playing..." def OnPlayerStopEvent(self, t): print "Stopping..." itunes = cominterface.iTunesApp() rClass = ClassType("COMEventClass", (itunes.__class__, itunes.default_source, ItunesEvents), {'__setattr__': _event_setattr_}) instance = rClass(itunes._oleobj_) itunes.default_source.__init__(instance, instance) #ItunesEvents.__init__(instance) #Uncomment this line if your events class has __init__. itunes = EventsProxy(instance) </code></pre> <p>Then you can go about your business.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload