Перекрестное копирование атрибутов DATE файла в PowerShell - PullRequest
1 голос
/ 08 апреля 2020

Usecase:

Есть ~ 4000 файлов, которые потеряли какое-либо отношение к дате, когда они были созданы, и в результате заказ полностью перепутался. После копирования всего каталога в Windows я увидел, в чем проблема: Android не хранит метку времени создания файла, а сортирует только по времени последнего изменения файла. Принимая во внимание, что «Время модификации» было «сломанным» атрибутом, из-за которого все мои файлы вышли из своего порядка: enter image description here

Отсюда я знаю, как действовать - просто скопируйте Атрибут «Дата» в «Дата изменения» для каждого отдельного файла, и я сделал бы это со следующим кодом:

$picts =  Get-ChildItem -force | Where-Object {! $_.PSIsContainer} 
foreach($object in $picts)
{
      $object.LastWriteTime=($object.Date)
}

Проблема в том, что $object.Date является неправильным аргументом, потому что Date похоже, не представляет атрибут «Дата» файла в Powershell.

Кто-нибудь знает, как правильно ChildItem представлять атрибуты «Дата» или / и «Дата получения»?

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Вы можете получить значение Date Taken программно, загрузив изображение как Image, а затем , получив соответствующее свойство :

function Get-DateTaken
{
  param(
    [ValidateNotNull()]
    [System.IO.FileInfo]$File
  )

  # Ensure System.Drawing assembly is available
  Add-Type -AssemblyName System.Drawing

  try{
    # Attempt to load image file from disk
    $img = [System.Drawing.Image]::FromFile($File.FullName)
    try{
      # Get the System.Photo.DateTaken property
      $dateTakenValue = $img.GetPropertyItem(36867).Value

      # Decode to string
      $dtString = [System.Text.Encoding]::UTF8.GetString($dateTakenValue)

      # Parse as DateTime, property string is in the format `yyyy:MM:dd HH:mm:ss\0`
      $dt = [datetime]::Now
      if([datetime]::TryParseExact($dtString.Trim(0), 'yyyy:MM:dd HH:mm:ss', $null, 'None', [ref]$dt)){
        # Success, return DateTime
        return $dt
      }
    }
    catch{
    }
  }
  finally{
    # Clean up
    $img.Dispose()
  }
}

Теперь, когда мы можем перевести FileInfo Ссылку на соответствующую дату мы можем сделать:

$picts =  Get-ChildItem -Force | Where-Object {! $_.PSIsContainer} 
foreach($object in $picts) {
  if(($DateTaken = Get-DateTaken $object)){
    $object.LastWriteTime = $DateTaken
  }
}
0 голосов
/ 08 апреля 2020

Я не импортировал изображения с телефона Android, так что это будет более общий ответ на то, как вы можете устранять неполадки, подобные этим.

Если вы берете произвольный файл в вашей коллекции с помощью Get -ChildItem вы можете увидеть все различные метаданные, которые он имеет, выполнив следующие действия:

$test = Get-ChildItem "Yourfile.jpg"
$test.LastWriteTime | Get-Member

Это покажет вам как тип объекта (в данном случае System.DateTime), а также даст вам список всех методов, которые вы можете использовать с ним. Если вы хотите понять, что такое $ object.Date в вашем примере, я бы использовал тот же подход и передал $ object.Date для Get-Member, чтобы увидеть, какой это тип объекта. Если они отличаются, вам придется преобразовать $ object.Date в System.DateTime, прежде чем вы сможете изменить дату изменения файла.

...