延迟加载,它被放置在文件系统程序后一个DLL已经启动文件系统、加载、程序、DLL

2023-09-06 15:08:05 作者:低调小伙最迷人

我建立一个自动化线束使用C#,我试图做到以下几点:

I am building an automation harness using C# and am trying to do the following:

引导线束 在安装可执行文件 使用一对夫妇的DLL的可执行文件规定了建立到该exe文件连接到基础设施的连接(大型,复杂的软件系统)

这是我需要使用的DLL文件是一些静态类执行自己的引导的过程可以连接到该服务器在测试环境中休息。我曾尝试是创造,看起来像这样的连接类:

The DLLs that I need to use are a few static classes that perform their own 'bootstrap' process to get connected to the rest of the servers in the test environment. What I have tried is creating a connection class that looks like this:

using CompanyName.Framework;

namespace TestNamespace{
    public class ProductConnectorClass{
        // Initialize a connection to the product and do stuff
        public ProductConnectorClass(){
            var connection = CompanyName.Framework.Initialize(...);

            // Do stuff with the connection
            connection.RunStuff();
        }
    }
}

这是包含在的DLL CompanyName.Framework 的命名空间是无法访问的,当第一次启动测试框架。它通过code的,看起来像这样lomething另一个类复制:

The DLL that contains the CompanyName.Framework namespace is not accessible when the test framework is first started. It is copied via code from another class that looks lomething like this:

namespace TestNamespace{
    public class TestRunnerClass{
        public TestRunnerClass(){
            // pseudo code here, so you get the idea:
            CopyMsiToHost(msiRemotePath, msiLocalPath);
            InstallMsi(msiLocalPath);
            CopyDllsToTestHarnessDir();
            ProductConnectorClass pcc = new ProductConnectorClass();
        }
    }
}

这是当code打在 ProductConnectorClass PCC =新ProductConnectorClass(); ,我得到一个异常行:

It is when the code hits the ProductConnectorClass pcc = new ProductConnectorClass(); line that I get an exception:

FileNotFoundException was unhandled
Could not load file or assembly 'CompanyName.Framework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXXXXXXX' or one of its dependencies. The system cannot find the file specified.

这让我为难,因为我已经设置的具体的版本:在我的测试项目假标签上的DLL,我认为.NET松散地加载的DLL(在我的脑海,这意味着搜索的假设下运行并将它们加载在他们需要的时间)。此时我正在寻找一种简单的方式来获得运行.NET程序找到所需的DLL已放置后程开始运行。

This puzzles me since I have set Specific Version: False on the DLL in my test project and I am operating under the assumption that .NET Lazy-loads DLLs (in my mind that means search for and load them at the time they are needed). At this point I am looking for a simple way to get a running .NET program to find a needed DLL that has been placed after the process started running.

注意1:如果我重新启动的DLL程序后就已经到位,它加载的罚款。它看起来像它是在启动时,仍然让我为难的DLL只扫描。

Note 1: If I restart the process after the DLL is already in place, it loads fine. It looks like it is only scanning for DLLs on startup, which still puzzles me.

注意2:此 SO回答给了我如何的DLL加载一些信息,但没有按'T完全回答我的问题。该概要是,如果.NET试图加载DLL和失败,它不会尝试再次加载它。在我来说,我不认为一个负载的尝试已经取得了自该DLL被引用没有实例化尚未类的DLL。

Note 2: This SO answer gives me some information about how DLLs are loaded, but doesn't fully answer my question. The synopsis is that if .NET has tried to load the DLL and it fails that it won't try to load it again. In my case I don't expect that a load attempt has been made on the DLL since the class where the DLL is referenced has not been instantiated yet.

推荐答案

从实验的测试项目中,我已经完成,看来我需要为了得到这个工作,执行我的code模块化。在任何情况下,我能够引用一个当前不存在一个dll,开始我的程序,然后下拉DLL。

From experiments in test projects that I have performed, it appears that I need to perform modularization of my code in order to get this to work. In no case am I able to reference a dll that does not currently exist, start my program then drop down the DLL.

下面是我的步骤来解决:

Here are my steps to a solution:

在重构我共同的类和接口,以自己的DLL项目在我的自动化解决方案 创建另一个DLL项目('TestLogic)在我的解决方案,它使用的DLL我放下了程序启动后 当我需要使用已规定的DLL程序启动后,我使用反射来加载DLL TestLogic和执行测试

有关参考我做了谷歌搜索C#后期加载DLL,发现这个MSDN社会帖子了一些有益的建议。下面是一个复制/粘贴/修改从该线程最有帮助的回复:

For reference I did a google search for 'C# late load dll' and found this msdn social post with some helpful advice. Here is a copy/paste/modify of the most helpful reply from that thread:

将所有的code,引用的安装后测试框架开始一个完全独立的组件的DLL。我们将这个TestLogicAssembly。 创建一个新的组件和定义一个接口。我们将这个TestInterfaceAssembly。 参考TestInterfaceAssembly在两个主DLL和你的TestLogicAssembly。 创建一个实现在TestInterfaceAssembly创建的接口的类的TestLogicAssembly。 请不要TestLogicAssembly从主应用程序中引用。 在运行时,检查是否实际安装的放下了测试框架的安装步骤的一部分的DLL文件。如果是这样,使用的Assembly.Load加载TestLogicAssembly,然后找到一个实现在数2.使用Activator.CreateInstance定义创建该类型的实例接口类型,并转换为你创建的接口。