是否可以通过 app.config 将 .NET dll“注入”到另一个 .NET 应用程序中?

Posted

技术标签:

【中文标题】是否可以通过 app.config 将 .NET dll“注入”到另一个 .NET 应用程序中?【英文标题】:Is it possible to "inject" a .NET dll into another .NET application, by way of app.config perhaps? 【发布时间】:2011-01-12 14:52:30 【问题描述】:

我在 C# 中创建了一个 .NET 类库,用于初始化一些日志记录,发送到外部工具。该库完全独立于任何应用程序,但为了对其进行初始化,我需要对其进行至少一个方法调用。

有没有办法让我将一些东西放入 app.config 中,以自动加载该 dll,并在其中调用一些东西?我可以更改内容以适应任何内容,我不需要支持任何自己的类名或方法名或诸如此类的东西。

注意,我需要在不对相关应用程序进行任何更改的情况下完成此操作,除非更改 app.config 文件。

这可能吗?如果是这样,我应该看什么?

【问题讨论】:

叫我疯了,但是你的日志工具为什么不在某个地方的静态初始化块中初始化呢? 关键是将这段代码注入到一个不是为调用它而构建的应用程序中。静态构造函数仅在使用类中的代码之前之前调用,如果您实际上不使用该类,则无法保证它会被调用。由于应用程序根本没有使用我的注入 dll,因此不会调用静态构造函数。 【参考方案1】:

这可能会被认为是一种 hack,但是如果您将继承 ConfigurationSection 的内容放入您的 dll 中,并将该配置部分添加到您的 app.config,这将允许您在配置部分的构造函数中执行代码并因此几乎可以做你想做的事。当然,它只会在应用程序启动时被调用一次,但如果我理解你是正确的,那就足够了。

【讨论】:

我会试试这个,听起来很有希望。 黑客很好。这个 dll 挂钩到 Debug and Trace 的监听器系统,捕获所有日志消息,并启动后台线程来监控内存和 cpu 使用情况,所有内容都发送到外部记录器应用程序。这是一个取证调试工具,我需要用于我无法更改的应用程序。 好吧,我不明白为什么那行不通。祝你好运,让我知道结果如何。 @Lasse:如果它是一个取证调试工具,您是否考虑过使用您可用的 CLR 分析器/调试器挂钩? 不,我没有,这将如何工作,是否易于设置?我现在正在尝试配置部分提示,但它似乎根本没有加载部分类。在我改变我的问题或发表其他评论之前,我会再调查一下。 @Brian,你能在这里留下一个答案,并为我提供一些相关信息吗?【参考方案2】:

这让我有一段时间不知道该怎么做。我最初认为可以通过创建一个自定义 WebProxy 来配置日志记录,并使用 defaultProxy 配置元素将其加载到主应用程序中来实现。然而,这与其他配置建议存在相同的问题,即代码仅在需要时运行(在这种情况下,当使用 HTTP 请求时) - 因此需要更改原始应用程序。

我通过反转方法实现了它。您可以编写一个应用程序的存根来配置日志记录,然后启动原始应用程序,而不是尝试让原始应用程序配置日志记录。

举个例子:

我有一个名为 Forms.exe 的 WinForms 应用程序,其入口点定义为:

[STAThread]
internal static void Main()

    Application.Run(new MainForm());

在我的存根应用程序(我有一个控制台应用程序)中,我配置了日志记录,然后加载并运行Forms.exe

internal static void Main()

    ConfigureLogging()
    Assembly app = Assembly.LoadFrom(@".\Forms.exe");
    app.EntryPoint.Invoke(null, null);

这使用反射将另一个应用程序加载到配置日志记录的应用程序中。

注意事项:

其他应用程序必须是 .Net 应用程序才能以这种方式加载 您可能需要使用 Reflector 来检查其他应用程序以计算出正确的参数以传递给入口点(即,如果它需要 string[] args,您可能需要传入一个空的 string[] 而不是null 作为参数) 原始应用程序的控制台窗口会在其他应用程序运行时挂起(这可能不是问题,但如果有问题,您可以尝试使用 FreeConsole 隐藏它)

【讨论】:

啊,我还没有想到这种方法,是的,这听起来更有希望。 这显然是唯一可行的选择。我不知道用于确定何时加载与 ConfigurationSection 相关的类的确切规则,但似乎只有在我接触过该配置时才会加载它们。在我的情况下,在一般情况下,应用程序不会读取此配置,因此这不起作用。但是,存根应用程序项目就像一个魅力。【参考方案3】:

Snoop 使用一些 C++ 巫术来做到这一点。幸运的是,源代码可用 - 查看名为“ManagedInjector”的项目

【讨论】:

【参考方案4】:

是的,你可以使用反射来加载程序集的内容

【讨论】:

重点是完全避免更改目标应用程序代码。如果我想走那条路,我可以很容易地添加反射或诸如此类的东西。 @Lasse: 嗯...如果目标应用程序不是为处理这个问题而构建的,并且您不想更新它,那么您就会被卡住。如果它有那么神奇,这将是一个安全问题。 是的,这也是我的假设,因为我无法让配置部分的答案正常工作,我猜我毕竟需要在应用程序中添加一些代码。也许@Brian 上面评论的调试钩子可以代替。

以上是关于是否可以通过 app.config 将 .NET dll“注入”到另一个 .NET 应用程序中?的主要内容,如果未能解决你的问题,请参考以下文章

app.config 全球化

类库的 app.config

c# app.config是否只用在程序运行的开始阶段,在程序运行过程中能不能进行保存和更新?

.net中 App.config的作用是啥?

VB.Net 如何将 app.config 文件移动到自定义位置

为 app.config 内置 .NET 键/值对 configSection 处理程序