Inconsistent assembly loading behavior in powershell
我正在调试PowerShell脚本开始出现故障的原因,看起来它使用的哈希集没有引用System.Core程序集,因此修复程序将以如下方式结束:
1 2
| Add-Type -AssemblyName System.Core
$hash = new-object 'System.Collections.Generic.HashSet[string]' |
我不知道它以前是如何工作的,在一些机器上仍然可以正常运行,没有添加类型行。我这里缺什么?
- 检查$profile,看看它是否在这些机器上加载该程序集?
- 不同的PowerShell版本?
- @Nathantuggy我仔细检查过,两台机器上都没有配置文件。
- @OJK两台计算机上的PowerShell版本相同。
- 我猜程序集以前是由另一台计算机上的另一个应用程序加载的。在两者上都尝试[AppDomain]::currentDomain.getAssemblies(),然后查看是否已加载System.Core。
- fwiw,在我的机器上,System.Core总是被加载,即使我用-NoProfile -version 启动PowerShell(安装的版本是3.0)。
- 没有System.CoreAdd-Type的呼叫,失败时,您得到的错误是什么?
为了继续大卫的想法,并且因为注释中的代码很可怕,您应该检查程序集是否已加载。这里有一个关于检查程序集的小博客
1 2 3 4
| If (!(([appdomain]::currentdomain.GetAssemblies()).FullName -match"System\.Core")){
Add-Type -AssemblyName System.Core
}
$hash = new-object 'System.Collections.Generic.HashSet[string]' |
我默认加载了这个程序集。好奇受影响的系统有什么。受影响的计算机上的.NET框架版本是什么?我的3.5代码中有一些在Windows更新后停止工作,需要重新安装框架。
Jeroen Mostert的评论
If you want to be really precise about it, you should verify you've
got .NET's very own System.Core, not any old impostor, and then
there is no need to check that's already happened. Add-Type
-AssemblyName"System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
- 好吧,如果你真的想对它精确些,你应该确认你有.NET自己的System.Core,而不是任何旧的冒名顶替者,然后就不需要检查已经发生了什么。单独使用EDOCX1[1]就足够了(如果需要,版本策略将负责加载更高版本)。
- @Jeroemoster好计划。我的看起来像是System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089不确定OP需要哪一个。谢谢。我还是不确定是否应该删除这个。
- 因为HashSet存在于3.5中,所以我将使用它来最大化脚本运行的机会。当然,除非你特别需要.NET 4.0,但那不是因为HashSet。
- 问题是,如果默认环境已经加载了System.Core, Version=4.0.0.0, ...,并且如果有PowerShell 4.0、Afaik,则该程序集应该自动加载,那么Add-Type将失败:"类型名称和命名空间在会话中必须是唯一的。不能卸载或更改类型。如果需要更改类型的代码,则必须更改名称或启动新的Windows PowerShell会话。否则,命令失败。"(见-Name参数)
- @培根片:但那不是真的。我在自己的系统上尝试过,当尝试加载EDOCX1的3.5版(0)is version 4.0 is already loaded(PowerShell 3.0)时,Add-Type根本不会失败。这是有道理的,因为在.NET 4.0上请求3.5只会得到4.0,这是由版本控制策略提供的。