在过去的几天里阅读了我能找到的关于 COM 对象的 C# 反射的所有内容,在代码中尝试了许多实验,并分析了示例代码以试图提高我的理解,我现在不得不承认我只是不够了解,所以我请求社区的帮助。
我需要能够访问和更新包装为System._COM
Object 的后期绑定 COM 对象的属性。
我尝试了所有标准的反射都没有成功,我查看了 using 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 不允许我剪切和粘贴,抱歉......)
乔恩,我认为您已经正确地确定问题出在 setter 方法上。DLL 是用 Fujitsu 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 方法;它带有蛮力的味道...... :-))
再次感谢,
皮特。