How do I use extension methods in ZipFileExtensionsClass?

This topic contains 2 replies, has 3 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 3 years, 4 months ago.

  • Author
    Posts
  • #12079
    Profile photo of GS
    GS
    Participant

    Hello,

    I'm trying to use ZipFile class from .NET 4.0 System.IO.Compression namespace and code fails to pull Extension method called "CreateEntryFromFile" implemented in ZipFileExtensions class (http://msdn.microsoft.com/en-us/library/system.io.compression.zipfileextensions(v=vs.110).aspx). It states "The ZipFileExtensions class contains only static methods that extend the ZipArchive and ZipArchiveEntry classes. You do not create an instance of the ZipFileExtensions class; instead, you use these methods from instances of ZipArchive or ZipArchiveEntry."

    Sample Code below fails with Method invocation failed because [System.IO.Compression.ZipArchive] does not contain a method named 'CreateEntryFromFile'.

    What am I missing?

    [Reflection.Assembly]::LoadWithPartialName( "System.IO.Compression.FileSystem" )
    $zipFile = [System.IO.Compression.ZipFile]::Open($zipFileLocation, "update")
    [System.IO.Compression.ZipArchive]$zipFile.CreateEntryFromFile("$PathToOutputResult\$filename.p12", "$filename.p12")

  • #12083
    Profile photo of Don Jones
    Don Jones
    Keymaster

    System.IO.Compression.ZipArchive does not, in fact, have a CreateEntryFromFile() method. See http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx; as noted, that's an extension method. Providing that as background info for future readers ;).

    Using extension methods in PowerShell is somewhat less than straightforward. There's a discussion (http://bartdesmet.net/blogs/bart/archive/2007/09/06/extension-methods-in-windows-powershell.aspx) you might look into.

    Extension methods were new in .NET 3.5; PowerShell's syntax was developed around .NET 2.0 and didn't really accommodate extension methods directly. So you sort of have to extend the type using PowerShell's ETS first, pointing to the underlying static method. http://social.technet.microsoft.com/Forums/en-US/bf3fd75b-30a8-44f9-b82d-5e9cc244faba/are-extension-methods-accessible?forum=winserverpowershell is perhaps a more straightforward example. Although whether that works and how you do it depends a lot on exactly what you're trying to get to.

    So, very short answer: you can't do that.

  • #12096
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Those articles appear to have been written prior to PowerShell 3.0's release. If you want to add an extension method these days, it's even easier; no need to produce an XML file first, if you don't want to. For example:

    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." }
        }
    }
    
    $zipFile = [System.IO.Compression.ZipFile]::Open($zipFileLocation, 'update')
    $zipFile.CreateEntryFromFile("$PathToOutputResult\$filename.p12", "$filename.p12")
    
    

    You can put the Add-Type and Update-TypeData commands into a module or profile script, and forget about them.

    Of course, you don't have to use the "extension method" syntax at all. If you prefer, you can just call them as static methods and not bother with Update-TypeData:

    Add-Type -AssemblyName System.IO.Compression.FileSystem
    
    $zipFile = [System.IO.Compression.ZipFile]::Open($zipFileLocation, 'update')
    [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipFile, "$PathToOutputResult\$filename.p12", "$filename.p12")
    

You must be logged in to reply to this topic.