我为应用程序的 gRPC 远程处理接口的客户端创建了一个 C# .NET 6 COM 互操作 DLL(由安装程序使用 REGSVR32 注册),该接口在我们之前的产品版本中运行良好。
对于我们的新软件版本,我需要添加更多方法来扩展接口。 但是,当我添加其他方法时,接口方法似乎变得混乱,导致 gRPC 中出现 COM 封送异常。 我尝试调试客户端 COM 对象,但没有成功地通过附加到进程来调试它。
这是原始的接口定义:
[ComVisible(true)]
[Guid("9DAF4501-4AF6-43FF-95EF-C421CB43F1B8")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[System.Reflection.Obfuscation(Feature = "renaming", Exclude = true, ApplyToMembers = true)]
public interface IWinCalClient5
{
[DispId(1501)]
bool ViewerOpen();
[DispId(1502)]
bool ViewerMeasurement(bool IsCorrected, ref int[] PortList, string DataSetName, bool ReplaceExisting);
[DispId(1503)]
bool ViewerMeasurementStr(bool IsCorrected, string PortList, string DataSetName, bool ReplaceExisting);
[DispId(1504)]
bool ViewerMeasureAllPortsRaw(string DataSetName);
[DispId(1505)]
bool ViewerMeasureCorrected(string DataSetName);
[DispId(1506)]
bool ViewerLoadReport(string FullFileName);
[DispId(1507)]
bool ViewerListNames(out string[] DataItemNames);
[DispId(1508)]
bool ViewerGetDataItem(string DataItemName);
[DispId(1509)]
bool ViewerClose();
[DispId(1510)]
bool ViewerSave();
[DispId(1511)]
bool ViewerSaveAs(string NewReportName);
[DispId(1512)]
bool ViewerLoadData(string NewDataName);
[DispId(1513)]
bool ViewerSaveData(string FileName, bool Overwrite, int ComplexFormat);
[DispId(1514)]
bool ViewerGetStringDataItemValue(string DataItemName, out string Value);
[DispId(1515)]
bool ViewerGetIntDataItemValue(string DataItemName, out int Value);
[DispId(1516)]
bool ViewerGetBoolDataItemValue(string DataItemName, out bool Value);
[DispId(1517)]
bool ViewerGetRealDataItemValue(string DataItemName, out double Value);
[DispId(1518)]
bool ViewerSetStringDataItemValue(string DataItemName, string Value);
[DispId(1519)]
bool ViewerSetIntDataItemValue(string DataItemName, int Value);
[DispId(1520)]
bool ViewerSetBoolDataItemValue(string DataItemName, bool Value);
[DispId(1521)]
bool ViewerSetRealDataItemValue(string DataItemName, double Value);
[DispId(1522)]
bool ViewerGetComplexDataItemValue(string DataItemName, out double RealValue, out double ImaginaryValue);
[DispId(1523)]
bool ViewerSetComplexDataItemValue(string DataItemName, double RealValue, double ImaginaryValue);
[DispId(1601)]
void EventWindowShow();
[DispId(1602)]
void EventWindowAddMsg(string TheMsg);
[DispId(1603)]
void EventWindowHide();
[DispId(1604)]
void EventWindowAddMsg(string TheMsg, bool ForceShow);
}
这是包含 3 个新方法的新接口定义:
[ComVisible(true)]
[Guid("9DAF4501-4AF6-43FF-95EF-C421CB43F1B8")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[System.Reflection.Obfuscation(Feature = "renaming", Exclude = true, ApplyToMembers = true)]
public interface IWinCalClient5
{
[DispId(1501)]
bool ViewerOpen();
[DispId(1502)]
bool ViewerMeasurement(bool IsCorrected, ref int[] PortList, string DataSetName, bool ReplaceExisting);
[DispId(1503)]
bool ViewerMeasurementStr(bool IsCorrected, string PortList, string DataSetName, bool ReplaceExisting);
[DispId(1504)]
bool ViewerMeasureAllPortsRaw(string DataSetName);
[DispId(1505)]
bool ViewerMeasureCorrected(string DataSetName);
[DispId(1506)]
bool ViewerLoadReport(string FullFileName);
[DispId(1507)]
bool ViewerListNames(out string[] DataItemNames);
[DispId(1508)]
bool ViewerGetDataItem(string DataItemName);
[DispId(1509)]
bool ViewerClose();
[DispId(1510)]
bool ViewerSave();
[DispId(1511)]
bool ViewerSaveAs(string NewReportName);
[DispId(1512)]
bool ViewerLoadData(string NewDataName);
[DispId(1513)]
bool ViewerSaveData(string FileName, bool Overwrite, int ComplexFormat);
[DispId(1514)]
bool ViewerGetStringDataItemValue(string DataItemName, out string Value);
[DispId(1515)]
bool ViewerGetIntDataItemValue(string DataItemName, out int Value);
[DispId(1516)]
bool ViewerGetBoolDataItemValue(string DataItemName, out bool Value);
[DispId(1517)]
bool ViewerGetRealDataItemValue(string DataItemName, out double Value);
[DispId(1518)]
bool ViewerSetStringDataItemValue(string DataItemName, string Value);
[DispId(1519)]
bool ViewerSetIntDataItemValue(string DataItemName, int Value);
[DispId(1520)]
bool ViewerSetBoolDataItemValue(string DataItemName, bool Value);
[DispId(1521)]
bool ViewerSetRealDataItemValue(string DataItemName, double Value);
[DispId(1522)]
bool ViewerGetComplexDataItemValue(string DataItemName, out double RealValue, out double ImaginaryValue);
[DispId(1523)]
bool ViewerSetComplexDataItemValue(string DataItemName, double RealValue, double ImaginaryValue);
// New methods
[DispId(1524)]
bool ViewerSetOnDemandPostProcessing(bool Enable);
[DispId(1525)]
bool ViewerGetOnDemandPostProcessing(out bool IsEnabled);
[DispId(1526)]
bool ViewerPerformPostProcessing();
// End New Methods
[DispId(1601)]
void EventWindowShow();
[DispId(1602)]
void EventWindowAddMsg(string TheMsg);
[DispId(1603)]
void EventWindowHide();
[DispId(1604)]
void EventWindowAddMsg(string TheMsg, bool ForceShow);
}
我相当确定问题出在客户端 .NET COM 服务器中,因为我注意到了这些问题,因此仅取消了 COM 接口添加,并且客户端-服务器功能工作正常。
我尝试了不同的方法,似乎在我将新方法添加到具有更高范围的调度 ID 的接口定义末尾后,我没有遇到问题。不完全理解它,但它现在似乎正在工作。