我已经创建了一个独立的exe Windows服务,它是用Python语言编写并用pyInstaller构建的。当我尝试导入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 Monikerwmi.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()这显然解决了线程中的导入问题,但这并不起作用...
发布于 2017-10-06 21:10:31
我也面临着同样的问题,我最终解决了这个问题,导入pythoncom和CoInitialize pythoncom.CoInitialize ()。它们导入wmi
import pythoncom
pythoncom.CoInitialize ()
import wmi发布于 2016-08-11 01:03:13
我尝试了无数种方法来解决这个问题。最后,我认输了,不得不找到一种不同的方法来实现与wmi相同的目标。
显然,当尝试使用无效的“名字”创建对象时,会抛出无效语法错误,这可能只是意味着服务、应用程序等在系统上不存在。在这种情况下,似乎根本找不到"winmgmts“!是的,我尝试了这个绰号的许多变体和额外的规格,我尝试在不同的用户帐户下运行该服务,等等。
发布于 2019-05-06 22:33:09
错误"com_error:(-2147221020,‘无效语法’,无,无)“正是在我的案例中出现的错误,所以我在网上搜索了很长时间后来到这里,瞧:
在这种情况下,"winmgmts“似乎根本找不到
!
这是正确的提示,因为我只有一个打字错误,使用了"winmgmt:“而没有尾随”s“。所以无效的sythax指的是第一个方法参数,而不是python代码本身。o_0不幸的是,我找不到任何可以用win32com.client.GetObject()获得的对象的引用……因此,如果任何人对哪些参数是“允许的”/应该工作的有一个提示,请将其移植到这里。:-)
kind关于ChrisPHL
https://stackoverflow.com/questions/38860185
复制相似问题