【问题标题】:How to validate a path string?如何验证路径字符串?
【发布时间】:2021-12-25 07:14:16
【问题描述】:

是否有任何函数可用于验证路径字符串?

https://docs.microsoft.com/en-us/dotnet/api/system.io.path?view=net-5.0 上的 Microsoft 文档说:“所有将路径作为参数的 Path 成员如果检测到无效的路径字符,就会抛出 ArgumentException。”

这应该抛出异常吗?

PS C:\src\t> [Io.Path]::GetFullPath('C:\sr<|c\t')
C:\sr<|c\t
PS C:\src\t> dotnet --version
5.0.301
PS C:\src\t> $PSVersionTable.PSVersion.ToString()
7.2.0

【问题讨论】:

  • 你可以滥用System.Uri.TryParse。如果返回true,则路径有效
  • if ((Test-Path -Path $yourPath) -eq $false) { Write-Output "Path is invalid";返回; }
  • Test-Path $path -IsValid 看起来很有希望,但当它为C:\sr&lt;|c\t 返回$true 时似乎被破坏了。
  • 有趣的是,Test-Path 'C:\sr&lt;|c\t' -IsValid 在 PS 5.1 上返回 $false,正如预期的那样。它似乎仅在 PS 7.x 中被破坏。
  • 在 PS 5.1 [IO.Path]::GetFullPath('C:\sr&lt;|c\t') 上确实会引发有关无效字符的异常。

标签: .net powershell .net-5


【解决方案1】:

由于自 PS 5.1 版以来行为显然发生了巨大变化,您可能不得不依赖自己的测试功能..

可能是这样的

function Test-IsValidPath {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [Alias('FullName')]
        [string]$Path,
        [switch]$MustExist
    )
    # test for invalid characters
    if ($Path.IndexOfAny([System.IO.Path]::GetInvalidPathChars()) -ge 0) { return $false }
    # if the path should exist
    if ($MustExist) { return (Test-Path -LiteralPath $Path) }
    $true
}

Test-IsValidPath 'C:\sr<|c\t'  # --> False

当然,你也可以创建一些会抛出异常的东西。关于这个,请参阅Which exception should be thrown for an invalid file name?

【讨论】:

  • 检查无效的路径字符是个好主意,@Theo。但是,我想知道是否还有更多需要考虑的事情?路径的长度呢?如果字符串是 Unicode 转换格式,这会起作用吗?还有其他失败的机会吗?
  • @lit 嗯.. 好点。这显然需要一些工作来处理这样的事情。
  • 这就是为什么我认为这是微软应该提供的工作。此外,这对FileSystem 提供者以外的“路径”是否有意义?注册表路径?
  • @lit 我同意,但请阅读github 上的最终答案“此问题已被标记为设计使然” 我认为不会固定..
【解决方案2】:

方法一:

我们有 ValidateScript 命令来验证 powershell 函数参数中的文件夹路径,如下所示:

function Validate-Path{
   param(
      [parameter(Mandatory)]
      [String]$Path
   )
   if(Test-Path $Path) {Write-Output "Path is valid"}
   else{Write-Output "Path is invalid"}
}

在 PowerShell 中输入此代码,然后按 Enter。 然后输入Validate-Path -Path &lt;give-your-folder-path&gt; 并回车,显示有效或无效路径。

我已执行此操作以验证我在 PowerShell 中的文件夹路径: 看看这张图片 (https://i.imgur.com/BHDg1HO.png)

方法二:

我还测试了zett42 评论,效果很好:

PS C:\Users\saiha> Test-Path "C:\Users\saiha\Documents"
True
PS C:\Users\saiha> Test-Path "C:\Users\saiha\Docs"
False
PS C:\Users\saiha>

还使用两种方法测试的问题中的给定路径:

PS C:\Users\saiha> Test-Path "C:\sr<|c\t"
Test-Path : Illegal characters in path.
At line:1 char:1
+ Test-Path "C:\sr<|c\t"
+ ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\sr<|c\t:String) [Test-Path], ArgumentException
    + FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.TestPathCommand

False
PS C:\Users\saiha> Test-Path "C:\src\t"
True
//User-Defined function
PS C:\Users\saiha> function Validate-Path{
>>    param(
>>       [parameter(Mandatory)]
>>       [String]$Path
>>    )
>>    if(Test-Path $Path) {Write-Output "Path is valid"}
>>    else{Write-Output "Path is invalid"}
>> }
PS C:\Users\saiha> Validate-Path -Path C:\src\t
Path is valid
PS C:\Users\saiha> Validate-Path -Path C:\sr<|c\t
c\t : The module 'c' could not be loaded. For more information, run 'Import-Module c'.
At line:1 char:28
+ Validate-Path -Path C:\sr<|c\t
+                            ~~~
    + CategoryInfo          : ObjectNotFound: (c\t:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CouldNotAutoLoadModule

PS C:\Users\saiha>

实用截图: https://i.imgur.com/ahTsSG3.png

如果我理解不同,请纠正我。

在方法 1 中,我创建了一个用户定义的函数并使用它进行测试,而在方法 2 中,Test-Path 是一个原生函数。但两者都进行相同的检查并给出正确的结果。

【讨论】:

  • 这会测试路径是否存在。我认为 OP 想测试一下,路径在语法上是否正确,即使它不存在。
  • 如果不存在则说明路径无效,同样通过给出不正确的路径地址进行测试
  • 仅在 PS 5 中。在 PS 7.2.0 中,我没有收到错误消息“路径中的非法字符”。
  • 遗憾的是,这不再适用于 PowerShell Core。见github.com/PowerShell/PowerShell/issues/16465
  • 是的,Test-Path 不会在这里抛出异常
猜你喜欢
  • 2012-10-08
  • 2022-01-06
  • 2011-12-08
  • 1970-01-01
  • 2016-03-19
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
相关资源
最近更新 更多