PowerShell .NET 对象缺少方法

Bre*_*ski 4 .net c# powershell

我正在 PowerShell 中使用 IO.Compression 命名空间,但遇到了一个问题:我的 C# 代码中可用的方法在 PowerShell 中不可用

C# 片段

string archfile = @"c:\temp\a1.zip";
string source = @"C:\temp\testing\logs\BatchProcess\BatchProcess_2017_08_22.log";

using (ZipArchive archive = ZipFile.Open(archfile, ZipArchiveMode.Update))
{
    archive.CreateEntryFromFile(source, @"myfolder\folder2\file.log");
}
Run Code Online (Sandbox Code Playgroud)

PowerShell 中类似的代码开头

Add-Type -assembly System.IO.Compression.FileSystem
$archfile = "c:\temp\a1.zip"
# open mode: 1: Create, 2: Update
$archive = [System.IO.Compression.ZipFile]::Open("C:\temp\2.zip", 2)
$archive.CreateEntryFromFile($source, "myfolder\folder2\file.log")
Run Code Online (Sandbox Code Playgroud)

对成员的审查表明,缺少函数 CreateEntryFromFile() (以及其他函数)。该变量是 ZipArchive 类型,并创建一个新文件。
$archive | Get-Member显示:

   TypeName: System.IO.Compression.ZipArchive

Name        MemberType Definition
----        ---------- ----------
CreateEntry Method     System.IO.Compression.ZipArchiveEntry CreateEntry(string entryName), System.IO.Compression.ZipArchiveE...
Dispose     Method     void Dispose(), void IDisposable.Dispose()
Equals      Method     bool Equals(System.Object obj)
GetEntry    Method     System.IO.Compression.ZipArchiveEntry GetEntry(string entryName)
GetHashCode Method     int GetHashCode()
GetType     Method     type GetType()
ToString    Method     string ToString()
Entries     Property   System.Collections.ObjectModel.ReadOnlyCollection[System.IO.Compression.ZipArchiveEntry] Entries {get;}
Mode        Property   System.IO.Compression.ZipArchiveMode Mode {get;}
Run Code Online (Sandbox Code Playgroud)

这是否只是 PowerShell 创建 .NET 对象(并非所有方法都受(或可以)支持)的一部分?

ZipArchive 参考:https://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive( v=vs.110).aspx

Nig*_*888 5

CreateEntryFromFile是一个扩展方法,因此它不会出现在ZipArchivePowershell 中的类中。

选项1

在 Powershell 3.0 或更高版本中,您可以声明在 Powershell 中使用的扩展方法。

Add-Type -AssemblyName System.IO.Compression.FileSystem

Update-TypeData -TypeName System.IO.Compression.ZipArchive -MemberType 
ScriptMethod -MemberName CreateEntryFromFile -Value {
    switch ($args.Count)
    {
        2 { [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($this, $args[0], $args[1]) }
        3 { [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($this, $args[0], $args[1], $args[2]) }
        default { throw "No overload for CreateEntryFromFile takes the specified number of parameters." }
    }
}

$archfile = "c:\temp\a1.zip"
# open mode: 1: Create, 2: Update
$archive = [System.IO.Compression.ZipFile]::Open("C:\temp\2.zip", 2)
$archive.CreateEntryFromFile($source, "myfolder\folder2\file.log")
Run Code Online (Sandbox Code Playgroud)

选项2

只需将扩展方法用作普通的旧静态方法即可。

$archfile = "c:\temp\a1.zip"
# open mode: 1: Create, 2: Update
$archive = [System.IO.Compression.ZipFile]::Open("C:\temp\2.zip", 2)
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $source, "myfolder\folder2\file.log")
Run Code Online (Sandbox Code Playgroud)

第二个选项是更少的代码,并且也适用于旧版本的 Powershell。

参考:如何在 ZipFileExtensionsClass 中使用扩展方法?