在调查某些问题时,我发现原因是看似相同的输入数据的字符串[]的意外不同转换。也就是说,在下面的代码中,两个命令都返回相同的两个项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
答案 0 :(得分: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
因此,看起来第一个Get-ChildItem
仅在创建FileInfo
个对象时使用名称,而第二个Get-ChildItem
使用–Include
参数使用完整路径。这是一个错误吗?它现在看起来有争议。这可能是一个特征,值得怀疑,但仍有一些潜在的原因。我怀疑,但是......