在我的程序中,我使用WMI接口来查询有关运行程序的硬件的大量信息.然后我将这些信息放入一个列表中,以便稍后显示它,但目前还没有其他更多的信息.到目前为止,这种方法已经很好地解决了,但是有一个主要问题:有时查询是/返回(不知道哪一个!)Nothing并导致a NullReferenceException.
现在,显然我可以将它包装在Try/Catch中,并以我的快乐方式.但是,我想避免这样做,因为我将查询数百位信息,其中数百个可能会导致异常.这只是草率的编程,并且正在大大减慢我的程序!
我的问题是:我要检查什么才能使用If而不是Try?我将把我当前的代码放在下面,然后列出我已经尝试过的解决方案.
Public Shared Function GetSomeInfo() As List(Of String)
Dim ret As New List(Of String)
Dim sq As New Management.SelectQuery("Win32_Processor")
Dim mos As New Management.ManagementObjectSearcher(sq)
For Each info As Management.ManagementObject In mos.Get()
ret.Add(TryQuery(info, "Name"))
ret.Add(TryQuery(info, "Caption")) 'this query may result in Nothing somewhere...
Next
Return ret
End Function
Private Shared Function TryQuery(ByRef info As
Management.ManagementObject, ByVal strID As String) As String
Try
Return strID & ": " & info(strID).ToString 'exception obviously thrown here...but WHERE?
Catch ex As NullReferenceException
Return String.Empty
Catch ex As Management.ManagementException
Return String.Empty
End Try
End Function
Run Code Online (Sandbox Code Playgroud)
所以,这是我试图尝试使用它的方法Try:
If Not info Is Nothing Then ... 仍然导致一些未被捕获的例外
If Not info(strID) Is Nothing Then ... 在某个地方仍然有例外
If Not info.Equals(Nothing) Then ... 绝望
If Not Info(strID).ToString Is Nothing ... :(
我根本不知道在 WMI查询中抛出此异常的位置.任何见解将不胜感激.谢谢!
根据您的描述,虽然属性名称可能会列为给定WMI类的现有名称,但WMI PropertyData项目不可用于给定的属性名称.强制方法应该通过迭代正确的PropertyDataCollection来避免生成"未找到"异常.
Private Shared Function TryQuery(ByRef info As ManagementObject, ByVal strID As String) As String
Dim ret As String = String.Empty
Dim propDatas As PropertyDataCollection
If strID.StartsWith("__") Then
' system property, ref: https://msdn.microsoft.com/en-us/library/system.management.managementbaseobject.systemproperties(v=vs.110).aspx
propDatas = info.SystemProperties
Else
' object properties: ref: https://msdn.microsoft.com/en-us/library/system.management.managementbaseobject.properties(v=vs.110).aspx
propDatas = info.Properties
End If
For Each data As PropertyData In propDatas
If data.Name.Equals(strID, StringComparison.InvariantCultureIgnoreCase) Then
ret = If(data.Value, String.Empty).ToString
Exit For
End If
Next
Return ret
End Function
Run Code Online (Sandbox Code Playgroud)
此外,大多数WMI对象都Disposable应该并且应该相应地进行处理.
Public Shared Function GetSomeInfo() As List(Of String)
Dim ret As New List(Of String)
Dim sq As New Management.SelectQuery("Win32_Processor")
Using mos As New Management.ManagementObjectSearcher(sq)
Using objects As ManagementObjectCollection = mos.Get
For Each info As Management.ManagementObject In objects
Using info
ret.Add(TryQuery(info, "Name"))
ret.Add(TryQuery(info, "Caption")) 'this query may result in Nothing somewhere...
End Using
Next
End Using
End Using
Return ret
End Function
Run Code Online (Sandbox Code Playgroud)
编辑:为了确保此技术有效,您可以检查ManagementBaseObject上的索引器的源代码.此方法调用:
public Object GetPropertyValue(string propertyName)
{
if (null == propertyName)
throw new ArgumentNullException ("propertyName");
// Check for system properties
if (propertyName.StartsWith ("__", StringComparison.Ordinal))
return SystemProperties[propertyName].Value;
else
return Properties[propertyName].Value;
}
Run Code Online (Sandbox Code Playgroud)
您可以看到,这将检索与我提供的代码类似的属性.问题是如果ProdertyDataCollection类找不到匹配的属性名称,则会抛出"Not Found"错误.
| 归档时间: |
|
| 查看次数: |
430 次 |
| 最近记录: |