获得从C#称为COM方法的错误信息(Getting the error message of a C

2019-09-26 16:35发布

这里是我的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;
}

这是我这调用C#代码TestCrap方法:

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 。 我失去了一些东西在这里? 我实现ISupportErrorInfo以下本指南 ,它说在维基百科说:

在.NET Framework,HRESULT /的IErrorInfo错误代码被转换成从本机转换到托管代码当CLR异常; 和从成功地机COM代码转换时CLR异常被转换为HRESULT /的IErrorInfo错误代码。

我怎样才能正确地设置并取回错误信息?

当前异常的消息是

错误HRESULT E_FAIL已经从COM组件的调用返回。

...但我希望它返回这是香蕉。

Answer 1:

你应该总是做正确的错误在你的代码检查。 这一呼吁:

SetErrorInfo(errorCode, pErrorInfo);

返回E_INVALIDARG因为第一个参数必须是0按照官方文件 。 通过替换它:

SetErrorInfo(0, pErrorInfo);

它会奏效。



文章来源: Getting the error message of a COM method called from C#
标签: c# c++ .net com atl