Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python py2exe/pyinstaller和DispatchWithEvents_Python_Py2exe_Win32com_Pyinstaller - Fatal编程技术网

Python py2exe/pyinstaller和DispatchWithEvents

Python py2exe/pyinstaller和DispatchWithEvents,python,py2exe,win32com,pyinstaller,Python,Py2exe,Win32com,Pyinstaller,我有一个程序,它使用Win32 COM库来控制iTunes,但在将其编译成可执行文件时遇到了一些问题。问题似乎围绕着使用DispatchWithEvents而不是Dispatch。我创建了一个非常简单的程序来说明我的问题: import win32com.client win32com.client.gencache.is_readonly = False #From py2exe wiki class ITunesEvents(object): def __init__(self):

我有一个程序,它使用Win32 COM库来控制iTunes,但在将其编译成可执行文件时遇到了一些问题。问题似乎围绕着使用
DispatchWithEvents
而不是
Dispatch
。我创建了一个非常简单的程序来说明我的问题:

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")
使用
Dispatch
,程序可以正确编译和运行。使用
DispatchWithEvents
,当从命令行调用时,程序运行正常,但在运行exe时产生以下错误:

Traceback (most recent call last):
File "sandbox.py", line 16, in <module>
  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'

然后你就可以开始你的工作了。

与其依赖缓存,我建议进入本地缓存目录,将生成的文件复制到本地项目文件中,并将其命名为类似ITunesInterface.py的名称,然后显式调用它。这将使py2exe将其拉入已编译的应用程序。

是正式的方法

(编辑:从上面的链接复制了逐字记录示例)


我遇到了完全相同的错误。 这个链接让我找到了正确的方向--> 然而,它提到: 注意:您必须确保python…\win32com.client.gen_py dir不存在 允许在%temp%中创建缓存 这有点让人困惑。
对我来说,解决这个问题的办法是将“C:\Python26\Lib\site packages\win32com\gen\u py”重命名为“C:\Python26\Lib\site packages\win32com\gen\u pybak”(运行py2exe时)

我认为这是可行的,但我似乎不知道如何显式调用接口,尤其是在事件中。我的
调度
正在工作,但后来意识到这只是正常地调用win32com。有关于如何做到这一点的信息吗?
File "<string>", line 16, in <module>
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
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)
import win32com.client
if win32com.client.gencache.is_readonly == True:

    #allow gencache to create the cached wrapper objects
    win32com.client.gencache.is_readonly = False

    # under p2exe the call in gencache to __init__() does not happen
    # so we use Rebuild() to force the creation of the gen_py folder
    win32com.client.gencache.Rebuild()

    # NB You must ensure that the python...\win32com.client.gen_py dir does not exist
    # to allow creation of the cache in %temp%

# Use SAPI speech through IDispatch
from win32com.client.gencache import EnsureDispatch
from win32com.client import constants
voice = EnsureDispatch("Sapi.SpVoice", bForDemand=0)
voice.Speak( "Hello World.", constants.SVSFlagsAsync )