Python wmi参数已反转

2024-06-06 02:39:13 发布

您现在位置:Python中文网/ 问答频道 /正文

使用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:\\')

msdn docs中,函数的用法应该是这样的:

^{pr2}$

为什么会这样?有没有办法使用预定的订单?在


Tags: 模块import参数defcreateservicevssroot
1条回答
网友
1楼 · 发布于 2024-06-06 02:39:13

摘要

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

细节

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

当你说“Python的wmi模块”是指在PyWin32上构建的Tim Golden's Python WMI module(链接到源代码)吗?在

当您从WMI模块获得一个Python WMI对象时,它所经历的初始化步骤在类_wmi_object内,包括查询底层WMI对象以获取其可用方法:

for m in ole_object.Methods_:
    self.methods[m.Name] = None

我将跳过Python的wmi模块,直接使用PyWin32查看在查询wmicom对象以获取其可用方法时得到的结果:

^{pr2}$

我们看到Win32的ShadowCopy对象有Create和{}方法。因此,pythonwmi包装器首先了解您使用的Create方法。在


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

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,win32u ShadowCopy的COM对象,Create方法-按您看到的顺序列出了它的可用参数-“错误”顺序。pythonwmi层正在接受这个顺序。在


当WMI{cdu>的wrapper{cdu>方法调用

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”并将它们向后获取,代码就会崩溃。在


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

Create(Volume='C:\\', Context="ClientAccessible")

并将它们作为关键字参数按您想要的顺序排列。(我没试过)。在


我尝试过通过PyWin32com跟踪.Properties_查找,以尝试确定在较低层的排序来自何处,并且它经历了一长串动态和缓存的查找链。我看不到会发生什么,而且我对COM或PyWin32的理解也不足以知道要寻找什么样的东西,所以这对我来说是一个死胡同。在


采取不同的方法,并试图从WMI对象设置文件中找到排序的来源:runmofcomp.exe,它与Windows一起提供,并处理托管对象格式(MOF)文件。。。点击Connect,创建类“Win32_ShadowCopy”;点击方法列表中的“Create”方法,点击“Edit method”按钮;点击“Edit Input Arguments”,点击“Show MOF”,得到如下结果:

[abstract]
class __PARAMETERS
{
    [in, ID(0): DisableOverride ToInstance] string Volume;
    [in, ID(1): DisableOverride ToInstance] string Context = "ClientAccessible";
};

这是参数的“正确”顺序rs来自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);

而位于this MSDN link的注释中的PowerShell示例包括$class.create("C:\", "ClientAccessible")。在

所以这三样东西都有相同的顺序,意味着有一个正确的或标准的顺序。在

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

  • PythonCOM中有一些排序信息,wmi模块应该查看它,但是没有。-我已经快速地查看了一下,没有找到带有参数列表的ID/排序数据,因此这似乎不太可能。在
  • 在我不知道的地方有一个我不知道的排序信息,Pywin32COM层应该查看它,但是没有。-这里不确定。在
  • 没有官方的命令。为了证实这一点,我们得到了一个有趣的链接:

    1. 什么是WMI?微软实施的标准管理框架WBEM和CIM,由DTMF指定。(DTMF=分布式管理任务组,WBEM是基于Web的企业管理,CIM是通用信息模型)。在
    2. MOF是托管对象格式,是CIM的文本表示

此文档:http://www.dmtf.org/sites/default/files/standards/documents/DSP0221_3.0.0.pdf似乎是MOF规范。查看第18页的7.3.3类声明

570号线:

"A method can have zero or more parameters".

第626至628行:

Method parameters are identified by name and not by position and clients invoking a method can pass the corresponding arguments in any order. Therefore parameters with default values can be added to the method signature at any position.

我不确定这是否是一个权威的和最新的规范,我也没有阅读所有的异常,但听起来你应该使用命名参数。在


WMI对象和方法有一个MOF定义,MOF规范说您不应该依赖参数排序;但是,通过PyWin32通过COM访问WMI对象显示了不同的顺序(MSDN docs、MOF文件和PowerShell示例)。我还是不知道为什么。在

在google上搜索Python wmi模块的作者Tim Golden的邮件列表,说的基本上和我刚刚发现的一样,除了五年前:

the method definition picks up the parameters in the order in which WMI returns them [..] I've got no idea if there is any guarantee about the order of parameters [..] Glancing at a few other method definitions, it does seem as though WMI is consistently returning params in the reverse order of their definition in the MOF.

在这一点上,PyWin32看起来像是将一个颠倒的列表返回到典型的Windows参数顺序,但是如果CIM managed object method参数列表规范文档明确地说不依赖参数顺序,那么这是一个错误吗?在

相关问题 更多 >