2016-06-12 17 views
7

为什么不是功能[System.IO.Path]::Combine采取我的第一个参数?[System.IO.Path] ::结合没有把我的PowerShell变量作为参数?

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它..?

回答

7

只是忽略前导反斜杠你的第二路:

[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

啊谢谢......我以为这种情报是建立在'[System.IO.Path] :: Combine'功能 – ibiza

+0

是的,我也这么想过,只是试了一下;-)。 –

+2

谢谢,我想过使用Join-Path ...但是不得不使用Join-Path两次有点难过:p – ibiza

8

为了补充Martin Brandl's helpful answer

Spe实际上,反直觉 - logic applied by [System.IO.Path]::Combine是:“如果路径2路径3也是绝对路径,则组合操作会丢弃所有先前组合的路径并重置为该绝对路径。” (这也适用于其他方法的重载)。

换句话说:最后路径参数指定的开始与\(包括\\)或<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小命令的逻辑:

尽管这是可以理解到期望-ChildPath参数以支持的路径的阵列(它不),这是重要了解Join-Path的设计根本不同于[System.IO.Path]::Combine(),从Windows PowerShell v5.1开始[1]

  • Join-Path使用多个输入路径,以产生多个输出路径而不是解释输入路径作为单个输出路径的部件。

  • 输入路径对(一个或多个)的父和子路径,每对得到接合,并导致其自身的输出路径:

    • > Join-Path \foo \bar \foo\bar
      • 短为: Join-Path -Path \foo -ChildPath \bar
      • 请注意PS与[System.IO.Path]::Combine()不同,它处理孩子的可选前导\如你所期望的那样。
  • 而父路径参数(-Path确实支持一个阵列的父路径,子路径参数(-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
  • 最后,值得注意的是,Join-Path不是只适用于文件系统路径,但任何PowerShell [分层数据存储]提供者的路径,应用提供适当的路径分隔符。


[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),而Windows自带的Windows PowerShell版本至v5.1仍不支持rt it。
这种新行为尚未记录(甚至在Join-Path -?中甚至没有反映语法),但它最终可能会进入Windows PowerShell(因此可能会进入所有版本)。

+1

这应该是被接受的答案。 –

相关问题