找不到类型[System.IO.Compression.CompressionLevel]:请确保包含此类型的程序集已加载。

37
我编写了这个PowerShell脚本来归档在特定日期范围内创建的所有日志文件。
$currentDate = Get-Date;
$currentDate | Get-Member -Membertype Method Add;
$daysBefore = -1;
$archiveTillDate = $currentDate.AddDays($daysBefore);

$sourcePath = 'C:\LOGS';
$destPath='C:\LogArchieve\_'+$archiveTillDate.Day+$archiveTillDate.Month+$archiveTillDate.Year+'.zip';

foreach( $item in (Get-ChildItem $sourcePath | Where-Object { $_.CreationTime -le $archiveTillDate }) )
{
    [Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
    $compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal;
    [System.IO.Compression.ZipFile]::CreateFromDirectory($sourcePath,$destPath, $compressionLevel, $false);
}

foreach循环之前是有效的,但一旦进入循环,它就会产生这些错误:

Unable to find type [System.IO.Compression.CompressionLevel]: make sure that the assembly containing this type is loaded.
At line:4 char:65
+ $compressionLevel = [System.IO.Compression.CompressionLevel] <<<< ::Optimal;
+ CategoryInfo          : InvalidOperation: (System.IO.Compression.CompressionLevel:String) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound

由于 System.IO.Compression 已经是 .NET 4.5 的一部分,我已在系统上安装了它,但我仍然遇到这些错误。我正在使用 PowerShell v2.0,且我的操作系统是 Windows Server 2008 R2。

我该如何使它工作?

3个回答

43

尝试使用Add-Type -AssemblyName System.IO.Compression.FileSystem。它更加简洁,而且不需要依赖于引用程序集,也不需要安装Visual Studio。


3
好的回答。你还不依赖于文件路径。 - majkinetor
1
这个答案仅适用于全局程序集缓存中的程序库。例外情况包括 C:/Program Files/WindowsPowerShell/Modules/ 下的任何内容,例如 Microsoft.PowerShell.PSReadline。这些必须使用 Add-Type -Path 来加载。 - MultiplyByZer0

19

你可以手动将一个.NET类添加到PowerShell会话中。

从你的脚本中删除[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");,并在最顶部添加以下内容:

Add-Type -Path "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll"

或者在32位系统上:

Add-Type -Path "C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.IO.Compression.FileSystem.dll"

假设您的系统已经成功安装了.NET 4.5,并且System.IO.Compression.FileSystem.dll文件实际存在。


这是针对PowerShell v2的,但是对于PowerShell v3或更高版本,LoadWithPartialName据说已经被弃用 - Peter Mortensen
20
尝试使用 Add-Type -AssemblyName System.IO.Compression.FileSystem 替代。这样更加简洁,而且不需要依赖于参考程序集,也无需安装 Visual Studio。 - bincob
1
@bincob 把你的评论变成一个答案。它应该是被接受的答案。 - Reg Edit
@RegEdit,谢谢 - 我已经将它发布为答案。 - bincob
在 Powershell ISE 中,我的代码被下划线标记为错误 - 即使我使用 Add-TypeLoadWithPartialName,也无法运行脚本。 - Sphynx

1
此外,请确保检查您的$pshome exe.config文件。我曾经遇到过一个问题,Powershell ISE拒绝加载.NET程序集,因为配置文件中列出了.NET 2.0而不是4。

这个文件在哪里? - Sphynx
好的,明白了,它是 Join-Path $PSHOME 'powershell_ise.exe.config',结果为 "C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe.config"。 - Sphynx
Powershell LSE 似乎只支持 .NET 4.0 - 我尝试将配置更改为 4.5 和 4.8,但当我启动 Powershell LSE 时,它弹出一个 Yes/No 对话框,指出它需要 4.5/4.8 并询问“是否现在要安装此 .NET Framework 版本?”,选择“Yes”会重定向到 Microsoft 主页。此外,我不得不遵循这个指南才能获得编辑该文件的权限:https://www.partitionwizard.com/partitionmagic/you-require-permission-from-trustedinstaller.html。 - Sphynx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接