I was wondering if someone could help me understand why does System.IO.FileInfo
behaves differently on Windows than on Linux when handling relative paths.
Example
- On Linux
PS /home/user/Documents> ([System.IO.FileInfo]'./test.txt').FullName
/home/user/Documents/test.txt
- On Windows
PS C:\Users\User\Documents> ([System.IO.FileInfo]'.\test.txt').FullName
C:\Users\User\test.txt
EDIT
To clarify on the above, there is no difference on how System.IO.FileInfo
handles relative paths on Windows or Linux. The issue is related to [Environment]::CurrentDirectory
not being updated by Push-Location
and Set-Location
, see Mark Bereza's answer for more details on this.
PS /home/user> [Environment]::CurrentDirectory
/home/user
PS /home/user> cd ./Documents/
PS /home/user/Documents> [Environment]::CurrentDirectory
/home/user
And assuming this is a expected behavior, what would be an optimal way to approach our param(...)
blocks on scripts and functions to accept both cases (absolute and relative). I used to type constraint the path parameter to System.IO.FileInfo
but now I can see it is clearly wrong.
This is what I came across, but I'm wondering if there is a better way.
I believe Split-Path -IsAbsolute
will also bring problems if working with Network Paths, please correct me if I'm wrong.
param(
[ValidateScript({
if (Test-Path $_ -PathType Leaf) {
return $true
}
throw 'Invalid File Path'
})]
[string] $Path
)
if (-not (Split-Path $Path -IsAbsolute)) {
[string] $Path = Resolve-Path $Path
}
[System.IO.Path]::GetFullPath([System.IO.Path]::Combine($pwd, '.\test.txt'))
– Joannjoanna[IO.Path]::IsRooted(..)
before or just do it no matter what? I guess I wont find an answer on the behavior ofFileInfo
on Windows vs Linux so you can propose this as an answer and if by the end of the day nobody can answer the other question I'll go ahead an accept it. Thanks Theo. – Assyrian