жизненный цикл консольного приложения .net - обход ошибки предварительной инициализации из BuildManager.GetReferencedAssemblies - PullRequest
1 голос
/ 06 августа 2010

Я пытаюсь перебрать ссылки на сборки в моем консольном приложении. Я делал это с BuildManager.GetReferencedAssemblies в других проектах, но в моем консольном приложении я получаю исключение InvalidOperationException: этот метод не может быть вызван на этапе предварительной инициализации приложения.

Насколько мне известно, в консольном приложении нет способа отложить выполнение. Вы делаете это в static void Main, или вы не делаете это вообще ... У кого-нибудь есть какие-либо предложения о том, как обойти это?

Ответы [ 2 ]

6 голосов
/ 06 августа 2010

BuildManager.GetReferencedAssemblies () из пространства имен System.Web.Compilation?

Насколько я знаю, это специфично для ASP.NET, поэтому оно не будет работать в вашем консольном приложении. (Или в приложении Windows, если на то пошло.)

Итак, первый подвопрос заключается в том, нужна ли вам специальная функциональность BuildManager.GetReferencedAssemblies, а именно, что он просматривает и находит - в дополнение к специальным способам ASP.NET ссылок на сборки - не только все сборки на которые ссылается ваше приложение, но на все сборки, на которые они ссылаются и т. д. и т. д.

(См. Разница между AppDomain.GetAssemblies и BuildManager.GetReferencedAssemblies )

Если то, что вы пытаетесь сделать, будет работать нормально только со списком сборок, на которые непосредственно ссылаются ваши .exe-файлы (плюс любые, которые были загружены с тех пор динамически, либо явно вашим кодом, либо неявно, вызывая ссылочную сборку который сам ссылается на них), самый простой способ это просто:

// Get all currently loaded assemblies.
var assemblies = AppDomain.CurrentDomain.GetAssemblies();

Если нет, то вот где вам будет сложно, потому что в .NET нет простого способа получить список всех сборок, на которые приложение ссылается косвенно. Теоретически вы можете написать код для рекурсивного вызова Assembly.GetReferencedAssemblies () для Assembly.GetEntryAssembly (), а затем для всех результатов, которые вы получите из этого, а затем для всех результатов, которые вы получите из этих - отбрасывание дубликатов, чтобы вы не делали не заканчивается бесконечным циклом - и в конечном итоге вы получите все сборки, на которые прямо или косвенно статически ссылается ваше приложение.

(Если вы когда-нибудь будете ссылаться на сборки динамически, например, с помощью AppDomain.Load () или чего-то подобного, они не будут перечислены в них. Но тогда я не верю, что BuildManager.GetReferencedAssemblies () тоже.)

0 голосов
/ 12 августа 2010

AppDomain.CurrentDomain.GetAssemblies () не совсем справились.Были некоторые сборки, которые не были включены, хотя на них ссылались.Я сделал следующее:

allAssemblies = (from name in Assembly.GetEntryAssembly().GetReferencedAssemblies()
        select Assembly.Load(name)).ToList();

Это не вернуло столько сборок, сколько AppDomain.CurrentDomain.GetAssemblies (), но вернуло те, которые мне нужныНе уверен, почему было расхождение.Cerebrate, спасибо за ответ, хотя.Вы поставили меня на нужную мне трассу, и я проголосовал за ваш ответ.

...