我有以下 COM 接口(interface)和实现此接口(interface)的 COM 对象:
[
object,
uuid(8FF1207F-24DD-4F34-B6CB-D90904CF4094),
dual
]
interface IThrowingProperty : IDispatch
{
[id(1), propget]
HRESULT IntPropertyValue([out, retval] int* pVal);
}
[
uuid(3869048C-A14F-4536-9FFC-0A4ECAEF2B08)
]
coclass ThrowingProperty
{
[default] interface IThrowingProperty;
};
此属性始终返回错误:
STDMETHODIMP CThrowingProperty::get_IntPropertyValue(/*[out,retval]*/ int* pVal)
{
return E_NOTIMPL;
}
但是当我尝试在 Powershell 中访问它时,我没有收到任何错误,并且属性值等于 $null:
$PropertyWillThrow = New-Object -ComObject "PowershellCom.ThrowingProperty"
$PropertyWillThrow.IntPropertyValue
$PropertyWillThrow.IntPropertyValue -eq $null
是否可以在不将属性更改为方法的情况下从 Powershell 中的 COM 属性中获取错误?
谢谢
最佳答案
请注意,此解决方案并非特定于 COM 对象,而是适用于 PowerShell 中的任何对象类型。
它不会抛出错误,它只会返回 $null
.这是 PowerShell 在访问对象上不存在的属性时的正常行为。但是,您可以通过以下代码检查该属性是否真正定义在对象上。针对 Excel COM 对象进行测试:
# Returns true if property exists
$excel = New-Object -ComObject Excel.Application
[bool]( $excel.PSobject.Properties.Name -match 'EnableCheckFileExtensions' ) # ==> True
[bool]( $excel.PSobject.Properties.Name -match 'NonExistentPropertyName' ) # ====> False
EnableCheckFileExtensions
是 Microsoft.Office.Interop.Excel.ApplicationClass
上的属性类型,所以它返回 true,但是 NonExistantPropertyName
不存在,因此评估返回 false。如果你想要一个错误驱动的行为,你可以使用
Add-Member
添加 ScriptMethod
到 PowerShell 端的 COM 对象,以在访问该属性之前检查该属性是否存在。再次以之前的 Excel COM 对象为例:$checkPropertyExistsBlock = {
Param(
[string]$memberName
)
if( [bool]( $This.PSobject.Properties.Name -match $memberName ) ) {
$This.$memberName
} else {
throw "Property ${memberName} does not exist"
}
}
$excel | Add-Member -MemberType ScriptMethod -Name 'GetPropertyByName' -Value $checkPropertyExistsBlock
$excel.GetPropertyByName( 'EnableCheckFileExtensions' ) # ==> Returns property value
$excel.GetPropertyByName( 'NonExistentPropertyName' ) # ====> throws exception
当然,如果你自己控制类的源代码,你也可以添加
GetPropertyByName
作为类的方法,并使用反射来实现与 ScriptBlock
相同的逻辑上面,而不必在初始化后修改运行中的对象。
关于访问失败的 COM 属性时,Powershell 返回 null 而不是异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59863506/