Python wmi参数已反转

Python wmi参数已反转,python,wmi,Python,Wmi,使用python的wmi模块创建vss快照,我发现除非我将参数反转,否则这些参数不起作用: import wmi def vss_create(): shadow_copy_service = wmi.WMI(moniker='winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy') res = shadow_copy_service.Create('ClientAccessible', 'C:\\') 在中,该函数应按以下方式使用: Wi

使用python的wmi模块创建vss快照,我发现除非我将参数反转,否则这些参数不起作用:

import wmi

def vss_create():
    shadow_copy_service = wmi.WMI(moniker='winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy')
    res = shadow_copy_service.Create('ClientAccessible', 'C:\\')
在中,该函数应按以下方式使用:

Win32_ShadowCopy.Create("C:\\", "ClientAccessible");
为什么会出现这种情况?是否有办法使用预定订单?

总结 看起来wmi对象方法的参数顺序在PyWin32层中与正常情况相反,并且这种行为已经存在至少五年了。相关的wmi规范说wmi客户端可以按任何顺序传递参数,因此PyWin32这样做并不是“错误的”,尽管我无法判断这是故意还是意外。我推测,出于向后兼容性的原因,它不太可能改变,但您可以解决这个问题,并通过将参数指定为关键字参数来按您想要的顺序排列:
Create(Volume=,Context=)

细节 注意。在下面的详细信息中,我尝试从Python WMI模块代码到PyWin32代码中COM访问的WMI对象,到其他语言中记录和使用的WMI对象,到MOF文件的WMI对象规范,再到规范文档。有几个层,我写了很多“WMI”,在不同的层上有不同的含义

当你说“Python的wmi模块”时,你是指(链接到源代码)构建在PyWin32上吗

从WMI模块获取Python WMI对象时,它所经历的初始化步骤在类
\u WMI\u object
中,包括查询底层WMI对象以获取其可用方法:

for m in ole_object.Methods_:
    self.methods[m.Name] = None
>>> from win32com.client import GetObject
>>> vss = GetObject('winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy')
>>> [method.Name for method in list(vss.Methods_)]
[u'Create', u'Revert']
我将跳过Python的wmi模块,直接使用PyWin32查看在查询wmi COM对象的可用方法时得到的结果:

for m in ole_object.Methods_:
    self.methods[m.Name] = None
>>> from win32com.client import GetObject
>>> vss = GetObject('winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy')
>>> [method.Name for method in list(vss.Methods_)]
[u'Create', u'Revert']
我们看到Win32_ShadowCopy对象具有方法
Create
Revert
。这就是Python wmi包装器第一次了解您正在使用的
Create
方法的地方


从那里开始,Python WMI包装器类完成了一些设置工作,我还没有完全跟踪这些工作,但它似乎为COM对象的每个可用方法初始化
class\u WMI\u方法一次。此类包括以下初始化步骤:

self.method = ole_object.Methods_ (method_name)
self.in_parameter_names = [(i.Name, i.IsArray) for i in self.in_parameters.Properties_]
一个列表,用于获取每个方法的可用参数。回到我的测试中,在没有Python WMI层的情况下,它会给出如下输出:

>>> CreateMethod = vss.Methods_('Create')
>>> [n.Name for n in list(CreateMethod.InParameters.Properties_)]
[u'Context', u'Volume']
此示例测试显示了PyWin32 later、Win32_ShadowCopy的COM对象、
Create
方法—按您看到的顺序列出其可用参数—顺序“错误”。PythonWMI层正在接受这种排序


当您通过Python WMI的包装器调用Win32\u ShadowCopy对象的
Create()
方法时,
\u WMI\u方法执行以下操作:

def __call__ (self, *args, **kwargs):
    for n_arg in range (len (args)):
      arg = args[n_arg]
      parameter = parameters.Properties_[n_arg]
      parameter.Value = arg
换言之;它将您传入的参数(
*args
)与存储的参数列表逐个配对,按照您传入参数的顺序获取参数,并按照WMI返回参数的顺序将其与方法参数配对-即,它不智能,它只是将您输入的第一个参数与“Context”链接起来,将第二个参数与“Volume”链接起来,并将它们向后移动,您的代码就会崩溃


调用方法还包括Python的
**kwargs
参数,该参数接受所有给定的关键字,建议您可以这样做

Create(Volume='C:\\', Context="ClientAccessible")
并将它们作为关键字参数按您想要的顺序排列。(我没有试过)


我曾尝试通过PyWin32com跟踪
.Properties\uuu
查找,以尝试确定较低层的排序来源,并通过一长串动态和缓存查找。我看不到会发生什么,我对COM或PyWin32的了解也不够,不知道要寻找什么样的东西,所以这对我来说是一条死胡同


采用另一种方法并尝试从WMI对象设置文件中找出排序的来源:运行Windows附带的
mofcomp.exe
,并处理托管对象格式(MOF)文件。。。单击连接,创建类“Win32_ShadowCopy”;单击方法列表中的“创建”方法,然后单击“编辑方法”按钮;然后单击“编辑输入参数”,然后单击“显示MOF”,得到以下结果:

[abstract]
class __PARAMETERS
{
    [in, ID(0): DisableOverride ToInstance] string Volume;
    [in, ID(1): DisableOverride ToInstance] string Context = "ClientAccessible";
};
这是来自Windows MOF文件的参数的“正确”顺序,参数带有数字ID,这意味着它们具有正确的顺序0、1等

c:\windows\system32\wbem\vss.mof
,似乎覆盖卷影复制对象的mof文件包含以下内容:

[static,implemented,constructor] uint32 Create([in] string Volume,[in] string Context = "ClientAccessible",[out] string ShadowID);
注释中的PowerShell示例包括
$class.create(“C:\”,“ClientAccessible”)

因此,这三件事都与相同的顺序联系在一起,意味着有一个正确的或标准的顺序

这让我想到了这些可能性:

  • PythonCOM中有订购信息,wmi模块应该查看,但没有我快速地四处查看了一下,找不到带有参数列表的ID/排序数据,所以这似乎不太可能
  • 有一些我不知道的订购信息,PyWin32 COM层应该查看这些信息,但没有查看我不确定
  • 没有官方命令。为了证实这一点,我们得到了一条有趣的链条:

  • 什么是WMI?微软对DTMF指定的标准管理框架WBEM和CIM的实施。(DTMF=分布式管理任务组,WBEM是基于Web的企业管理,CIM是通用信息模型)
  • MOF是托管对象格式,是CIM的文本表示形式
本文件:似乎是MOF规范。检查第18页的第7.3.3节类别声明:

第570行:

“一个方法可以有零个或多个参数”

第626至628行:

方法参数由名称而不是位置和参数标识 调用met的客户端