如何通过 System.IO.File 个调用访问 PSDrive?
How to access a PSDrive from System.IO.File calls?
我正在编写一个 c# cmdlet,它将文件从一个位置复制到另一个位置(类似于 rsync)。它甚至支持 ToSession 和 FromSession。
我希望它能与使用文件系统提供程序的 PSDrives 一起使用,但它目前从 System.IO.File.GetAttributes("psdrive:\path")
中抛出错误
我真的很想在 PSDrive 上使用来自 System.IO 的电话。
copy-item 之类的东西是如何做到这一点的?
我已经执行了从 C# 访问 PSDrives 的搜索,但没有返回任何结果。
这相当于我的代码
new-psdrive -name mydrive -psprovider filesystem -root \aserver\ashare -Credential domain\user
$attributes=[system.io.file]::GetAttributes("mydrive:\path\")
returns
Exception calling "GetAttributes" with "1" argument(s): "The given path's format is not supported."
.NET 对 PowerShell 驱动器 一无所知(通常也有不同的工作目录),所以 conversion 本地文件系统路径是必需的:
在 PowerShell 代码中:
使用 Convert-Path
将基于 PowerShell 驱动器的路径转换为 .NET 类型理解的本机文件系统路径:
$attributes=[System.IO.File]::GetAttributes((Convert-Path "mydrive:\path\"))
默认情况下(使用位置参数)和 -Path
,Convert-Path
执行通配符解析;要抑制后者,请使用 -LiteralPath
参数。
警告:Convert-Path
仅适用于 现有 路径。取消该限制是 this feature request on GitHub.
的主题
在 C# 代码中:
在 PSCmdlet
派生的 cmdlet 中:
使用 GetUnresolvedProviderPathFromPSPath()
将基于 PS 驱动器的路径转换为基于本机驱动器的路径[1] 未解决,这意味着,除了翻译驱动部分:
- 未验证路径是否存在(但驱动器名称必须存在)
- 和不执行通配符解析。
使用GetResolvedProviderPathFromPSPath()
来解析一个基于PS驱动器的路径到一个基于本机驱动器的路径,这意味着那,除了翻译驱动部分:
- 执行通配符解析,可能产生多个路径甚至none。
- 文字路径组件必须存在。
使用提供程序 ID "FileSystem"
的 CurrentProviderLocation()
方法获取当前文件系统位置的路径作为 System.Management.Automation.PathInfo
实例;该实例的 .Path
属性 和 .ToString()
方法 return 路径的 PS 形式;使用 .ProviderPath
属性 获取本机表示。
这是一个简单的临时编译的 cmdlet,它可以使用这两种方法:
# Compiles a Get-NativePath cmdlet and adds it to the session.
Add-Type @'
using System;
using System.Management.Automation;
[Cmdlet("Get", "NativePath")]
public class GetNativePathCommand : PSCmdlet {
[Parameter(Mandatory=true,Position=0)]
public string PSPath { get; set; }
protected override void ProcessRecord() {
WriteObject("Current directory:");
WriteObject(" PS form: " + CurrentProviderLocation("FileSystem"));
WriteObject(" Native form: " + CurrentProviderLocation("FileSystem").ProviderPath);
//
WriteObject("Path argument in native form:");
WriteObject(" Unresolved:");
WriteObject(" " + GetUnresolvedProviderPathFromPSPath(PSPath));
//
WriteObject(" Resolved:");
ProviderInfo pi;
foreach (var p in GetResolvedProviderPathFromPSPath(PSPath, out pi))
{
WriteObject(" " + p);
}
}
}
'@ -PassThru | % Assembly | Import-Module
您可以按如下方式测试:
# Create a foo: drive whose root is the current directory.
$null = New-PSDrive foo filesystem .
# Change to foo:
Push-Location foo:\
# Pass a wildcard path based on the new drive to the cmdlet
# and have it translated to a native path, both unresolved and resolved;
# also print the current directory, both in PS form and in native form.
Get-NativePath foo:\*.txt
如果您的当前目录是 C:\Temp
并且它恰好包含文本文件 a.txt
和 b.txt
,您将看到以下输出:
Current directory:
PS form: foo:\
Native form: C:\Temp\
Path argument in native form:
Unresolved:
C:\Temp\*.txt
Resolved:
C:\Temp\a.txt
C:\Temp\b.txt
[1] 如果在输入路径中引用的 PS 驱动器(使用 New-PSDrive
创建)是根据 UNC 路径,生成的本机路径也将是 UNC 路径。
我正在编写一个 c# cmdlet,它将文件从一个位置复制到另一个位置(类似于 rsync)。它甚至支持 ToSession 和 FromSession。
我希望它能与使用文件系统提供程序的 PSDrives 一起使用,但它目前从 System.IO.File.GetAttributes("psdrive:\path")
中抛出错误我真的很想在 PSDrive 上使用来自 System.IO 的电话。
copy-item 之类的东西是如何做到这一点的?
我已经执行了从 C# 访问 PSDrives 的搜索,但没有返回任何结果。
这相当于我的代码
new-psdrive -name mydrive -psprovider filesystem -root \aserver\ashare -Credential domain\user
$attributes=[system.io.file]::GetAttributes("mydrive:\path\")
returns
Exception calling "GetAttributes" with "1" argument(s): "The given path's format is not supported."
.NET 对 PowerShell 驱动器 一无所知(通常也有不同的工作目录),所以 conversion 本地文件系统路径是必需的:
在 PowerShell 代码中:
使用 Convert-Path
将基于 PowerShell 驱动器的路径转换为 .NET 类型理解的本机文件系统路径:
$attributes=[System.IO.File]::GetAttributes((Convert-Path "mydrive:\path\"))
默认情况下(使用位置参数)和 -Path
,Convert-Path
执行通配符解析;要抑制后者,请使用 -LiteralPath
参数。
警告:Convert-Path
仅适用于 现有 路径。取消该限制是 this feature request on GitHub.
在 C# 代码中:
在 PSCmdlet
派生的 cmdlet 中:
使用
GetUnresolvedProviderPathFromPSPath()
将基于 PS 驱动器的路径转换为基于本机驱动器的路径[1] 未解决,这意味着,除了翻译驱动部分:- 未验证路径是否存在(但驱动器名称必须存在)
- 和不执行通配符解析。
使用
GetResolvedProviderPathFromPSPath()
来解析一个基于PS驱动器的路径到一个基于本机驱动器的路径,这意味着那,除了翻译驱动部分:- 执行通配符解析,可能产生多个路径甚至none。
- 文字路径组件必须存在。
使用提供程序 ID
"FileSystem"
的CurrentProviderLocation()
方法获取当前文件系统位置的路径作为System.Management.Automation.PathInfo
实例;该实例的.Path
属性 和.ToString()
方法 return 路径的 PS 形式;使用.ProviderPath
属性 获取本机表示。
这是一个简单的临时编译的 cmdlet,它可以使用这两种方法:
# Compiles a Get-NativePath cmdlet and adds it to the session.
Add-Type @'
using System;
using System.Management.Automation;
[Cmdlet("Get", "NativePath")]
public class GetNativePathCommand : PSCmdlet {
[Parameter(Mandatory=true,Position=0)]
public string PSPath { get; set; }
protected override void ProcessRecord() {
WriteObject("Current directory:");
WriteObject(" PS form: " + CurrentProviderLocation("FileSystem"));
WriteObject(" Native form: " + CurrentProviderLocation("FileSystem").ProviderPath);
//
WriteObject("Path argument in native form:");
WriteObject(" Unresolved:");
WriteObject(" " + GetUnresolvedProviderPathFromPSPath(PSPath));
//
WriteObject(" Resolved:");
ProviderInfo pi;
foreach (var p in GetResolvedProviderPathFromPSPath(PSPath, out pi))
{
WriteObject(" " + p);
}
}
}
'@ -PassThru | % Assembly | Import-Module
您可以按如下方式测试:
# Create a foo: drive whose root is the current directory.
$null = New-PSDrive foo filesystem .
# Change to foo:
Push-Location foo:\
# Pass a wildcard path based on the new drive to the cmdlet
# and have it translated to a native path, both unresolved and resolved;
# also print the current directory, both in PS form and in native form.
Get-NativePath foo:\*.txt
如果您的当前目录是 C:\Temp
并且它恰好包含文本文件 a.txt
和 b.txt
,您将看到以下输出:
Current directory:
PS form: foo:\
Native form: C:\Temp\
Path argument in native form:
Unresolved:
C:\Temp\*.txt
Resolved:
C:\Temp\a.txt
C:\Temp\b.txt
[1] 如果在输入路径中引用的 PS 驱动器(使用 New-PSDrive
创建)是根据 UNC 路径,生成的本机路径也将是 UNC 路径。