从WMI COM对象调用Win32_NetworkAdapterConfiguration例程

2 投票
3 回答
2641 浏览
提问于 2025-04-17 07:06

感谢大家的帮助。我正在尝试使用win32com模块设置网络接口的IP地址,但一直没能成功。我搜索了很多资料,但还是找不到解决这个问题的方法。以下是我运行的代码:

import win32com.client 
obj  = win32com.client.Dispatch("WbemScripting.SWbemLocator") 
wmobj = obj.ConnectServer("localhost","root\cimv2")
nobj = wmobj.ExecQuery("Select * from Win32_NetworkAdapterConfiguration")
for n in nobj:
    print n.Caption
    n.SetMTU('9000')
 

当我运行这段代码时,出现了以下错误:

Traceback (most recent call last):
  File "<pyshell#18>", line 3, in <module>
    n.SetMTU('9000')
  File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 505, in __getattr__
    ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
com_error: (-2147352567, 'Exception occurred.', (0, u'SWbemObjectEx', u'Invalid method ', None, 0, -2147217362), None)

我进行了更多的调试,发现我可以访问Win32Networking类的任何变量,但每当我尝试调用这个类的任何方法时,它都会返回同样的错误。

3 个回答

0

我刚刚试了试 FlagAsMethod

这是针对 Win32_Process 类的建议,举个例子:

proc10 = GetObject(pos).ExecQuery("Select * from Win32_Process")[10]
proc10._FlagAsMethod('GetOwner')
proc10.GetOwner()
# >> 0

不过,我期待的是 domain\user 这样的格式。此外,我也能写

proc10.GetOwner(10,20,30)

但效果是一样的。

我在 这里发了一个在我这儿有效的方法。我只是想知道 SetMTU 是否收到了正确的值,使用 _FlagAsMethod 的提示。

1

我遇到了类似的问题,找到了一个方法来调用Win32_NetworkAdapterConfiguration对象的这些方法。在这里,我没有直接使用这些方法,而是把所有的输入参数放进一个叫SpawnInstance_的东西里。听起来有点奇怪,但确实有效。

import win32com.client
objLocator = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objService = objLocator.ConnectServer(".","root\cimv2")
nobj = objService.ExecQuery("Select * from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
obj = nobj[0]

## here is the strange part. 
obj_method = obj.Methods_("SetWINSServer")
obj_in_param = obj_method.inParameters.SpawnInstance_()
obj_in_param.WINSPrimaryServer = "127.0.0.1"
obj_in_param.WINSSecondaryServer = "127.0.0.2"
#invoke the SetWINServer method, and it worked.
obj.ExecMethod_("SetWINSServer", obj_in_param)

几乎所有Win32_NetworkAdapterConfiguration的方法都可以这样使用。不过,“SetMTU”这个方法不行,可能是因为“这个方法不被支持”。我在Windows 2008R2上试过,结果也遇到了同样的错误。系统提示SetMTU在这里不被支持。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa393463(v=vs.85).aspx
2

我对使用 win32com 的经验不多,但可能 SetMTU 这个方法并没有实现。根据MSDN文档中关于 Win32_NetworkAdapterConfiguration类 的说明,这个方法是“不支持”的。在我的XP系统上调用它会失败。

需要注意的是,使用win32com时,单纯访问一个属性就可能会触发它:

>>> import win32com.client
>>> wmobj = obj.ConnectServer("localhost","root\cimv2")
>>> nobj = wmobj.ExecQuery("Select * from Win32_NetworkAdapterConfiguration")
>>> n = nobj[10]  #my wireless interface
>>> n.ReleaseDHCPLease  #invoked
0
>>> n.RenewDHCPLease
0

如果你尝试正常调用这个方法,结果会试图调用一个整数返回值,这样会引发一个 TypeError 错误。不过,你可以先把这个方法包装一下,让它变成一个正常的Python调用:

>>> n._FlagAsMethod('ReleaseDHCPLease')
>>> n._FlagAsMethod('RenewDHCPLease')
>>> n.ReleaseDHCPLease()
0
>>> n.RenewDHCPLease()
0

补充:

在上面链接的页面的用户贡献区域,搜索一下静态方法的列表,这些方法必须从类中访问,包括 SetMTU。获取这个类的方法如下:

>>> NetAdapterConfig = wmobj.Get("Win32_NetworkAdapterConfiguration")
>>> NetAdapterConfig._FlagAsMethod('SetMTU')

查看 文档 了解返回值的含义。虽然我其实不太明白这个方法在静态上下文中是干什么的。


下面是一个使用标准库 winreg 来更新注册表的例子:

import winreg

nid = n.SettingID
MTU = 1500

path = r'SYSTEM\CurrentControlSet\Services\TCPIP\Parameters\Interfaces\\'+ nid 
sam = winreg.KEY_ALL_ACCESS
adapter = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path, 0, sam)
winreg.SetValueEx(adapter, 'MTU', None, winreg.REG_DWORD, MTU)

撰写回答