Author Posts

December 16, 2016 at 10:42 pm

Recently have been working on a script that extracts the contents of a file and puts that contents on a server unzipped.

I've run into an issue where the script will bomb because it cannot find types that are clearly loaded in the script.

Here is the issue and question:

If I run this script in a new session I get the following error everytime:
At C:\temp\copycode.ps1:89 char:13
+ hidden [ZipArchiveEntry]$entry
+ ~~~~~~~~~~~~~~~
Unable to find type [ZipArchiveEntry].
At C:\temp\copycode.ps1:91 char:18
+ ArchiveFile([ZipArchiveEntry]$entry) {
+ ~~~~~~~~~~~~~~~
Unable to find type [ZipArchiveEntry].
At C:\temp\copycode.ps1:100 char:10
+ [ZipFileExtensions]::ExtractToFile($this.entry, $file.FullNam ...
+ ~~~~~~~~~~~~~~~~~
Unable to find type [ZipFileExtensions].
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : TypeNotFound

However if I add the following in a separate file and then call this script it runs with out issue. Why won't the using statements and the add-type work in the same script.

This way works:
param(
[Parameter(Mandatory=$true)][string]$sourceZip,
[Parameter(Mandatory=$true)][string]$destPath
)
[void][Reflection.assembly]::LoadWithPartialName('System.IO.Compression')
[void][Reflection.assembly]::LoadWithPartialName('System.IO.Compression.FileSystem')
add-type -assemblyname 'System.IO.Compression'
add-type -assemblyname 'System.IO.Compression.FileSystem'
& .\copy-code.ps1 -sourcezip $sourceZip -destpath $destPath

this doesnt
.\copy-code -sourcezip c:\temp\somezipfile.zip -destpath c:\temp\somezip

copy-code.ps1 — Full source is in gist below:

December 20, 2016 at 9:14 pm

Using, with namespace, is basically like it is in C# – it makes it easier to use referenced namespaces, but it doesn't actually reference and load them. So it works when you explicitly load them.

December 21, 2016 at 3:26 am

Yes it works when I load them in a wrapper before I create the class. That is why I was puzzled. Or was this a question don? So it works when you explicitly load them. Or a statement?

December 21, 2016 at 2:46 pm

I would expect it to work when the assemblies are explicitly loaded; "using" does not actually attempt to load assemblies – it provides a shortcut was of using already loaded assemblies.

December 21, 2016 at 3:33 pm

I commented the classes out and changed to the fullname of the class.. Yet I'm still faced with the same issue when trying to initially run the script:

#requires -version 5.0
#using namespace System.IO
#using namespace System.IO.Compression
param(
[Parameter(Mandatory=$true)][string]$sourceZip,
[Parameter(Mandatory=$true)][string]$destPath
)
add-type -assemblyname 'System.IO.Compression'
add-type -assemblyname 'System.IO.Compression.FileSystem'

These two references keep failing:
System.IO.Compression.ZipFileExtensions
System.IO.Compression.ZipArchiveEntry

If I add the types in a separate script then call the script with the class it works fine.