.net 控制台应用程序生命周期 - 解决 BuildManager.GetReferencedAssemblies 的预启动初始化错误

发布于 2024-09-12 17:42:49 字数 239 浏览 6 评论 0原文

我正在尝试迭代控制台应用程序中引用的程序集。我一直在其他项目中使用 BuildManager.GetReferencedAssemblies 执行此操作,但在我的控制台应用程序中,我收到 InvalidOperationException: 在应用程序的预启动初始化阶段无法调用此方法。

据我所知,没有办法在控制台应用程序中延迟执行。您在 static void Main 中执行此操作,或者根本不执行此操作...有人对如何解决此问题有任何建议吗?

I'm trying to iterate through the referenced assemblies in my console app. I have been doing this with BuildManager.GetReferencedAssemblies in other projects, but in my console application, I get an InvalidOperationException: This method cannot be called during the application's pre-start initialization stage.

To my knowledge, there isn't a way to delay execution in a console app. You do it in static void Main, or you don't do it at all... Anyone have any suggestions on how to get around this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤还要旧人安 2024-09-19 17:42:49

来自 System.Web.Compilation 命名空间的 BuildManager.GetReferencedAssemblies() ?

据我所知,这是特定于 ASP.NET 的,这就是它无法在您的控制台应用程序中工作的原因。 (或者在 Windows 应用程序中,就此而言。)

因此,第一个子问题是您是否需要 BuildManager.GetReferencedAssemblies 的特殊功能,即,除了 ASP.NET 特定的功能之外,它还需要仔细查找并查找引用程序集的方式 - 不仅是应用程序引用的所有程序集,还包括它们引用的所有程序集等等

(请参阅 AppDomain.GetAssemblies 和 BuildManager.GetReferencedAssemblies 之间的差异

如果您想要执行的操作只需使用 .exe 直接引用的程序集列表即可正常工作(加上此后动态加载的任何内容(无论是通过代码显式加载还是通过调用本身引用它们的引用程序集隐式加载),最简单的方法就是这样:

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

如果没有,那么这对您来说会变得复杂,因为.NET 中没有一种直接的方法来获取应用程序间接引用的所有程序集的列表。理论上,您可以编写代码在 Assembly.GetEntryAssembly() 上递归调用 Assembly.GetReferencedAssemblies(),然后调用从中获得的所有结果,然后调用从中获得的所有结果 - 丢弃重复项,这样就不会不会陷入无限循环 - 最终您将得到应用程序直接或间接静态引用的所有程序集。

(如果您曾经动态引用程序集,例如通过 AppDomain.Load() 或类似的方法,它不会列出它们。但是,我也不相信 BuildManager.GetReferencedAssemblies() 会这样做。)

BuildManager.GetReferencedAssemblies() from the System.Web.Compilation namespace?

So far as I am aware, that's ASP.NET specific, which is why it won't work in your console app. (Or in a Windows app either, for that matter.)

So, the first sub-question is whether or not you need the special functionality of BuildManager.GetReferencedAssemblies, namely, that it grovels through and finds - in addition to ASP.NET specific ways of referencing assemblies - not only all the assemblies that your application references, but all the assemblies that they reference, etc., etc.

(See Difference between AppDomain.GetAssemblies and BuildManager.GetReferencedAssemblies )

If what you're trying to do will work fine with just a list of the assemblies your .exe references directly (plus any that have been dynamically loaded since then, either explicitly by your code or implicitly by calling into a referenced assembly that itself references them), the easiest way is just this:

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

If not, that's where it's going to get complicated for you, because there isn't a straightforward way in .NET to get a list of all assemblies which an app references indirectly. You can, in theory, write code to recursively call Assembly.GetReferencedAssemblies() on Assembly.GetEntryAssembly(), and then on all the results you get from that, and then on all the results you get from those - discarding duplicates so you don't end up in an infinite loop - and you'll eventually end up with all the assemblies that are directly or indirectly statically referenced by your app.

(If you ever reference assemblies dynamically, say by AppDomain.Load() or some such, it won't list them. But then, I don't believe BuildManager.GetReferencedAssemblies() does either.)

心病无药医 2024-09-19 17:42:49

AppDomain.CurrentDomain.GetAssemblies() 并没有完全达到目的。尽管引用了一些程序集,但未包含这些程序集。我所做的是:

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

这没有返回与 AppDomain.CurrentDomain.GetAssemblies() 一样多的程序集,但它返回了我需要的程序集。不知道为什么会出现差异。 Cerebrate,不过还是谢谢你的回复。你让我走上了我需要的轨道,我赞成你的回复。

AppDomain.CurrentDomain.GetAssemblies() didn't quite do the trick. There were some assemblies that were not included, though they were referenced. What I did was this:

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

This didn't return as many assemblies as AppDomain.CurrentDomain.GetAssemblies(), but it returned the ones I needed. Not sure why there was a discrepancy. Cerebrate, thank you for the reply though. You got me on the track I needed, and I upvoted your reply.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文