我用这个撞了壁。我需要创建一个基于python的com服务器,将其打包为windowsexe并部署到windows上。它必须有一个“完整”的接口,因为消费者需要idispatch和一个特定的接口才能正常工作。现在我已经创建了com服务器,并在解释器下运行,它可以完美地与我挑剔的客户机一起工作。但是,当打包为EXE(它是一个localserver)时,当系统尝试实例化它时(即使是从vbs脚本中),我在日志中得到一个错误。一切都在这里。我在itnernet中搜索了高和低,这看起来像是一个导入问题,但我不知道如何导入我自己的python对象供localserver使用。在
这是安装了pywin32扩展的python2.7。在
首先,我为服务器创建的IDL:
在图3.idl在
// This file will be processed by the MIDL tool to
// produce the type library (imtg.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(4fafbb23-6a38-4613-b93b-68ea66c67043),
dual,
helpstring("IImtGroupApp Interface"),
pointer_default(unique)
]
interface IImtGroupApp : IDispatch
{
[id(1), helpstring("method EchoString")] HRESULT EchoString([in] BSTR in1, [out, retval] BSTR *vals);
[id(2), helpstring("method AddNumbers")] HRESULT AddNumbers([in] long in1, [in] long in2, [out, retval] long *vali);
};
[
uuid(d665e9d0-71a9-4e23-a1b4-abe3376d5c58),
version(1.0),
helpstring("ImtGroup 1.0 Type Library")
]
library IMTGROUPLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
importlib("msado15.dll");
[
uuid(ced66424-93fb-4307-9062-7bee76d3d8eb),
helpstring("ImtGroupApp Class")
]
coclass ImtGroupApp {
[default] interface IImtGroupApp;
};
};
接下来是Python代码-现在这有点棘手,因为当我发布它时,我不想创建.tlb-所以我不分发.idy-只要确保你有.tbl来注册。如有必要,使用as admin cmd提示符。在
imtg公司_服务器.py在
^{pr2}$接下来是py2exe的设置
我不得不添加modulefinder的奇怪导入,因为win32com.shell公司未包含在打包的可执行文件中
设置_图像.py在
# This setup script builds a single-file Python inprocess COM server.
#
import modulefinder
import win32com, sys
for p in win32com.__path__[1:]:
modulefinder.AddPackagePath("win32com",p)
for extra in ["win32com.shell"]:
__import__(extra)
m = sys.modules[extra]
for p in m.__path__[1:]:
modulefinder.AddPackagePath(extra, p)
from distutils.core import setup
import py2exe
import sys
# If run without args, build executables, in quiet mode.
if len(sys.argv) == 1:
sys.argv.append("py2exe")
sys.argv.append("-q")
class Target:
def __init__(self, **kw):
self.__dict__.update(kw)
# for the versioninfo resources
self.name = "IMTG Server"
################################################################
# pywin32 COM pulls in a lot of stuff which we don't want or need.
CImtg = Target(
description = "Sample COM server",
# what to build. For COM servers, the module name (not the
# filename) must be specified!
modules = ["imtg_server"],
# we only want the inproc server.
)
excludes = ["pywin", "pywin.debugger", "pywin.debugger.dbgcon",
"pywin.dialogs", "pywin.dialogs.list"]
options = {
"bundle_files": 1, # create singlefile exe
"compressed": 1, # compress the library archive
"excludes": excludes,
"dll_excludes": ["w9xpopen.exe"] # we don't need this
}
setup(
options = {"py2exe": options},
zipfile = None, # append zip-archive to the executable.
com_server = [CImtg]
)
运行生成的EXE时,可以使用
imtg_服务器—注册
但你看不到输出
--注销注销
您可以使用此vbs文件来测试它。在
t.vbs公司
dim MD
set MD = CreateObject("ImtGroup.Test")
dim response
response = MD.EchoString("Really")
MsgBox(response)
运行时将创建一个.log,如下所示:
pythoncom error: ERROR: server.policy could not create an instance.
Traceback (most recent call last):
File "win32com\server\policy.pyc", line 136, in CreateInstance
File "win32com\server\policy.pyc", line 194, in _CreateInstance_
File "win32com\server\policy.pyc", line 727, in call_func
File "win32com\server\policy.pyc", line 717, in resolve_func
AttributeError: 'module' object has no attribute 'CImtg'
pythoncom error: Unexpected gateway error
Traceback (most recent call last):
File "win32com\server\policy.pyc", line 136, in CreateInstance
File "win32com\server\policy.pyc", line 194, in _CreateInstance_
File "win32com\server\policy.pyc", line 727, in call_func
File "win32com\server\policy.pyc", line 717, in resolve_func
AttributeError: 'module' object has no attribute 'CImtg'
pythoncom error: CPyFactory::CreateInstance failed to create instance. (80004005)
所以我需要的是绕过这个错误。这个类当然是我的目标。我担心我在服务器中指定的值为:
_reg_class_spec_ = "__main__.CImtg"
不正确。main可能引用包装好的exe文件,而不是我自己的未指定main的服务器。我也尝试过创建main,但没有得到更好的结果。我只是不知道py2exe如何代理类。我试着用我的文件名imtg_服务器.CImtg如果找不到模块,则失败。我试过CImtg,但失败了。我尝试过使用win32com和pythoncom的变体,但它做不到。我所做的似乎“正确”,所以也许我需要一个额外的reg标签或其他什么东西?非常感谢任何帮助。谢谢您。在
我终于弄明白了。我希望它能帮助其他人解决这个问题。在
这是导入的问题。py2exe打包的方式就是在作为com服务器运行时找不到合适的部分。我在下面发布的内容有效。在
所以第一件事是设置需要像这样。注意在选项中添加了“packages”,其中包括我的com服务器。这很重要,因为我们要将
__reg_class_spec__
改为显式地指向它。在所以整个修改后的设置_图像.py在
现在,我更改了服务器代码,指定
_reg_class_spec_
指向imtg_服务器.CImtg. 在但还不止这些!我们从启动com服务器的代码开始这样做。我们不需要那样做!我开始使用的初始示例使用了py2exe并构建了一个控制台应用程序而不是com_服务器,但是py2exe确实构建了一个com服务器,因此我们不需要再次启动它-因此删除了以下代码:
^{pr2}$但正如他们所说-这还不是全部!因为我们包含了包本身,所以我们正在执行的“name”不是
__main__
,而是imtg\u服务器!在所以除了main之外,这里还有一个检查,以防您正在开发而不是部署。现在的大部分代码都是确定运行的方式,并进行适当的检查和运行,因为还有一件事!从IDL中获取用于从IDL构建typelib或注册typelib所运行的目录,会将exe的名称附加到路径中,而运行解释器时则不会!所以我不得不把它脱掉。在
请记住,当您运行exe时,打印语句将被抑制,因此当您注册时,不必担心什么也不显示。如果出现问题,将创建一个.log文件。在
以下是imtg的工作代码_服务器.py享受
相关问题 更多 >
编程相关推荐