Ссылки на файлы - PullRequest
       16

Ссылки на файлы

2 голосов
/ 12 ноября 2010

Я делаю приложение, которое почти готово, но есть одна вещь, которая меня беспокоит. Для запуска приложения в каталоге должно быть около 12-13 файлов (некоторые файлы .dll, некоторые файлы .xml и т. Д.), И я хочу сделать приложение максимально компактным, то есть меньше файлов, чтобы идти с приложением. Итак, мой вопрос, как я могу это сделать? Можно ли все файлы включить в само приложение? Нужно ли, чтобы .dll находились в папке приложения или я могу ссылаться на них откуда-то еще? Я думал создать папку для всех этих файлов, но я не думаю, что мое приложение будет работать, если файл .dll не будет находиться в том же каталоге, что и приложение.

Ответы [ 4 ]

2 голосов
/ 12 ноября 2010

Вы можете обработать событие AppDomain.AssemblyResolve и вызвать Assembly.Load(path) для загрузки библиотек DLL из нестандартных папок.

Вы даже можете вызвать Assembly.Load(byte[]), чтобы загрузить DLL, встроенную в ваш EXE-файл, в качестве ресурса.

Обратите внимание, что JITter загрузит все типы, используемые методом, до того, как метод начнет выполняться (для компиляции метода).
Поэтому необходимо добавить обработчик событий перед использованием любых методов или типов в DLL, и метод, который добавляет обработчик, не может напрямую использовать DLL.

0 голосов
/ 12 ноября 2010

Похоже, вы могли бы использовать Встроенные ресурсы для части этого (все не-DLL). Вы можете использовать ILMerge для объединения ваших сборок после компиляции, хотя ILMerge имеет некоторые ограничения ...

0 голосов
/ 12 ноября 2010

Оформить этот пост

Microsoft предоставляет инструменты для этой цели

0 голосов
/ 12 ноября 2010

Как встраивать и получать доступ к ресурсам с помощью Visual C # выглядит именно то, что вам нужно.
[редактировать] Если вы хотите загрузить DLL, вы можете объединить вышеперечисленное с событием AppDomain.AssemblyResolve, которое упоминается SLaks следующим образом:

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 alt text

...