引用文件

发布于 2024-10-01 17:27:02 字数 251 浏览 2 评论 0原文

我正在制作一个即将完成的应用程序,但有一件事困扰着我。文件夹目录中必须有大约 12-13 个文件(一些 .dll、一些 .xml 文件等)才能运行应用程序,我想让我的应用程序尽可能紧凑,这意味着我想要应用程序附带的文件更少。所以我的问题是,我该怎么做?所有文件都可以包含在应用程序本身中吗? .dll 是否必须位于应用程序文件夹中,或者我可以从其他地方引用它们吗?我正在考虑为所有这些文件创建一个文件夹,但我认为如果 .dll 文件未放置在与应用程序相同的目录中,我的应用程序将不会运行。

I am making an application which is almost done but there is one thing that is bugging me. There are about 12-13 files that must be in the directory of the folder (some .dlls, some .xml files etc.) for the application to run, and I want to make my application as compact as possible, meaning I want as fewer files to go with the application. So my question is, how can I do this? Can all the files be included in the application itself? Is it necessary for the .dlls to be in the application folder or can I reference them from somewhere else? I was thinking to make a folder for all those files but I don't think my application will run if a .dll file isn't placed in the same directory as the application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青萝楚歌 2024-10-08 17:27:02

您可以处理 AppDomain.AssemblyResolve 事件 并调用 Assembly.Load(path) 从非标准文件夹加载 DLL。

您甚至可以调用 Assembly.Load(byte[]) 来加载作为资源嵌入到 EXE 中的 DLL。

请注意,JITter 将在方法开始执行之前加载该方法使用的所有类型(以便编译该方法)。
因此,在使用DLL中的任何方法或类型之前必须添加事件处理程序,并且添加处理程序的方法不能直接使用DLL。

You can handle the AppDomain.AssemblyResolve event and call Assembly.Load(path) to load DLLs from non-standard folders.

You can even call Assembly.Load(byte[]) to load a DLL that is embedded in your EXE as a resource.

Note that the JITter will load all types used by a method before the method starts executing (in order to compile the method).
Therefore, you must add the event handler before using any methods or types in the DLLs, and the method that adds the handler cannot directly use the DLLs.

森罗 2024-10-08 17:27:02

如何使用 Visual C# 嵌入和访问资源看起来正是您所需要的。
[编辑]
如果您想加载 DLL,您可以将上述内容与 SLaks 提到的 AppDomain.AssemblyResolve 事件结合起来,如下所示:

using System.IO;
using System.Reflection;

namespace ConsoleApplication3
{
  class Program
  {
    static void Main(string[] args)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += 
                new ResolveEventHandler(MyResolveEventHandler);
        var myWrappedClass1 = 
            currentDomain.CreateInstance(
                    "ConsoleApplication3.ClassLibrary1.dll", 
                    "ClassLibrary1.Class1");
        var myClass1 = myWrappedClass1.Unwrap();
        Console.WriteLine(myClass1.GetType().InvokeMember(
                    "Add", 
                    BindingFlags.Default | BindingFlags.InvokeMethod, 
                    null,
                    myClass1, 
                    new object[] { 1, 1 }));
        Console.ReadLine();
    }

    private static Assembly MyResolveEventHandler(
            object sender, ResolveEventArgs args)
    {
        Assembly currentAssembly=null;
        Stream dllStream;
        try
        {
            currentAssembly = Assembly.GetExecutingAssembly();
            dllStream = 
                    currentAssembly.GetManifestResourceStream(args.Name);
            var length = (int)dllStream.Length;
            var dllByteArray = new byte[length];
            int bytesRead;
            int offset = 0;
            while ((bytesRead = dllStream.Read(
                                    dllByteArray, 
                                    offset, 
                                    dllByteArray.Length - offset)) 
                    > 0)
                offset += bytesRead;
            return Assembly.Load(dllByteArray);
        }
        catch
        {
            Console.WriteLine("Error accessing resources!");
        }
        return null;
    }
  }
}

其中 Class1 是一个类库,仅包含:

namespace ClassLibrary1
{
    public class Class1
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

DLL 是作为嵌入资源添加到文件中:

alt text
替代文本

How to embed and access resources by using Visual C# looks like just what you need.
[edit]
If you want to load DLLs, you can combine the above with the AppDomain.AssemblyResolve event SLaks mentions like this:

using System.IO;
using System.Reflection;

namespace ConsoleApplication3
{
  class Program
  {
    static void Main(string[] args)
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.AssemblyResolve += 
                new ResolveEventHandler(MyResolveEventHandler);
        var myWrappedClass1 = 
            currentDomain.CreateInstance(
                    "ConsoleApplication3.ClassLibrary1.dll", 
                    "ClassLibrary1.Class1");
        var myClass1 = myWrappedClass1.Unwrap();
        Console.WriteLine(myClass1.GetType().InvokeMember(
                    "Add", 
                    BindingFlags.Default | BindingFlags.InvokeMethod, 
                    null,
                    myClass1, 
                    new object[] { 1, 1 }));
        Console.ReadLine();
    }

    private static Assembly MyResolveEventHandler(
            object sender, ResolveEventArgs args)
    {
        Assembly currentAssembly=null;
        Stream dllStream;
        try
        {
            currentAssembly = Assembly.GetExecutingAssembly();
            dllStream = 
                    currentAssembly.GetManifestResourceStream(args.Name);
            var length = (int)dllStream.Length;
            var dllByteArray = new byte[length];
            int bytesRead;
            int offset = 0;
            while ((bytesRead = dllStream.Read(
                                    dllByteArray, 
                                    offset, 
                                    dllByteArray.Length - offset)) 
                    > 0)
                offset += bytesRead;
            return Assembly.Load(dllByteArray);
        }
        catch
        {
            Console.WriteLine("Error accessing resources!");
        }
        return null;
    }
  }
}

where Class1 is a class library containing just:

namespace ClassLibrary1
{
    public class Class1
    {
        public int Add(int x, int y)
        {
            return x + y;
        }
    }
}

and the DLL is added as an Embedded Resource to the file:

alt text
alt text

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文