神秘的不同转换为看似相同的输入数据的字符串[]

Rom*_*min 3 powershell powershell-2.0

在调查某些问题时,我发现原因是看似相同的输入数据的字符串[]的意外不同转换.也就是说,在下面的代码中,两个命令都返回相同的两个项File1.txt和File2.txt.但转换为string []会产生不同的结果,请参阅注释.

任何想法为什么呢?这可能是一个错误.如果有人也这么认为,我会提交.但是,了解正在发生的事情并避免陷阱就好了.

# *** WARNING
# *** Make sure you do not have anything in C:\TEMP\Test
# *** The code creates C:\TEMP\Test with File1.txt, File2.txt

# Make C:\TEMP\Test and two test files
$null = mkdir C:\TEMP\Test -Force
1 | Set-Content C:\TEMP\Test\File1.txt
1 | Set-Content C:\TEMP\Test\File2.txt

# This gets just file names
[string[]](Get-ChildItem C:\TEMP\Test)

# This gets full file paths
[string[]](Get-ChildItem C:\TEMP\Test -Include *)

# Output:
# File1.txt
# File2.txt
# C:\TEMP\Test\File1.txt
# C:\TEMP\Test\File2.txt
Run Code Online (Sandbox Code Playgroud)

Rom*_*min 8

好吧,我有一些线索(可能发布这个问题刺激了我的想法).是的,这是一种陷阱,不仅在PowerShell中(但PowerShell使其成为可能).

显然PowerShell只是ToString()用于转换.这是一个错误的假设,System.IO.FileInfo.ToString()返回FullName.Reflector显示它返回的base.OriginalPath是构造函数中传递的内容,而不是完整路径.

这是演示:

Set-Location C:\TEMP\Test
[string](New-Object IO.FileInfo File1.txt)
[string](New-Object IO.FileInfo C:\TEMP\Test\File1.txt)
[string](New-Object IO.FileInfo ./..//Test///..Test\File1.txt)

# Output:
# File1.txt
# C:\TEMP\Test\File1.txt
# ./..//Test///..Test\File1.txt
Run Code Online (Sandbox Code Playgroud)

因此,看起来第一个Get-ChildItem在创建FileInfo对象时仅使用名称,而第二个Get-ChildItem使用–Include参数使用完整路径.这是一个错误吗?它现在看起来有争议.这可能是一个特征,值得怀疑,但仍有一些潜在的原因.我怀疑,但......