Жизненный цикл консольного приложения.net - обход ошибки предварительной инициализации из BuildManager.GetReferencedAssemblies
Я пытаюсь перебрать ссылочные сборки в моем консольном приложении. Я делал это с помощью BuildManager.GetReferencedAssemblies в других проектах, но в моем консольном приложении я получаю исключение InvalidOperationException: этот метод не может быть вызван на этапе предварительной инициализации приложения.
Насколько мне известно, нет способа отложить выполнение в консольном приложении. Вы делаете это в static void Main, или не делаете это вообще... У кого-нибудь есть какие-либо предложения о том, как обойти это?
2 ответа
AppDomain.CurrentDomain.GetAssemblies() не совсем справились. Были некоторые сборки, которые не были включены, хотя на них ссылались. То, что я сделал, было это:
allAssemblies = (from name in Assembly.GetEntryAssembly().GetReferencedAssemblies()
select Assembly.Load(name)).ToList();
Это не вернуло столько сборок, сколько AppDomain.CurrentDomain.GetAssemblies(), но вернуло те, которые мне были нужны. Не уверен, почему было расхождение. Cerebrate, спасибо за ответ, хотя. Вы поставили меня на нужную мне трассу, и я проголосовал за ваш ответ.
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() делает то же самое.)