我从一个不同的问题的答案中获得了一些Powershell代码并创建了这个脚本,稍微修改它以便我可以传入文件名。
$file = [System.io.File]::Open($Args[0], 'Open', 'Read', 'None')
Write-Host "Press any key to continue..."
$null = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
$file.Close()
如果我在我的主目录中运行带有非限定文件的(在Powershell窗口中)或在任何目录中使用完全限定的文件名,它都可以正常工作。该脚本是我路径上的实用程序文件夹中的lockfile.ps1,这些调用都按预期工作。
C:\Users\SteveC.AFRICA> . lockfile abc.txt
C:\Users\SteveC.AFRICA> lockfile abc.txt
C:\Users\SteveC.AFRICA> lockfile .\abc.txt
C:\Users\SteveC.AFRICA> lockfile D:\Junk\abc.txt
但是,当前目录不是我的主目录时,我需要完全限定文件名,即使对于当前目录中的文件也是如此。所以此调用有效
D:\Junk> lockfile D:\Junk\abc.txt
但这些不是
D:\Junk> lockfile abc.txt
D:\Junk> lockfile .\abc.txt
报告以下错误,表示他们希望找到我的主目录中指定的非限定文件。
Exception calling "Open" with "4" argument(s): "Could not find file 'C:\Users\SteveC.AFRICA\abc.txt'."
为什么会这样,我需要做些什么才能允许这样的脚本正确接受不合格的文件名作为参数?
答案 0 :(得分:1)
我认为,你混合了两件事:PowerShell路径和提供者(尤其是FileSystem
提供者)路径。这两件事情是不同的。
在PowerShell中,您可以随意创建驱动器,例如:
New-PSDrive -Name Win -PSProvider FileSystem -Root C:\Windows
之后你可以这样写:
Get-Content Win:\System.ini
当然,如果你写这样的东西:
[System.IO.File]::ReadAllLines('Win:\System.ini')
它会失败,因为ReadAllLines
对PowerShell及其Win
驱动器一无所知。在将PowerShell路径传递给文件系统API之前,需要将PowerShell路径转换为FileSystem
提供程序路径。可以使用Convert-Path
cmdlet:
Convert-Path Win:\System.ini
要轻松混合这些东西简化向PowerShell的过渡,FileSystem
提供程序会自动将文件系统驱动器映射到具有相同名称的PowerShell驱动器。所以,你通常不会注意到区别。但是对于相对路径而言,它的效果并不好,因为PowerShell current location and process current working directory are different things也是如此。