吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 433|回复: 10
上一主题 下一主题
收起左侧

[已解决] 如何使用反射来执行加载项dll里的按钮事件?

 关闭 [复制链接]
跳转到指定楼层
楼主
zhanglei1371 发表于 2023-12-13 13:24 回帖奖励
本帖最后由 zhanglei1371 于 2023-12-14 08:17 编辑

我用vs创建了一个vsto项目,添加了一个按钮和测试代码:
在Excel里也能正常点击,出现消息框。

我尝试用反射来执行这个按钮事件,再次新建一个新的vsto工程,代码如下:
Assembly a = Assembly.LoadFrom("E:\\TestVsto\\bin\\Debug\\TestVsto.dll");
        Type t = a.GetType("TestVsto.Ribbon1");
        MethodInfo m = t.GetMethod("Button1_Click", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
        if (m != null)
        { //已经成功执行到这里;
                m.Invoke(t, new[] {sender, e}); //此处出错;
        }
错误信息如下:

多次修改,始终都是这个错误提示。
不知该如何修改,望高人能解惑,谢谢!
-----------------------------------------------------
感谢@周易和@cdj68765 的帮助,问题已解决!

测试文件:https://wwi.lanzoup.com/iA3js1hqvz0b

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
610100 发表于 2023-12-13 13:33
本帖最后由 610100 于 2023-12-13 13:45 编辑

似乎是方法名搞错了?应该是button不是Button吧?另外参数改成null,null呢?
3#
周易 发表于 2023-12-13 14:00
本帖最后由 周易 于 2023-12-14 09:09 编辑

非静态方法需要实例才能调用。

Activator.CreateInstance(type);

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
610100 + 1 + 1 我很赞同!

查看全部评分

4#
 楼主| zhanglei1371 发表于 2023-12-13 20:23 |楼主
周易 发表于 2023-12-13 14:00
[md]非静态方法需要实例才能调用。

```cs

谢谢回答,不过测试未通过。
可以测试下我发的源码:Object obj = Activator.CreateInstance(type);这句就出错了:
错误信息:System.Reflection.TargetInvocationException:“调用的目标发生了异常。”
NullReferenceException: 未将对象引用设置到对象的实例。
5#
周易 发表于 2023-12-13 21:08
zhanglei1371 发表于 2023-12-13 20:23
谢谢回答,不过测试未通过。
可以测试下我发的源码:Object obj = Activator.CreateInstance(type);这句 ...
  1. 针对错误本身:创建实例需要自行处理构造函数参数。
  2. 如果目标程序集已经加载,那么GetField获取实例字段要比自行创建实例更符合现实场景。请明确一下需求。
6#
 楼主| zhanglei1371 发表于 2023-12-13 21:33 |楼主
周易 发表于 2023-12-13 21:08
[md]1. 针对错误本身:创建实例需要自行处理构造函数参数。
2. 如果目标程序集已经加载,那么`GetField` ...

哦,我的目的就是希望能通过反射来运行vsto加载项的Button1按钮,就是实例里的,您可以下载附件看看。
我现在有点怀疑,是否ribbon对象无法反射区执行按钮?
7#
周易 发表于 2023-12-13 22:01
zhanglei1371 发表于 2023-12-13 21:33
哦,我的目的就是希望能通过反射来运行vsto加载项的Button1按钮,就是实例里的,您可以下载附件看看。
...

要调用方法的话非常简单。但是这么做意义不明。如果不考虑参数的话伪代码如下。实现是肯定可以实现的但是为什么要实现?

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace ConsoleApp1
{
    class Program
    {
        public delegate void ButtonClickDelegate();

        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom(@"TestVsto.dll");
            Type type = assembly.GetType("TestVsto.Ribbon1");
            MethodInfo method = type.GetMethod("Button1_Click", BindingFlags.Instance | BindingFlags.NonPublic);
            RuntimeHelpers.PrepareMethod(method.MethodHandle);
            IntPtr ptr = method.MethodHandle.GetFunctionPointer();
            ButtonClickDelegate del = (ButtonClickDelegate)Marshal.GetDelegateForFunctionPointer(ptr, typeof(ButtonClickDelegate));
            del();
        }
    }
}

免费评分

参与人数 3吾爱币 +5 热心值 +3 收起 理由
ps122 + 1 + 1 谢谢@Thanks!
zhanglei1371 + 2 + 1 谢谢@Thanks!
cdj68765 + 2 + 1 我很赞同!

查看全部评分

8#
 楼主| zhanglei1371 发表于 2023-12-14 06:06 |楼主
本帖最后由 zhanglei1371 于 2023-12-14 08:15 编辑
周易 发表于 2023-12-13 22:01
[md]要调用方法的话非常简单。但是这么做意义不明。如果不考虑参数的话伪代码如下。实现是肯定可以实现的 ...

谢谢大佬回复,已成功实现!

点评

可以把最终的解决方案放出来以供参考吗。  发表于 2023-12-14 09:40
9#
ps122 发表于 2023-12-14 11:12
周易 发表于 2023-12-13 22:01
[md]要调用方法的话非常简单。但是这么做意义不明。如果不考虑参数的话伪代码如下。实现是肯定可以实现的 ...

大佬,如果考虑参数的话又该怎么处理?
10#
 楼主| zhanglei1371 发表于 2023-12-14 17:26 |楼主
周易 发表于 2023-12-13 21:08
[md]1. 针对错误本身:创建实例需要自行处理构造函数参数。
2. 如果目标程序集已经加载,那么`GetField` ...

感谢大佬的代码,已实现反射调用ribbon按钮事件。
测试发现win10完美通过。win7在调试时可能会存在问题,但是非调试模式就没问题了。
成品地址:
https://wwi.lanzoup.com/itd4P1hwd7zg
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止回复与主题无关非技术内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-16 19:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表