我创建了一个用Python编写并使用pyInstaller构建的独立的exe Windows服务。当我尝试导入wmi时,会抛出异常。
真正令人费解的是,如果在前台exe,前景python脚本或通过pythonservice.exe作为后台服务运行的python脚本中运行代码,我可以毫无问题地执行此操作!
为什么在作为服务exe运行的特殊情况下它会失败?
import wmi
为我生成此错误:
com_error: (-2147221020, 'Invalid syntax', None, None)
这里是追溯:
Traceback (most recent call last):
File "<string>", line 43, in onRequest
File "C:\XXX\XXX\XXX.pyz", line 98, in XXX
File "C:\XXX\XXX\XXX.pyz", line 31, in XXX
File "C:\XXX\XXX\XXX.pyz", line 24, in XXX
File "C:\XXX\XXX\XXX.pyz", line 34, in XXX
File "C:\Program Files (x86)\PyInstaller-2.1\PyInstaller\loader\pyi_importers.py", line 270, in load_module
File "C:\XXX\XXX\out00-PYZ.pyz\wmi", line 157, in <module>
File "C:\XXX\XXX\out00-PYZ.pyz\win32com.client", line 72, in GetObject
File "C:\XXX\XXX\out00-PYZ.pyz\win32com.client", line 87, in Moniker
wmi.py第157行对GetObject进行全局调用:
obj = GetObject ("winmgmts:")
win32com \ client__init.py__包含GetObject(),最终调用Moniker():
def GetObject(Pathname = None, Class = None, clsctx = None):
"""
Mimic VB's GetObject() function.
ob = GetObject(Class = "ProgID") or GetObject(Class = clsid) will
connect to an already running instance of the COM object.
ob = GetObject(r"c:\blah\blah\foo.xls") (aka the COM moniker syntax)
will return a ready to use Python wrapping of the required COM object.
Note: You must specifiy one or the other of these arguments. I know
this isn't pretty, but it is what VB does. Blech. If you don't
I'll throw ValueError at you. :)
This will most likely throw pythoncom.com_error if anything fails.
"""
if clsctx is None:
clsctx = pythoncom.CLSCTX_ALL
if (Pathname is None and Class is None) or \
(Pathname is not None and Class is not None):
raise ValueError("You must specify a value for Pathname or Class, but not both.")
if Class is not None:
return GetActiveObject(Class, clsctx)
else:
return Moniker(Pathname, clsctx)
Moniker()中的第一行,即MkParseDisplayName()是遇到异常的地方:
def Moniker(Pathname, clsctx = pythoncom.CLSCTX_ALL):
"""
Python friendly version of GetObject's moniker functionality.
"""
moniker, i, bindCtx = pythoncom.MkParseDisplayName(Pathname)
dispatch = moniker.BindToObject(bindCtx, None, pythoncom.IID_IDispatch)
return __WrapDispatch(dispatch, Pathname, clsctx=clsctx)
注意:我尝试使用
pythoncom.CoInitialize()
显然在一个帖子中解决了这个导入问题,但是没有用......
答案 0 :(得分:5)
我也面临同样的问题,最后我发现了这个问题, 导入pythoncom和CoInitialize pythoncom.CoInitialize()。他们导入wmi
import pythoncom
pythoncom.CoInitialize ()
import wmi
答案 1 :(得分:0)
我尝试过无数种方式。最后,我全身心投入,不得不找到一种不同的方法来实现与wmi相同的目标。
显然,当尝试创建具有无效&#34;名字对象名称&#34;的对象时,会抛出无效的语法错误,这可能只是意味着系统上不存在服务,应用程序等。在这种情况下&#34; winmgmts&#34;似乎根本无法找到它!是的,我尝试使用其他规格对该名称进行了大量修改,并尝试在不同的用户帐户下运行该服务等。
答案 2 :(得分:0)
错误“ com_error:(-2147221020,'无效语法',None,None)“正是我的情况,因此经过长时间的网上搜索后我才来到这里:
在这种情况下根本找不到“ winmgmts” 似乎!
这是正确的提示,因为我只有一个错字,使用了“ winmgmt:”而没有在后面加上“ s”。因此,无效的sythax是指第一个方法参数,而不是python代码本身。 o_0不幸的是,我找不到任何引用,我们可以通过win32com.client.GetObject()获得哪些对象...因此,如果有人暗示“允许”使用参数/应该起作用,请在此处进行移植。 :-)
亲切的问候 克里斯·菲尔(ChrisPHL)
答案 3 :(得分:0)
老实说,我没有挖洞是为了理解为什么会发生这种情况。
无论如何,以下导入解决了我的问题-仅在从Flask实例运行时才发生:
import os
import pythoncom
pythoncom.CoInitialize()
from win32com.client import GetObject
import wmi