【问题标题】:PropertyInfo.GetProperty returns null when it shouldn'tPropertyInfo.GetProperty 在不应该返回 null 时
【发布时间】:2017-01-03 05:36:19
【问题描述】:

我正在尝试获取 WPF WebBrowser 对象的私有属性的值。我可以在调试器中看到它有一个非空值。

PropertyInfo activeXProp = Browser.GetType().GetProperty("ActiveXInstance", BindingFlags.Instance | BindingFlags.NonPublic);
object activeX = activeXProp.GetValue(Browser, null); // here I get null for the activeX value
activeX.GetType().GetProperty("Silent").SetValue(activeX, true); // and here it crashes for calling a method on a null reference...

我的猜测是我没有以正确的方式使用反射,但在这种情况下正确的方法是什么? 该项目是在 .NET 4.6.1 和 Windows 10 上运行的 WPF 项目。 我尝试使用管理员权限运行它(将清单文件添加到项目中),但没有任何区别。

【问题讨论】:

  • 你确定activeXnull 吗?它不会给我 null。
  • 感谢您试一试。不幸的是,它确实给了我一个空值。如果您想查看,这里是完整的项目:github.com/zskolbay/WpfBrowserTest
  • 我在 github 上测试了你的代码,activeX 不为空。只有下一行会引发异常。
  • 返回null的是activeX.GetType().GetProperty("Silent")
  • 如果真的activeX为null,则在没有创建窗口并且您尝试访问它时为null。

标签: c# wpf reflection properties webbrowser-control


【解决方案1】:

activeX.GetType()返回的类型是System.__ComObject,不支持这种反射。但是,有两个简单的解决方案。

使用dynamic

dynamic activeX = activeXProp.GetValue(Browser, null);
activeX.Silent = true;

dynamic 支持所有类型的 COM 反射,由 IDispatch COM 接口提供(由所有 ActiveX 元素实现)。

只是反思

对您的代码稍作改动与上面的代码相同:

object activeX = activeXProp.GetValue(Browser, null);
activeX.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, activeX, new object[]{true});

这两种方法在对象上调用相同的东西,但我猜第一种方法会随着时间的推移更快,因为调用站点的缓存。仅当您由于某种原因无法使用dynamic 时才使用第二个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-27
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多