2

我很好奇是否有人知道监视.Net应用程序运行时信息的方法(调用什么方法等等)

并注入额外的代码以从单独的运行进程在某些方法上运行。

说我有两个应用程序:

为简单起见,app1.exe 可能是

class Program
{
    static void Main(string[] args)
    {
      while(true){
        Somefunc();
      }
    }

    static void Somefunc()
    {
       Console.WriteLine("Hello World");
    }
} 

我有第二个应用程序,我希望能够检测应用程序 1 的 Somefunc() 何时运行并注入自己的代码,

 class Program
 {
     static void Main(string[] args)
     {
       while(true){
          if(App1.SomeFuncIsCalled)
             InjectCode();
         }
     }

    static void InjectCode()
    {
       App1.Console.WriteLine("Hello World Injected");
    }
 } 

所以结果将是应用程序一会显示

Hello World
Hello World Injected 

我知道它不会这么简单(从长远来看),但我不知道它是否可能以及它是否可以从哪里开始。

有什么建议么 ?

我在 java 中看到过类似的操作,但在 c# 中从未见过。

编辑:澄清一下,它的用途是将插件系统添加到我无法访问其源代码的基于 .Net 的游戏中。

4

9 回答 9

4

可能值得研究 Mono.Cecil 进行代码注入。它不会按照您在问题中描述的方式在线工作,但我相信它可以离线完成您想要的工作(能够找到给定的方法,向其中添加代码,并写出修改后的程序集)。 http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx

于 2009-07-22T17:46:49.133 回答
2

好吧,在没有 App1 许可的情况下这样做是很困难的。但是假设您确实想在 App1 中创建一个扩展点,那么使用某种可扩展性框架执行您所建议的操作相对简单。我建议:

由于我对 MEF 更熟悉,因此它的外观如下:

class Program
{
    [ImportMany("AddinContractName", typeof(IRunMe))]
    public IEnumerable<IRunMe> ThingsToRun { get; set; }

    void SomeFunc()
    {
        foreach(IRunMe thing in ThingsToRun)
        {
            thing.Run();
        }
        /* do whatever else ... */
    }
}
于 2009-07-22T16:45:14.140 回答
2

您需要使用Profiling API使第二个程序配置文件成为第一个程序配置文件。然后可以通知您任何方法调用。

于 2009-07-22T16:40:05.073 回答
1

通过您在评论中所做的澄清,在我看来,您最好使用 ildasm 和 ilasm 拆卸和重新组装。

于 2009-07-22T16:39:56.307 回答
1

另一个想法是编写一个应用程序来更改您要监视的 exe。它会做类似于分析工具在“检测”您的应用程序时所做的事情。基本上,您使用反射来浏览应用程序,然后使用 .NET 的 Emit 功能重新创建 exe(具有不同的文件名)并同时插入您的代码。

当然,如果应用程序试图安全地做事,这个新版本可能不允许与它的其他程序集通信。

于 2009-07-22T16:52:42.690 回答
0

根据作者如何打包/构建他的应用程序,您也许可以从您自己的项目中添加对他的 EXE 文件的引用,并从您自己的应用程序中执行他的代码。如果可行,那么只需在此时使用反射来获取可以插入的有用接口/事件/等(如果它们被标记为私有......否则直接使用它们:)。您可以添加对使用调试或发布版本的默认设置构建的任何 EXE 的引用,并像使用 DLL 一样使用它。

如果这不起作用,您还可以使用高级技巧来交换方法调用等,但这超出了本回复的范围......我建议先尝试参考。

于 2009-07-22T17:45:17.717 回答
0

使用Mono Cecil在程序集中注入代码

于 2009-07-22T18:42:25.700 回答
0

您可以尝试CInject将您的 C# 或 VB.NET 代码注入程序集

于 2012-09-03T05:16:17.837 回答
0

将代码注入正在运行的应用程序是可能的。 是一个工作示例,但涉及注入到非托管 dll 中。

于 2009-07-22T17:52:42.697 回答