Как получить доступ к PSDrive из вызовов System.IO.File? - PullRequest
2 голосов
/ 06 ноября 2019

Я пишу командлет ac #, который копирует файлы из одного места в другое (аналогично rsync). Он даже поддерживает ToSession и FromSession.

Я бы хотел, чтобы он работал с PSDrives, которые используют провайдер файловой системы, но в настоящее время выдает ошибку из System.IO.File.GetAttributes ("psdrive: \ path")

Я бы очень хотел использовать вызовы из System.IO на PSDrive.

Как что-то вроде copy-item делает это?

Я выполнил поиск доступа к PSDrive из c # и не дал результатов.

Это эквивалентномой код

new-psdrive -name mydrive -psprovider filesystem  -root \\aserver\ashare -Credential domain\user
$attributes=[system.io.file]::GetAttributes("mydrive:\path\")

возвращает

Exception calling "GetAttributes" with "1" argument(s): "The given path's format is not supported."

1 Ответ

0 голосов
/ 06 ноября 2019

.NET ничего не знает о PowerShell дисках (и, как правило, также имеет другой рабочий каталог), поэтому преобразование в путь к файловой системе :

В коде PowerShell :

Используйте Convert-Path для преобразования пути на основе диска PowerShell в собственныйПуть файловой системы, который понимают типы .NET:

$attributes=[System.IO.File]::GetAttributes((Convert-Path "mydrive:\path\"))

По умолчанию (использование позиционных аргументов) и с -Path, Convert-Path выполняет разрешение по шаблону;чтобы подавить последнее, используйте параметр -LiteralPath.

Caveat : Convert-Path работает только с существующими путями. Снятие этого ограничения является предметом запроса этой функции на GitHub .


В коде C #:

В PSCmdlet -произведенные командлеты:

  • Используйте GetUnresolvedProviderPathFromPSPath() для перевода пути на основе PS-диска в путь на основе собственного диска [1] неразрешено , что означает, что, кроме перевода части диска:

    • существование пути не проверено (но имя диска должно существовать)
    • и no Разрешение подстановочного знака выполняется.
  • Использование GetResolvedProviderPathFromPSPath() до разрешение путь на основе PS-диска к собственному диску, которыйозначает, что, кроме перевода дисковой части:

    • разрешение подстановочного знака выполняется , получая потенциально несколько путей или даже ни одного.
    • компоненты буквального пути должен существовать .
  • Используйте метод CurrentProviderLocation() с идентификатором провайдера "FileSystem", чтобы получить путь к текущему местоположению файловой системы в виде System.Management.Automation.PathInfo экземпляр;свойство .Path этого экземпляра и метод .ToString() возвращают PS-форму пути;используйте свойство .ProviderPath, чтобы получить собственное представление.

Вот простой скомпилированный командлет, который выполняет оба метода:

# 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путь тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...