在过去的几天里,我阅读了我能找到的关于COM对象上的C#反射的所有内容,尝试了许多代码实验,并分析了示例代码以试图提高我的理解,现在我被迫承认我知道的还不够多,所以我向社区请求帮助。
我需要能够访问和更新包装为System._COM对象的后期绑定COM对象的属性。
我尝试了所有的标准引用,但都没有成功,我使用了IDispatch,但我不喜欢使用相关的指针,所以我希望我在正常的界面中遗漏了一些非常简单的东西。我在MSDN上找到了一些关于如何做我需要的东西的论文,但是所有的例子都是用C++写的,我不能理解。
如果有人能解释一下为什么以下简单的C#代码不能像预期的那样工作,那将是非常有帮助的:
try
{
// late binding:
// localCB is a COM object (System._COMObject) created by Activator.CreateInstance() from
// the ProgID of a registered COM .DLL.
//
// The original .DLL has a string PROPERTY called
// "TESTEXTERNAL1". localCB has an IDispatch Interface. The original COM .DLL has a separate Typelib,
// and, although I did not register the typelib separately, I can see from OLEView on the COM object
// that the GUID for the typelib is included in it.
// Here's the code that is puzzling me...
var vv = localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.GetProperty,
null, localCB, null);
string rt = vv.ToString();
// works exactly as expected and returns the value of TESTEXTERNAL1 - OK.
// now try and update the SAME PROPERTY, on the SAME COM object...
Parameters = new Object[1];
Parameters[0] = "Hello, World!";
localCB.GetType().InvokeMember("TESTEXTERNAL1", BindingFlags.SetProperty,
null, localCB, Parameters);
// throws an (inner) exception: HRESULT 0x8002003 DISP_E_MEMBERNOTFOUND !!!
}
catch (Exception xa)
{
string xam = xa.Message;
}期望已经找到并提供属性的对象能够更新相同的属性,这是不合理的吗?有没有什么我不知道的“替代更新”策略?
非常感谢你的帮助,
皮特。
更新:
为了回应乔恩的请求,这里有一些Oleview的片段:(我不得不使用图片,因为Oleview不允许我剪切和粘贴,对不起……)
OleView of the COM .DLL
OLEView typelib view
Jon,我想你已经正确地认识到问题出在setter方法上。DLL是用Fujitsu COBOL编写的,它为标识为属性的字段提供了一个“幕后”GET和SET。从C#或COBOL语言访问COM组件时,它工作得很好,但是,正如您所看到的,当我尝试使用反射访问它时,它就不能工作了。因为我不熟悉反射的使用,我怀疑我的语法是否正确,所以我试图使SET尽可能接近GET。我认为我需要在COBOL中生成自己的SET方法(针对每个属性),然后将我的"BindingFlags.SetProperty“更改为"BindingFlags.InvokeMember”。(我在BindingFlags上做了一些准备工作,发现如果指定"SetProperty“,它会自动暗示您提到的其他两个标志。)
我认为所有问题的关键在于认识到问题出在Fujitsu *COM Class SET上,这需要您有经验的眼睛才能看到。非常感谢。如果您在看完OLEView后有任何其他意见,或者可以建议任何替代方法来设置属性,我将非常感兴趣。(我并不希望为每个属性都生成SETter方法;这有点像蛮力……:-))
再次感谢,
皮特。
发布于 2016-08-30 07:32:06
汉斯是对的。问题出在setter方法上。我已经编写了代码来为每个属性生成一个setter,回到原始的COBOL COM组件中。它并不像我想象的那样乏味或丑陋(每个属性大约有7行COBOL代码),现在一切都很好。非常感谢社区,特别是Hans Passant的支持。
https://stackoverflow.com/questions/39189291
复制相似问题