如何将位于不同文件夹中的C#dll引用到使用该DLL公开的接口的不同文件夹中的C#winforms exe [英] How to reference C# dll located in different folder to a C# winforms exe in different folder which uses Interface exposed by that dll

查看:39
本文介绍了如何将位于不同文件夹中的C#dll引用到使用该DLL公开的接口的不同文件夹中的C#winforms exe的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#Windows窗体,该窗体使用Utility.dll位于与EXE位置不同的文件夹中.Utility.dll包含一个类UtilityClass和一个接口ILoadString.当我不继承Form1.cs类中的ILoadString接口时,就可以通过Program.cs中的AppDomain.AssemblyResolve事件成功加载Utility.dll.

I have a C# windows forms that uses a Utility.dll located in different folder than that of the EXE location. Utility.dll contains a class UtilityClass and an interface ILoadString. When i do not inherit ILoadString interface in my Form1.cs class, i am successfully able to load the Utility.dll through AppDomain.AssemblyResolve Event in Program.cs.

当我尝试继承Form1.cs中的ILoadString接口时,会出现问题.当我尝试运行项目时,我从Visual Studio中收到FileNotFoundException,说无法加载文件或程序集'Utility,版本= 1.0.0.0,Culture =中性,PublicKeyToken =空"或其中的一个依赖项.系统找不到指定的文件."该控件甚至不会在Program.cs中变成静态void Main().我认为CLR试图在开始时就自己加载Utility.dll,因为我的Form1.cs继承了ILoadString.

The problem arises when i try to inherit ILoadString interface in Form1.cs. When i try to run the project, i get an FileNotFoundException from visual studio saying "Could not load file or assembly 'Utility, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified." The control does not even come to static void Main() in Program.cs. I think CLR is trying to load Utility.dll in the beginning itself as my Form1.cs is inheriting ILoadString.

注意:在添加引用" Utility.dll的本地副本中设置为"false".因此,Exe文件夹不包含此dll.

Note: In Add reference Utility.dll 's copy local is set to "false". so Exe folder do not contain this dll.

在这种情况下,如何从其他文件夹加载Utility.dll?任何帮助表示赞赏.

How do i load Utility.dll from other folder in this case? Any help appreciated.

谢谢.

我在下面粘贴我的代码.

I am pasting my code below.

using System.Reflection;

namespace SampleForm
{
    static class Program
    {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
    {
        Assembly MyAssembly, objExecutingAssemblies;
        string strTempAssmbPath = "";
        objExecutingAssemblies = Assembly.GetExecutingAssembly();
        AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
        foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
        {
            if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
            {
                strTempAssmbPath = "D:\\Ezhirko\\SampleForm\\bin\\Common\\" +
                    args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
            }
        }       
        MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
        return MyAssembly;
    }
}

我的Windows表单在这里....

My Windows form here....

using Utility;

namespace SampleForm
{
    public partial class Form1 : Form, ILoadString
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        string Name = string.Empty;
        UtilityClass obj = new UtilityClass();
        Name = obj.GetName();
        this.lblHello.Text = Name;
        ChangeName();
    }


    public void ChangeName()
    {
        this.lblHello.Text = "InterFace Called !";
    }
}

这是Utility.dll中的UtilityClass.cs

This is UtilityClass.cs from Utility.dll

namespace Utility
{
    public class UtilityClass
    {
        private string sName = string.Empty;

        public UtilityClass()
        {
            sName = "My Name";
        }

        public string GetName()
        {
            return sName;
        }
    }
}

这是Utility.dll的接口ILoadString.cs

This is interface ILoadString.cs from Utility.dll

namespace Utility
{
    public interface ILoadString
    {
        void ChangeName();
    }
}

推荐答案

您是否有特定原因将 copy local设置为"false" ?
它认为您最好将其设置为true.
另一个选择是使用构建事件将其复制到您的 bin 文件夹,或使用反射动态加载它.
但是,就像我说的那样,我认为最好将 copy local 设置为 true .

Is there a specific reason you have copy local is set to "false"?
It think you would be better off setting it to true.
Another option would be copying it to your bin folder using build events, or loading it dynamically using reflection.
But again, as I said, I think it would be better to simply set copy local to true.

编辑 :(根据Ezhirko的评论)

(as per Ezhirko's Comment)

您可以将加载程序集添加到 Program 的静态构造函数上或 SampleForm 中:

You can add loading the assemblies on the static constructor of Program or in SampleForm:

static class Program
{
    static Program()
    {
        //Loads assemblies. 
    }

   //the rest of your code...

}

这篇关于如何将位于不同文件夹中的C#dll引用到使用该DLL公开的接口的不同文件夹中的C#winforms exe的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆