3

У меня есть скрипт, который я использовал очень часто, чтобы получить список файлов, а затем обработать их с помощью ffmpeg, начало которого читалось так:

$files = Get-ChildItem -Path "Season *\*" -Include *.mp4, *.mkv, *.m4v, *.avi, *.wmv, *.mpg -recurse
ForEach ($file in $files) {
  $parent = Split-Path $file -parent
  $origFile = $parent+'\'+$file.name
  $shortName = $file.name
....

Мне нужно было решение, чтобы иметь возможность использовать его в каталогах, которые были бы более гибкими, но избегали пересечений в каталоге (команда recurse будет проходить всегда вниз по пересечениям). Я нашел ответ здесь на суперпользователя, ссылка. Я обернул свой оригинальный скрипт в функцию и изменил 4-ю строку найденной здесь функции recurse, чтобы вызвать функцию и обработать файлы, как они были найдены.

function Recurse($path) {
  $fc = new-object -com scripting.filesystemobject
  $folder = $fc.getfolder($path)
  foreach ($i in $folder.files) {if ($i.name -match '.*\.(mp4|mkv|m4v|avi|wmv|mpg)$') {processFile($i)}}
  foreach ($i in $folder.subfolders) {
    $i | select Path        
    if ( (get-item $i.path).Attributes.ToString().Contains("ReparsePoint") -eq $false) {        
        Recurse($i.path)
    }
  }
}

function processFile($file) {
  $parent = Split-Path $file -parent
  $origFile = $parent+'\'+$file.name
  $shortName = $file.name
...

Но ясно, что функция recurse работает и генерирует список, но не создает файл-объект того же типа (?) что делает get-childitem. Операции типа «Split-Path $ file -parent» теперь не работают и вместо этого ничего не возвращают. Все, что я тестировал систему, чтобы указать, что переменная $ file является Системой._ComObject, который, как я предполагаю, установлен в первой команде функций recurse. Разве это не то, что возвращает Get-Childitem? Как мне заставить две функции работать вместе?

Я открыт для изменения либо исходного сценария, либо функции recurse так, чтобы исходная возможность (например, вызов Split-Path) снова работала.

1 ответ1

1

Система._ComObject, который, как я предполагаю, установлен в первой команде функций recurse. Разве это не то, что возвращает Get-Childitem?

Нет. COM-объекты, возвращаемые из объекта scripting.filesystem, являются объектами различных типов, чем те, которые вы получаете от поставщика файловой системы Powershell. Поставщик Powershell в основном состоит из .NET System.Объекты IO.FileInfo. Хотя может показаться, что они одинаковы, поскольку оба они имеют дело с операциями файловой системы, два типа объектов несовместимы.

Microsoft предоставляет документ, который предлагает преобразования.

Фактически ваш сценарий уже использует метод для их преобразования, в один из ваших условных операторов if. Бит, где вы делаете get-item $i.path . Этот фрагмент кода в основном преобразует один тип объекта в другой. У него есть Get-Item возвращающий объект файловой системы powershell, и для этого вы даете команде Get-Item полный путь, возвращаемый значением объекта scripting.filesystem в $i . Вы должны быть в состоянии сделать этот же трюк и в других местах.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .