如何在PowerShell中没有任何预定义路径的情况下读取文件输入?

时间:2017-01-10 20:12:14

标签: windows file powershell io powershell-v2.0

我让用户提供输入txt文件作为参数-InputFile,我将其存储为$inputfile。但是当我尝试:

$reader = [System.IO.File]::OpenText("$inputfile")

PowerShell会自动将$inputfile路径附加到C:\ Windows \ system32。如何让PowerShell不假设路径前缀,因此如果用户所需的文件位于运行脚本的同一目录中,用户可以简单地传递-InputFile inputfile.txt?如果文件位于当前目录之外而不自动附加到C:\ Windows \ system32,我怎么能支持它们枚举一个完全不同的文件路径?

编辑:更改了变量" $ input" to" $ inputfile"根据你的建议。

4 个答案:

答案 0 :(得分:2)

首先:请注意$input是PowerShell中的特殊变量。有关详细信息,请参阅help about_Automatic_Variables。 (你没有在你的问题中提供足够的上下文来了解你是否正确使用了该变量。)

其次,.NET对象不假设与PowerShell具有相同的工作位置。他们不能,因为PowerShell除了文件系统驱动器之外还有“驱动器”。如果您确定自己在文件系统中,可以使用以下内容:

$fullPath = Join-Path (Get-Location).Path $inputFilenameFromUser

Cmdlet将使用工作地点。

答案 1 :(得分:1)

使用Resolve-Path解决将{/ 1}}传递给OpenText()之前/之后的路径:

$reader = [IO.File]::OpenText((Resolve-Path $InputFile).Path)

由于Resolve-Path在无法解析路径时会引发异常,因此您可能希望在try..catch块中运行此异常,例如像这样:

try {
    $path = (Resolve-Path $InputFile).Path
    $reader = [IO.File]::OpenText($path)
} catch [Management.Automation.ItemNotFoundException] {
    # cannot resolve path
} catch {
    # other error
}

或者,更好的是,验证参数:

[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path -LiteralPath $_ -Type Leaf})]
[string]$InputFile

答案 2 :(得分:0)

首先,不要将$input用作变量名;它是automatic variable,因此可能会被覆盖或产生意外结果。

第二,你确定"当前"目录不是C:\Windows\System32?工作目录不一定(通常也不是脚本所在的路径)。

如果您希望它始终使用脚本目录而不是工作目录,但只有当路径是相对的时,您才需要进行一些编码以确保(注意我将替换您的{{1} }变量,其中一个名为$input):

$Path

答案 3 :(得分:0)

首先,我想说明其他人所说的内容:你不应该使用$Input作为变量名,因为这是一个自动变量。

除此之外,我还想为您提供另一种选择。我个人保留了一个函数,当我希望人们指定一个输入文件时,它会弹出一个Open File对话框。

Function Get-FilePath{
[CmdletBinding()]
Param(
    [String]$Filter = "All Files (*.*)|*.*|Comma Seperated Values (*.csv)|*.csv|Text Files (*.txt)|*.txt",
    [String]$InitialDirectory = "C:\",
    [String]$Title)

    [void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $InitialDirectory
    $OpenFileDialog.filter = $Filter
    $OpenFileDialog.Title = $Title
    [void]$OpenFileDialog.ShowDialog()
    $OpenFileDialog.filename
}

然后你可以做一些像

这样的事情
$InputFilePath = Get-FilePath

这将为您提供文件的完整路径作为字符串。