python wmi mac变动_Python WMI参数反转
使用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参数反转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 倍福 在 vs 里 编程 是怎么做到的_
- 下一篇: mmtray2k.exe有什么作用 是什