System.IO.FileInfo相对路径跨平台差异及脚本参数最优处理方案问询
System.IO.FileInfo本身在Windows和Linux下的相对路径解析逻辑完全一致,出现表现差异的核心原因是:PowerShell的当前工作目录($PWD)与.NET运行时维护的[Environment]::CurrentDirectory不会自动同步,FileInfo构造函数解析相对路径时默认使用.NET的当前工作目录,而非PowerShell当前所在的目录。
举个实际场景:你在PowerShell里用cd命令切换目录后,[Environment]::CurrentDirectory的值并不会同步更新,这就导致同一段相对路径传入FileInfo后解析结果和预期不符,和操作系统本身无关。
不用手动判断路径是否为绝对路径,PowerShell内置的$PSCmdlet.GetUnresolvedProviderPathFromPSPath()方法会自动基于PowerShell当前工作目录解析路径,天然兼容绝对路径、相对路径、UNC网络路径、PowerShell自定义提供程序路径(如注册表路径、证书路径等),不受.NET当前目录不同步的问题影响。
场景1:要求传入的是已存在的文件
param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [ValidateScript({ if (Test-Path $_ -PathType Leaf) { return $true } throw "无效的文件路径:$_" })] [string]$Path ) # 直接获取解析完成的绝对路径 $absolutePath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Path) # 转换为FileInfo对象不会再出现路径错误 $fileInfo = [System.IO.FileInfo]$absolutePath
场景2:允许传入不存在的文件路径(如输出文件场景)
如果你的脚本需要支持传入还未创建的文件路径,不要用Resolve-Path(该方法要求路径必须存在才会返回结果),直接用上述内置方法即可:
param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$OutputPath ) $absoluteOutputPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($OutputPath) $outputFile = [System.IO.FileInfo]$absoluteOutputPath # 后续可直接基于该路径创建文件
你担心的网络路径(UNC路径,格式为\\服务器地址\共享名\路径)识别问题并不存在,Split-Path -IsAbsolute会正确将UNC路径判定为绝对路径返回$true。但手动判断路径类型的方案存在局限性:如果遇到PowerShell自定义提供程序路径、或者需要支持不存在的路径时,处理逻辑容易出问题,更推荐使用上述内置方法处理路径解析。
内容的提问来源于stack exchange,提问作者Santiago Squarzon

