C #: Как встроить DLL в файл ресурсов (без копирования DLL в программном каталоге) - PullRequest
0 голосов
/ 21 декабря 2010

У меня есть приложение C # (проект A), для которого требуется X.dll.Я добавил проект, который производит X.dll для A в качестве ссылки в Visual Studio.Я также добавил сборку выпуска X.dll в файл ресурсов в формате A в виде двоичного файла.Я сказал проекту A , а не , чтобы скопировать X.dll в выходной каталог.

Теперь я хочу загрузить A.exe, сказать «эй, я не могу найти этот файл», затем посмотреть в файле ресурсов и использовать Assembly.Load (byte []), чтобы вернуть X.dll.У меня есть код, который перемагирует DLL обратно, однако этот код никогда не вызывается.

В настоящее время у меня простой проект, я просто пытаюсь заставить его работать.Это скомпилировано ОК.Когда я запускаю его, я получаю FileNotFoundException для X.dll.

У меня есть:

[STAThread]
static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

Но точка останова в * CurrentDomain_AssemblyResolve * никогда не попадает в цель.Я немедленно получаю FileNotFoundException.Неужели есть что-то, чего мне не хватает?

1 Ответ

10 голосов
/ 21 декабря 2010

Этот вопрос, кажется, очень похож на то, что вы пытаетесь достичь, и он работал для спрашивающего.

Объединить .dll в C # Assembly?

Вы делаете что-то по-другому?В частности, если вы нацелены на более старую версию .NET Framework, возможно, это подсказка для понимания того, почему ваше приложение ведет себя по-другому.

В другом направлении используйте такой инструмент, как Fusion Log Viewer , чтобы проанализировать, что происходило, когда вы пытались загрузить сборку.Это может дать еще несколько советов.Если вам удастся получить информацию журнала, размещение ее в вопросе может помочь кому-то это выяснить.

РЕДАКТИРОВАТЬ: Другое объяснение, после вашего комментария.

Ну, теперьЯ думаю, я знаю, в чем проблема.

В вашем методе Main вы ссылаетесь на тип в другой DLL.Но вы делаете это в статическом коде, то есть вы явно используете тип в коде (в отличие от динамической загрузки его по имени).

Почему это проблема?CLR пытается загрузить вашу сборку , чтобы сам JIT Main.

Ваш FileNotFoundException был брошен во время компиляции Main.Main даже не запустился, и, следовательно, ваш обработчик событий не был зарегистрирован.

Простой способ проверить, прав ли я, это изменить код на что-то вроде этого:

static public void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += MyEventHandler;
    MyMain();
}

// The CLR will actually try to load your assembly before even starting the execution
// of this method. It needs the assembly in order to JIT the method because it has to 
// know the Thing type.
static public void MyMain()
{
    using(var thing = new Thing())
    {
         // ...
    }
}

Важным отличием является то, что Main не зависит от другой сборки, поэтому не будет проблем с JIT и его запуском.

К тому времени, когда MyMain будет JIT'ed,ваш обработчик событий уже установлен, поэтому вы можете вручную загрузить сборку.

Кстати, чтобы избежать другой возможной подобной ошибки, убедитесь, что класс, в котором определен Main, не имеет никакого поляс типом из другой сборки, поскольку в этом случае CLR также попытается загрузить сборку до запуска Main, чтобы скомпилировать ее.

...