Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell .NET object missing methods

I am working with the IO.Compression namespace in PowerShell and am running into an issue where Methods which are available in my C# code are not available in PowerShell

C# snippet

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");
}

Similar start of code in 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")

A review of members shows that the function CreateEntryFromFile() (among others) is missing. The variable is a type of ZipArchive and a new file is created.
$archive | Get-Member displays:

   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;}

Is this simply part of how PowerShell creates .NET objects where not all methods are (or can be) supported?

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

like image 769
Brettski Avatar asked Nov 16 '25 22:11

Brettski


1 Answers

CreateEntryFromFile is an extension method, so it doesn't appear on the ZipArchive class in Powershell.

Option 1

In Powershell 3.0 or higher, you can declare the extension method for use in 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")

Option 2

Just use the extension method as a plain old static method.

$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")

The second option is less code and also works in older versions of Powershell.

Reference: How do I use extension methods in ZipFileExtensionsClass?

like image 63
NightOwl888 Avatar answered Nov 18 '25 11:11

NightOwl888



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!