Search code examples
windowspowershellunzip

cannot call a method on a null-valued expression - how to solve it


I have written a script that gets the zip file from a specific folder and unzip the file to a specific folder.

please check the below codes

$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace("C:\Users\jhnayak\Views_Seagate\jhnayak_DDTools_Phase14_Dev\apps\ddcli\build\win\\..\\..\\..\\..\sas2_rel\mptlib2_rel\mptlib2_rel.zip")
$destination = $shell_app.namespace("C:\Users\jhnayak\Views_Seagate\jhnayak_DDTools_Phase14_Dev\apps\ddcli\build\win\\..\\..\\..\\..\sas2_rel\mptlib2_rel")
$destination.Copyhere($zip_file.items())

$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace((Get-Location).Path + "\\..\\..\\..\\..\\sas2_rel\mptlib2_rel" + "\$filename")
$destination = $shell_app.namespace((Get-Location).Path + "\\..\\..\\..\\..\\sas2_rel\mptlib2_rel")
$destination.Copyhere($zip_file.items())

for both the codes i got the same error, please check below

You cannot call a method on a null-valued expression.
At line:1 char:38
+ $destination.Copyhere($zip_file.items <<<< ())
    + CategoryInfo          : InvalidOperation: (items:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

when i hardcoded the path without using \..\ in between it worked perfectly.

please check the below code

$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace("C:\Users\jhnayak\Views_Seagate\jhnayak_DDTools_Phase14_Dev\sas2_rel\mptlib2_rel\mptlib2_rel.zip")
$destination = $shell_app.namespace("C:\Users\jhnayak\Views_Seagate\jhnayak_DDTools_Phase14_Dev\sas2_rel\mptlib2_rel")
$destination.Copyhere($zip_file.items())

but i would like to use the earlier one, so that the path should not be hard coded, it should work for all paths.

What is causing this error? What exactly is my null valued expression?


Solution

  • Try parsing the path before passing it to $shell_app.namespace(). There is a handy method in .Net that does just that: System.IO.Path.GetFullPath(). Like so,

    $relativeLoc = "...build\win\\..\\..\\..\\..\sas2..." # Complex dynamic path
    $parsedLoc = [IO.Path]::GetFullPath($relativeLoc) # Get absolute path
    $zip_file = $shell_app.namespace($parsedLoc)
    

    As a bonus, you can use Test-Path to check that the target $parsedLoc exists.