为什么函数[System.IO.Path]::Combine
没有采用我的第一个参数?
PS C:\WINDOWS\system32> $g_basePath
F:\Dev\OneClickTools
PS C:\WINDOWS\system32> [Tests.Utils]::CUSTOMASSEMBLY_TEST
CustomLogic.dll
PS C:\WINDOWS\system32> [System.IO.Path]::Combine($g_basePath, "\bin\debug", [Tests.Utils]::CUSTOMASSEMBLY_TEST)
\bin\debug\CustomLogic.dll
第三个命令显示只连接了第二个和第三个参数,或者它是否使用空字符串$g_basePath
..?
答案 0 :(得分:8)
只需省略第二条路径上的反斜杠:
[System.IO.Path]::Combine($g_basePath, "bin\debug", [Tests.Utils]::CUSTOMASSEMBLY_TEST)
纯PowerShell尝试将使用Join-path cmdlet两次:
Join-Path $g_basePath 'bin\debug' | Join-path -ChildPath [Tests.Utils]::CUSTOMASSEMBLY_TEST
答案 1 :(得分:8)
补充Martin Brandl's helpful answer:
具体来说, - 反直觉 - logic applied by [System.IO.Path]::Combine
是:"如果 path2 或 path3 也是绝对路径,则合并操作会丢弃所有先前组合的路径并重置到该绝对路径。" (这类似于其他方法也适用于重载)。
换句话说:指定的 last 路径参数以\
(包括\\
)或<letter>:
(驱动器规格)开头。导致所有先前路径被忽略。
> [IO.Path]::Combine('\foo', '\bar', '\baz')
\baz # !! '\foo' and '\bar' were ignored
对于预期的行为 - 初始\
应被视为除第一个之外的每个路径组件的可选部分 - 确保除第一个之外的每个组件都没有从\
开始 - Join-Path
处理正如人们所期望的那样。
简单功能可以做到这一点:
# Combines array of path components $a to a single path.
function combine([string[]] $a) {
[IO.Path]::Combine([string[]] (@($a[0]) + $a[1..$($a.count-1)] -replace '^\\', ''))
}
请注意,转换为[string[]]
对于此工作至关重要。
示例电话:
> combine '\foo', '\bar', '\baz'
\foo\bar\baz # as expected
使用 Join-Path
,仅支持对组件,自Windows PowerShell v5.1开始 [1]
,使用管道链接多个呼叫的替代方法是使用(...)
嵌套多个呼叫:
> Join-Path \foo (Join-Path \bar \baz)
\foo\bar\baz
请注意,即使嵌套有点笨拙,您也不必担心以\
开头的从属组件。
至于PowerShell自己的Join-Path
cmdlet 的逻辑:
虽然期望-ChildPath
参数支持路径的数组是可以理解的,但它并不重要,理解这一点非常重要 Join-Path
的设计与[System.IO.Path]::Combine()
的设计基本不同,自Windows PowerShell v5.1 [1] 起
:
Join-Path
使用多个输入路径生成多个输出路径 ,而不是将输入路径解释为 single的组件输出路径。
输入路径是父路径和子路径的 对 ,每对都会加入并产生自己的输出路径:
> Join-Path \foo \bar
\foo\bar
Join-Path -Path \foo -ChildPath \bar
[System.IO.Path]::Combine()
不同,如您所期望的那样处理子路径中的可选前导\
。虽然父路径参数(-Path
) 支持父路径的数组,但子路径参数({{1 不,但是当与-ChildPath
参数和通配符结合使用时,它可以有效地生成多个子路径。
-Resolve
与> Join-Path -Path \foo, \baz -ChildPath \bar
\foo\bar
\baz\bar
不同, [System.IO.Path]::Combine()
可选择支持使用Join-Path
解析通配符路径:
-Resolve
最后值得注意的是> Join-Path -Resolve C:\Win* Sys*
C:\Windows\System
C:\Windows\System32
C:\Windows\SystemApps
C:\Windows\SystemResources
C:\Windows\SysWOW64
C:\Windows\system.ini
不仅适用于文件系统路径,而且适用于任何PowerShell [分层数据存储]提供程序的路径,应用提供者适当的路径分隔符。 / p>
[1]
跨平台 PowerShell版本 PowerShell核心 ,自v6.0.0起,已 支持任意数量的子组件,enabling calls such as Join-Path a b c
to yield a\b\c
(Windows) or a/b/c
(Unix),而从v5.1开始的Windows原生 Windows PowerShell 版本仍然不支持它。
这个新行为尚未记录(甚至没有在Join-Path
中反映语法],但最终可能会进入Windows PowerShell(从而所有版本)。