获取从 C# 调用的 COM 方法的错误消息
Getting the error message of a COM method called from C#
这是我的 IDL:
[
object,
uuid(61B0BFF7-E9DF-4D7E-AFE6-49CC67245257),
dual,
nonextensible,
pointer_default(unique)
]
interface ICrappyCOMService : IDispatch {
typedef
[
uuid(C65F8DE6-EDEF-479C-BD3B-17EC3F9E4A3E),
version(1.0)
]
struct CrapStructure {
INT ErrorCode;
BSTR ErrorMessage;
} CrapStructure;
[id(1)] HRESULT TestCrap([in] INT errorCode, [in] BSTR errorMessage, [in, out] CrapStructure *crapStructure);
};
[
uuid(763B8CA0-16DD-48C8-BB31-3ECD9B9DE441),
version(1.0),
]
library CrappyCOMLib
{
importlib("stdole2.tlb");
[
uuid(F7375DA4-2C1E-400D-88F3-FF816BB21177)
]
coclass CrappyCOMService
{
[default] interface ICrappyCOMService;
};
};
这是我的 C++ 实现:
STDMETHODIMP CCrappyCOMService::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* const arr[] = {
&IID_ICrappyCOMService
};
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP CCrappyCOMService::TestCrap(INT errorCode, BSTR errorMessage, CrapStructure *crapStructure) {
memset(crapStructure, 0, sizeof(CrapStructure));
crapStructure->ErrorCode = errorCode;
crapStructure->ErrorMessage = errorMessage;
ICreateErrorInfo* pCreateErrorInfo;
CreateErrorInfo(&pCreateErrorInfo);
pCreateErrorInfo->AddRef();
pCreateErrorInfo->SetDescription(errorMessage);
pCreateErrorInfo->SetGUID(IID_ICrappyCOMService);
pCreateErrorInfo->SetSource(L"CCrappyCOMService::TestCrap");
IErrorInfo* pErrorInfo;
pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo);
pErrorInfo->AddRef();
SetErrorInfo(errorCode, pErrorInfo);
pErrorInfo->Release();
pCreateErrorInfo->Release();
return E_FAIL;
}
这是调用 TestCrap
方法的 C# 代码:
static void Main(string[] args)
{
var service = new CrappyCOMService();
var crapStructure = new CrapStructure();
try
{
service.TestCrap(1337, "This is bananas.", ref crapStructure);
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
Console.WriteLine(crapStructure.ErrorCode);
Console.WriteLine(crapStructure.ErrorMessage);
}
我似乎无法弄清楚如何读回我传递给 IErrorInfo
的错误消息。我在这里错过了什么吗?我在 this guide and it says on Wikipedia 之后实施了 ISupportErrorInfo
:
In the .NET Framework, HRESULT/IErrorInfo error codes are translated
into CLR exceptions when transitioning from native to managed code;
and CLR exceptions are translated to HRESULT/IErrorInfo error codes
when transitioning from managed to native COM code.
如何正确设置和取回错误信息?
当前异常信息为
Error HRESULT E_FAIL has been returned from a call to a COM component.
...但我希望它 return 这是香蕉。。
您应该始终在代码中进行适当的错误检查。此调用:
SetErrorInfo(errorCode, pErrorInfo);
returns E_INVALIDARG 因为根据 official documentation 第一个参数 必须 为 0。替换为:
SetErrorInfo(0, pErrorInfo);
它会起作用。
这是我的 IDL:
[
object,
uuid(61B0BFF7-E9DF-4D7E-AFE6-49CC67245257),
dual,
nonextensible,
pointer_default(unique)
]
interface ICrappyCOMService : IDispatch {
typedef
[
uuid(C65F8DE6-EDEF-479C-BD3B-17EC3F9E4A3E),
version(1.0)
]
struct CrapStructure {
INT ErrorCode;
BSTR ErrorMessage;
} CrapStructure;
[id(1)] HRESULT TestCrap([in] INT errorCode, [in] BSTR errorMessage, [in, out] CrapStructure *crapStructure);
};
[
uuid(763B8CA0-16DD-48C8-BB31-3ECD9B9DE441),
version(1.0),
]
library CrappyCOMLib
{
importlib("stdole2.tlb");
[
uuid(F7375DA4-2C1E-400D-88F3-FF816BB21177)
]
coclass CrappyCOMService
{
[default] interface ICrappyCOMService;
};
};
这是我的 C++ 实现:
STDMETHODIMP CCrappyCOMService::InterfaceSupportsErrorInfo(REFIID riid)
{
static const IID* const arr[] = {
&IID_ICrappyCOMService
};
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
if (InlineIsEqualGUID(*arr[i], riid))
return S_OK;
}
return S_FALSE;
}
STDMETHODIMP CCrappyCOMService::TestCrap(INT errorCode, BSTR errorMessage, CrapStructure *crapStructure) {
memset(crapStructure, 0, sizeof(CrapStructure));
crapStructure->ErrorCode = errorCode;
crapStructure->ErrorMessage = errorMessage;
ICreateErrorInfo* pCreateErrorInfo;
CreateErrorInfo(&pCreateErrorInfo);
pCreateErrorInfo->AddRef();
pCreateErrorInfo->SetDescription(errorMessage);
pCreateErrorInfo->SetGUID(IID_ICrappyCOMService);
pCreateErrorInfo->SetSource(L"CCrappyCOMService::TestCrap");
IErrorInfo* pErrorInfo;
pCreateErrorInfo->QueryInterface(IID_IErrorInfo, (void**)&pErrorInfo);
pErrorInfo->AddRef();
SetErrorInfo(errorCode, pErrorInfo);
pErrorInfo->Release();
pCreateErrorInfo->Release();
return E_FAIL;
}
这是调用 TestCrap
方法的 C# 代码:
static void Main(string[] args)
{
var service = new CrappyCOMService();
var crapStructure = new CrapStructure();
try
{
service.TestCrap(1337, "This is bananas.", ref crapStructure);
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
Console.WriteLine(crapStructure.ErrorCode);
Console.WriteLine(crapStructure.ErrorMessage);
}
我似乎无法弄清楚如何读回我传递给 IErrorInfo
的错误消息。我在这里错过了什么吗?我在 this guide and it says on Wikipedia 之后实施了 ISupportErrorInfo
:
In the .NET Framework, HRESULT/IErrorInfo error codes are translated into CLR exceptions when transitioning from native to managed code; and CLR exceptions are translated to HRESULT/IErrorInfo error codes when transitioning from managed to native COM code.
如何正确设置和取回错误信息?
当前异常信息为
Error HRESULT E_FAIL has been returned from a call to a COM component.
...但我希望它 return 这是香蕉。。
您应该始终在代码中进行适当的错误检查。此调用:
SetErrorInfo(errorCode, pErrorInfo);
returns E_INVALIDARG 因为根据 official documentation 第一个参数 必须 为 0。替换为:
SetErrorInfo(0, pErrorInfo);
它会起作用。