Сборка не может найти ссылочную сборку при составлении в память с помощью CodedomProvider

StackOverflow https://stackoverflow.com/questions/6804147

Вопрос

Я пытаюсь скомпилировать код в память во время выполнения с помощью CodedomProvider.

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

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

(Исключение)
«Невозможно загрузить один или несколько запрашиваемых типов. Получить свойство LoadErexCeptions для получения дополнительной информации».

(LoaderException)
"{" Не удалось загрузить файл или сборку 'Dynamo.jiss.task, версия = 1.0.0.0, культура = нейтральная, publickeytoken = null' или одна из ее зависимостей. Система не может найти указанный файл. ":" Dynamo.jiss.task, версия = 1.0.0.0, культура = нейтральная, publickeytoken = null "}"

Я пытался ссылаться на сборку из разных мест, используя абсолютный путь.

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

У кого-нибудь есть идея, почему компиляция в память и ссылка на сборку не работает в надстройке?

Есть ли некоторые ограничения в приложении, о котором он работает, или о чем -то, о чем я должен знать? (Мое лучшее предположение в настоящее время)

Должен ли это быть в определенной папке? ссылка на относительный путь? Настройки безопасности? нужно подписано? Любые идеи?


То, что я пытаюсь достичь, - это способ поместить файлы с определенным расширением в проекте и позволить Addin автоматически скомпилировать его и, если он реализует интерфейс itask (от внешней сборки), он вызовет метод setup (), который делает его Возможно, для кода зацепиться в события Visual Studio и выполнять задачи/сценарии, прослушивая различные события. Таким образом, я могу легко выполнить текстовые шаблоны, если изменяется другой файл, или объединять и министерство файлов на разных событиях (сохраненный документ, сборка и т. Д.).

Существует ли что -то подобное (чтобы освободить меня от боли)? :)

Это было полезно?

Решение

Скорее всего, это происходит потому, что вы говорите Codedom генерировать сборку в памяти (которая действительно является ложью, поскольку он временно генерирует диск, загружает его, затем удаляет файл). Дело в том, что каталог компиляции для сборки Codedom не тот, который вы используете для его компиляции. То есть, если вы работаете в Bin Debug, сборка Codedom генерируется до %temp %.

Вы можете решить это одним из двух способов, которые я могу придумать:

  1. Скомпилируйте сборку Codedom по тому же пути, что и ваша выполняющая сборка.

    myCodeProvider.GenerateInMemory = false; // may not be necessary...haven't tried this in a while
    myCodeProvider.OutputAssembly = string.Format(@"{0}\{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location, "mydll.dll");
    
  2. Обработайте событие AssemblyResolve и предоставьте сборку Codedom обращаемую ссылку на сборку.

    AppDomain.CurrentDomain.AssemblyResolve += OnCurrentDomainAssemblyResolve
    
    private static Assembly OnCurrentDomainAssemblyResolve(object sender, ResolveEventArgs args)
    {
                    // this is absurdly expensive...don't do this more than once, or load the assembly file in a more efficient way
                    // also, if the code you're using to compile the CodeDom assembly doesn't/hasn't used the referenced assembly yet, this won't work
                    // and you should use Assembly.Load(...)
                    foreach (Assembly @assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        if (@assembly.FullName.Equals(args.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            return @assembly;
                        }
                    }
    }
    
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top