相同代码编译的exe正常运行,C# csx脚本为何报System.NullReferenceException
问题原因
- 线程模型不匹配:
System.Management库依赖的WMI底层组件要求代码必须运行在无上下文附着的**MTA(多线程单元)**线程中。你在Visual Studio中编译的控制台程序默认主线程就是无上下文的MTA线程,符合运行要求;而dotnet script默认的脚本执行线程不符合该要求,触发MTAHelper.IsNoContextMTA()内部检查时抛出空引用异常。 - 程序集兼容问题:你当前引用的是GAC中.NET Framework版本的
System.Management.dll,如果你的dotnet script运行在.NET Core/.NET 5+环境下,跨版本引用程序集也可能额外引发兼容异常。
解决方案
第一步:替换程序集引用
把原来硬编码GAC路径的引用替换为NuGet包引用,避免版本兼容问题:
// 替换原来的#r GAC路径语句 #r "nuget: System.Management" using System.Management; using System.Threading;
第二步:将WMI逻辑放到显式指定MTA状态的线程中执行
ManagementClass regProvClass = null; // 新开线程,指定MTA单元状态 Thread wmiThread = new Thread(() => { // 所有System.Management相关操作都放在这个线程里执行 regProvClass = new ManagementClass(@"\\.\root\default:StdRegProv"); // 后续对regProvClass的操作也可以放在这里 }); wmiThread.SetApartmentState(ApartmentState.MTA); wmiThread.Start(); wmiThread.Join(); // 线程执行完成后即可正常使用regProvClass对象
按上述修改后,脚本就可以正常运行。
内容的提问来源于stack exchange,提问作者Markus Peterson
相关产品推荐
相关产品推荐

