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

importwmidefvss_create():shadow_copy_service=wmi.WMI(moniker='winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy')res=shadow_copy_service.Create('ClientAccessible','C:\\')

在msdn docs中,应该以这种方式使用该函数:

Win32_ShadowCopy.Create("C:\\","ClientAccessible");

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

解决方案

摘要

看起来Wmi对象的方法的参数顺序已被PyWin32层颠倒了,这种现象已经存在至少五年了。相关的wmi规范指出,wmi客户端可以按任何顺序传递参数,因此PyWin32这样做不是“错误”,尽管我无法确定这是故意还是偶然。我推测出于向后兼容的原因,它不太可能更改,但是您可以解决此问题,并通过将其指定为关键字参数来按所需顺序放置参数Create(Volume=, Context=)。

细节

注意在下面的详细信息中,我尝试逐层深入研究,从Python WMI模块代码到PyWin32代码中COM访问的WMI对象,再到其他语言中记录和使用的WMI对象,再到MOF文件指定的WMI对象规范,再到规格文件。有多个层次,我经常写“ WMI”,意思是不同层次上的不同事物。

当您说“ Python的wmi模块”时,您是说Tim Golden的基于PyWin32的Python WMI模块(链接到源代码)吗?

当从wmi模块获取Python WMI对象时,它经过的初始化步骤在类内_wmi_object,包括查询基础wmi对象以获取其可用方法:

forminole_object.Methods_:self.methods[m.Name]=None

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

>>>fromwin32com.clientimportGetObject>>>vss=GetObject('winmgmts:\\\\.\\root\\cimv2:Win32_ShadowCopy')>>>[method.Nameformethodinlist(vss.Methods_)][u'Create',u'Revert']

并且我们看到Win32_ShadowCopy对象具有方法Create和Revert。这就是Python wmi包装器首先了解Create您所使用的方法的地方。

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

self.method=ole_object.Methods_(method_name)self.in_parameter_names=[(i.Name,i.IsArray)foriinself.in_parameters.Properties_]

列表理解,以获取每种方法的可用参数。回到我的测试以探索没有Python WMI层的情况,它给出的输出如下:

>>>CreateMethod=vss.Methods_('Create')>>>[n.Nameforninlist(CreateMethod.InParameters.Properties_)][u'Context',u'Volume']

此示例测试显示了PyWin32,稍后是Win32_ShadowCopy的COM对象,该Create方法-按照您看到的顺序(“错误”顺序)列出其可用参数。Python WMI层正在接受该排序。

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

def__call__(self,*args,**kwargs):forn_arginrange(len(args)):arg=args[n_arg]parameter=parameters.Properties_[n_arg]parameter.Value=arg

换一种说法;它将传入(*args)的参数与存储的参数列表一对一地配对,按照传递它们的顺序获取参数,并按WMI返回它们的顺序将它们与方法参数配对-即,它不是智能的,它只需将您输入的第一个参数与“上下文”链接起来,将第二个参数与“音量”链接起来,然后将它们向后移动,代码就会崩溃。

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

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

并通过将它们用作关键字参数将它们按所需的顺序排列。(我没有尝试过)。

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

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

[abstract]class__PARAMETERS{[in,ID(0):DisableOverrideToInstance]stringVolume;[in,ID(1):DisableOverrideToInstance]stringContext="ClientAccessible";};

这是Windows MOF文件中参数的“正确”顺序,带有参数的数字ID-表示它们的正确顺序为0、1等。

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

[static,implemented,constructor]uint32Create([in]stringVolume,[in]stringContext="ClientAccessible",[out]stringShadowID);

MSDN链接的注释中的PowerShell示例包括$class.create("C:\", "ClientAccessible")。

因此,这三件事都以相同的顺序捆绑在一起,并暗示存在正确或标准的顺序。

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

有一些订购信息是从PythonCOM发出的,而wmi模块应该查看它,但是没有。-我快速浏览了一下,找不到带有参数列表的ID /订购数据,因此似乎不太可能。

PyWin32 COM层应该查看但我不知道的某个地方有订购信息。-不确定这里。

没有官方订购。为了确认这一点,我们得到了一个有趣的链条:

什么是WMI?DTMF指定的Microsoft标准管理框架WBEM和CIM的实现。(DTMF =分布式管理工作组,WBEM是基于Web的企业管理,CIM是公共信息模型)。

MOF是托管对象格式,是CIM的文本表示形式

570行:

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

626至628行:

方法参数是通过名称而不是位置来标识的,并且调用方法的客户端可以按任何顺序传递相应的参数。因此,可以在任何位置将具有默认值的参数添加到方法签名中。

我不确定这是否是权威性的最新规范,也无法阅读所有的规范以查找异常,但是听起来您应该使用命名参数。

WMI对象和方法具有MOF定义,并且MOF规范指出您不应依赖参数排序。但是,通过PyWin32通过COM访问WMI对象显示了不同的顺序(MSDN文档,MOF文件和PowerShell示例)。我仍然不知道为什么。

而谷歌搜索这 使我这个添金,Python的WMI模块的作者的邮件列表的帖子,他说基本上是相同的事情我只是发现,除五年前:

方法定义按照WMI返回它们的顺序来拾取参数[..]我不知道是否有关于参数[..]顺序的任何保证,看上去还有其他一些方法定义,好像WMI始终按照MOF中定义的相反顺序返回参数。

在这一点上,PyWin32似乎将反向列表返回到典型的Windows参数顺序,但是如果CIM受管对象方法参数列表规范文档明确表示不依赖参数顺序,那是否是一个bug?

python wmi mac变动_Python WMI参数反转相关推荐

  1. python读取mac地址_python - 获取MAC地址

    python - 获取MAC地址 我需要一种在运行时确定计算机MAC地址的跨平台方法. 对于Windows,可以使用'wmi'模块,我可以找到Linux下唯一的方法是运行ifconfig并在其输出中运 ...

  2. python修改mac地址_python利用_winreg模块制作MAC地址修改工具

    通过百度搜索知道,xp下修改MAC地址的方法主要有两个,一种是通过配置本地链接属性来实现,这种方法不适合用程序来完成,另一种是通过修改注册表来完成,本程序主要是利用了这种方法. 具体方法:Window ...

  3. python wmi 显卡型号_python - wmi模块学习(windwos硬件信息获取)

    #!/usr/bin/env python#-*- coding: utf-8 -*-#http://www.cnblogs.com/liu-ke/ importwmiimportosimportsy ...

  4. python冒号声明类型_Python 函数参数有冒号 声明后有- 箭头 返回值注释 参数类型注释...

    在python3.7 环境下 函数声明时能在参数后加冒号,如图: 1 def f(ham: str, eggs: str = 'eggs') -> str : 2 print("Ann ...

  5. python中figure函数_Python figure参数及subplot子图绘制代码

    1. Python的figure参数主要有: def figure(num=None, # autoincrement if None, else integer from 1-N figsize=N ...

  6. python 正则式替换_python 正则表达式参数替换实例详解

    正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re 模块使 Python ...

  7. python m什么意思_Python -m参数原理及使用方法解析

    作用是:把xxx.py文件当做模块启动 但是我一直不明白当做模块启动到底有什么用.python xxx.py和python -m xxx.py有什么区别! 自问自答:python xxx.py pyt ...

  8. python函数赋值函数_python 函数参数赋值过程

    形参赋值的过程是这样的:首先按顺序把"arg"这种形式的实参给对应的形参第二,把"arg="这种形式的实参赋值给形式第三,把多出来的"arg" ...

  9. python wmi安装_Python wmi 模块的学习

    # -*- coding:utf-8 -*- import datetime import os import wmi import time import _winreg import python ...

最新文章

  1. sqlite3命令详解
  2. 致NLP学习者,该跟大佬学习做项目了,附资料
  3. InnoDB的auto_increment指定值被重置问题
  4. vue2 父子组件传参 回调函数使用
  5. vue里面v-cloak/v-text/v-html/v-pre的应用
  6. Scipy教程 - python数值计算库
  7. 汉字乱码的终极解决方案
  8. MT4 缠论双线MACD面积背离指标
  9. php使用blob加密视频,javascript实现blob加密视频源地址的方法
  10. 数据结构实训之商店存货管理系统(c+html+pyhon)
  11. Python Des加密与解密实现软件注册码、机器码
  12. windows虚拟网卡驱动开发
  13. mariadb 卸载 Kali_Revo Uninstaller(卸载工具) 专业版!!!
  14. Python数据分析案例09——航空公司客户聚类分析
  15. 栈和队列的顺序和链式存储结构
  16. LaTex便捷插入罗马数字
  17. knx ets5安装
  18. adb命令模拟按键事件 KeyCode
  19. ROS通信机制:话题、服务、参数
  20. 集成创新,拓展兼容--红旗Linux桌面版5.0隆重发布(转)

热门文章

  1. string的反转输出以及char型字符串的反转输出
  2. android无线充产品,一天售罄!鲁蛋超薄无线快充太火爆 兼容苹果安卓成最大卖点...
  3. android 相册 uri空,Android---相册getContentResolver().query结果为空指针
  4. len在python_len在python
  5. yum安装ruby_centos 6.5 ruby环境安装
  6. 编译libxml2-2.6.26 __open_missing_mode 错误
  7. 中国的程序员为什么这么辛苦?
  8. nginx 怎么重新编译安装mysql,centos 下 编译安装 nginx + mysql + php 服务
  9. linux中将hdfs数据导入hbase,将数据文件导入到HBase中
  10. 利用python读取点矢量对应栅格值