PowerShell 核心。相对路径问题

For*_*s1k 1 .net powershell .net-core powershell-core

电源外壳:

$file = "text.txt"
Test-Path $file            
# True
 
Get-Location
# C:\Users\Fors1k

[IO.File]::OpenRead($file) 
# FileStream
 
[IO.FileInfo]::new($file)  
# Mode                 LastWriteTime         Length Name                         
# ----                 -------------         ------ ----                         
# -a----        05.03.2021     18:12              7 text.txt  
                      
gc $file                   
# test123
Run Code Online (Sandbox Code Playgroud)

一切都好。

PowerShell 核心:

$file = "text.txt"
Test-Path $file            
# True
 
Get-Location
# C:\Users\Fors1k

[IO.File]::OpenRead($file) 
# Exception calling "OpenRead" with "1" argument(s): "Could not find file 'C:\Windows\system32\text.txt'."
 
[IO.FileInfo]::new($file)  
# Mode                 LastWriteTime         Length Name                         
# ----                 -------------         ------ ----
# larhs          01.01.1601     3:00  
                      
gc $file                   
# test123
Run Code Online (Sandbox Code Playgroud)

这里我遇到了错误。

据我了解,问题在于 .NET 方法认为当前位置是 sysfolder,而不是真正的当前位置。

回应建议:

据我了解,有很多解决方案:

$file = "text.txt"
[Environment]::CurrentDirectory = Get-Location
[IO.File]::OpenRead($file)
#
#
$file = "text.txt"
[IO.Directory]::SetCurrentDirectory((Get-Location))
[IO.File]::OpenRead($file)
#
#
$file = "text.txt"
$file = Convert-Path $file
[IO.File]::OpenRead($file)
#
#
# My solution, before asking, was
$file = "text.txt"
$file = Get-Item $file
[IO.File]::OpenRead($file)
Run Code Online (Sandbox Code Playgroud)

但所有这些都是“fix on the go”(我不知道这个短语的正确英语习语)。

我的意思是,为什么这在 posh 5.1 上正常工作?

为什么这个代码:[IO.File]::OpenRead("text.txt")适用于 pwsh 我的朋友,我问了哪些?

也许还有这样的设定(夸张):[DotNet.Path]::SetDefaultLocation("TheSameAsPwsh")

@mathias-r-jessen,明白你的意思了:

[Environment]::CurrentDirectoryGet-Location是一个最初不相关的东西。

电源外壳:

"$(Get-Location)" -eq ([Environment]::CurrentDirectory)
# True
##
##
Set-Location ([Environment]::GetFolderPath("desktop"))

"$(Get-Location)" -eq ([Environment]::CurrentDirectory)
# False (!!!)
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是为了了解正在发生的事情:

为什么我的 pwsh 是[Environment]::CurrentDirectoryC:\Windows\system32,是否可以像在 posh 中一样将此默认值更改为用户文件夹?

Jom*_*oma 5

更改 .NET 的当前工作目录。

[Environment]::CurrentDirectory = "$(Get-Location)"
Run Code Online (Sandbox Code Playgroud)

或者

[System.IO.Directory]::SetCurrentDirectory("$(Get-Location)")
Run Code Online (Sandbox Code Playgroud)

替代代码 - 相同的结果
您的代码使用 Streams。您应该在最后使用 try -finally 释放/关闭流资源。

$file = "text.txt"


if (! (Test-Path $file -PathType Leaf)) {
    New-Item $file
}

Get-Content $file
Run Code Online (Sandbox Code Playgroud)

File.OpenRead(String path) 方法
备注
path 参数允许指定相对或绝对路径信息。相对路径信息被解释为相对于当前工作目录。要获取当前工作目录,请参阅GetCurrentDirectory

Directory.GetCurrentDirectory 方法
备注
当前目录与原始目录不同,原始目录是启动进程的目录。

在 pwsh.exe 和 powershell.exe 中检查此方法。返回的值不同。我认为每个人都有不同的实现。 普沃什 Windows PowerShell

如果您从脚本文件运行代码。即./Script.ps1 您可以使用$PSScriptroot全局变量,它包含脚本运行的目录的路径。

Write-Host "ScriptPath: $PSScriptroot"
[Environment]::CurrentDirectory = "$PSScriptroot"
Write-Host "CurrentDirectory: $([Environment]::CurrentDirectory)"
Run Code Online (Sandbox Code Playgroud)

普沃什