从WMI COM对象调用Win32_NetworkAdapterConfiguration例程
感谢大家的帮助。我正在尝试使用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 个回答
我刚刚试了试 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
的提示。
我遇到了类似的问题,找到了一个方法来调用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我对使用 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)