我花了最近几天阅读了有关COM对象的C#反射,在代码中尝试了许多实验,并分析示例代码以尝试提高我的理解的所有内容,我现在不得不承认我不会我知道的,所以我要求社区提供帮助。
我需要能够访问和更新包装为System._COM
Object的后期绑定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;
}
期望已经找到并提供属性的对象能够更新相同的属性是不合理的吗?是否有一些我不知道的“替代更新”策略?
非常感谢您的帮助,
皮特。
更新:
响应Jon的请求,这里是OleView的片段: (我不得不使用图像,因为Oleview不会让我剪切和粘贴,抱歉......)
Jon,我认为你已经正确地确定了问题是使用setter方法。 DLL是用富士通COBOL编写的,为标识为PROPERTY的字段提供“隐藏”GET和SET。从C#或COBOL访问COM组件,它工作正常,但是,正如您所看到的,当我尝试使用反射访问SET时,它不起作用。因为我不熟悉使用反射,所以我怀疑我的语法是否正确,所以我试图使SET尽可能接近GET。我想我需要为COBOL生成自己的SET方法(对于每个PROPERTY),然后将我的“BindingFlags.SetProperty”更改为“BindingFlags.InvokeMember”。 (我在BindingFlags上完成了作业,发现如果指定“SetProperty”,它会自动隐含你提到的其他2个标志。)
我认为这一切的关键在于认识到问题出在Fujitsu * COM Class SET上,并且您需要经验丰富的眼光才能看到它。非常感谢。如果您在看到OLEView后有任何其他注释,或者可以建议任何替代方法以获得属性设置,我会非常感兴趣。 (我不期待必须为每个属性生成SETter方法;它有点蛮力......: - ))
再次感谢,
皮特。
答案 0 :(得分:0)