Datetime 文件日期元数据未正确显示

Datetime 文件日期元数据未正确显示,datetime,powershell,com,metadata,powershell-3.0,Datetime,Powershell,Com,Metadata,Powershell 3.0,我一直在尝试根据一些脚本编写Powershell脚本,这些脚本将从图片、视频和其他文件中读取元数据信息,然后根据其中一个日期对它们进行排序(如果日期可用,则当前获取的日期似乎是最佳选择,但日期修改适用于尚未更改的文件) 但是,当我运行脚本并提取信息时,我无法将字符串转换为日期。下面是我通过COM对象获取信息的大致方式: PS C:/> $objShell = New-Object -ComObject Shell.Application PS C:/> $objFolder = $o

我一直在尝试根据一些脚本编写Powershell脚本,这些脚本将从图片、视频和其他文件中读取元数据信息,然后根据其中一个日期对它们进行排序(如果日期可用,则当前获取的日期似乎是最佳选择,但日期修改适用于尚未更改的文件)

但是,当我运行脚本并提取信息时,我无法将字符串转换为日期。下面是我通过COM对象获取信息的大致方式:

PS C:/> $objShell = New-Object -ComObject Shell.Application
PS C:/> $objFolder = $objShell.namespace("C:\MyFolder")
PS C:/> $date = $objFolder.GetDetailsOf($objFolder.Items().Item(0), 12)
PS C:/> $date

7/‎10/‎2014 ‏‎7:09 PM
问题是我应该能够将其转换为datetime对象。例如,如果我手动将其写入it works:

PS C:/> [datetime]::ParseExact("7/10/2014 7:09 PM","g",$null)

Thursday, July 10, 2014 7:09:00 PM
但是如果我替换变量,它就不起作用了:

PS C:/> [datetime]::ParseExact($date,"g",$null)
Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."
At line:1 char:1
+ [datetime]::ParseExact($date,"g",$null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException
这很可能是因为变量实际上并不是我所看到的。事实上它更长。更不用说,如果遍历所有字符,可以看到额外长度的来源:

PS C:\> $date.Length #should be about 16, you'd think

22

PS C:\> $datearray = @()
PS C:\> for ($i = 0; $i -lt $date.Length; $i++) {$datearray += $date[$i]}
PS C:\> $datearray #i'm printing on one line and in quotes for ease of viewing

" 7/ 10/ 2014   7:09 PM"
如果您尝试使用联接或类似的方式打印数组,结果(对我来说,不知道发生了什么)是不可预测的。它将其视为有22个字符,但打印时忽略空格

我相信我可以花一点时间做一些字符串格式化,但我更希望能够解析给定的日期。发生什么事了


编辑:我能够轻松访问文件信息,尽管我不喜欢。我主要关注的是为什么我看到的结果不稳定,显示的长度与打印出来的长度不匹配,以及我如何处理它们。如果没有别的,我很好奇到底发生了什么。

当我运行代码时,
$objFolder.GetDetailsOf($objFolder.Items().Item(0),12)
我得到一个空字符串。我甚至更改了项目编号和正在查找的文件夹,以确保获得文件对象

但是,如果我这样做:

$objShell=新对象-ComObject Shell.Application
$objFolder=$objShell.namespace(“C:\Temp”)
$date=$objFolder.Items().Item(3).ModifyDate
我得到的值已经是
DateTime
对象


(上面的代码使用我的文件夹和项目索引)

当我运行代码时,
$objFolder.GetDetailsOf($objFolder.Items().item(0),12)
我得到一个空字符串。我甚至更改了项目编号和正在查找的文件夹,以确保获得文件对象

但是,如果我这样做:

$objShell=新对象-ComObject Shell.Application
$objFolder=$objShell.namespace(“C:\Temp”)
$date=$objFolder.Items().Item(3).ModifyDate
我得到的值已经是
DateTime
对象


(上面的代码使用了我的文件夹和项目索引)

我想知道额外的字符是什么(你没有提到已经看过了)。我将您的数组代码
$datearray+=$date[$I]
更新为
$datearray+=[int][char]$date[$I]
。截断的输出显示了两个奇怪的
8207
8206
,它们分别转换为从左到右的标记和从右到左的标记。它们通常与html相关联。不幸的是,我无法提供对他们存在的见解。好消息是它们很容易移除

$date = ($date -replace [char]8206) -replace [char]8207
[datetime]::ParseExact($date,"g",$null)
哪一个抵消了产出

Thursday, March 26, 2009 1:43:00 PM
希望这是一个有点接近你想要的。我试图寻找出现这些ascii码的原因,但没有发现任何有用的东西

其他读者的额外信息

我这样做是因为我不知道索引
12
是什么。因此,我制作了一个数组,其中包含所有可能的文件元数据的友好名称(288个条目!)。为了简洁起见,我找到了here字符串

有了这个,我就用我的一张图片来测试下面的代码

$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace("C:\Temp\")
0..$Meta.GetUpperBound(0)| %{
    $metaValue = $objFolder.GetDetailsOf($objFolder.Items().Item(2), $_)
    If ($metaValue) {Write-Host "$_ - $($meta[$_]) - $metaValue"}
    } 
$Meta
是我前面提到的数组。 代码将循环浏览我的文件的所有详细信息,由
项目(2)
指示,写入到包含值的所有文件详细信息的屏幕中。最后有一行将字符串转换为日期值。下面是脚本输出

0 - Name - IMG_0571.JPG
1 - Size - 3.12 MB
2 - Item type - JPEG image
3 - Date modified - 3/26/2009 3:34 PM
4 - Date created - 8/24/2014 5:19 PM
5 - Date accessed - 8/24/2014 5:19 PM
6 - Attributes - A
9 - Perceived type - Image
10 - Owner - TE_ST\Cameron
11 - Kind - Picture
12 - Date taken - ‎3/‎26/‎2009 ‏‎1:43 PM
19 - Rating - Unrated
30 - Camera model - Canon EOS DIGITAL REBEL XS
31 - Dimensions - ‪3888 x 2592‬
32 - Camera maker - Canon
53 - Computer - TE_ST (this computer)
155 - Filename - IMG_0571.JPG
160 - Bit depth - 24
161 - Horizontal resolution - ‎72 dpi
162 - Width - ‎3888 pixels
....output truncated....
247 - Program mode - Normal program
250 - White balance - Auto
269 - Sharing status - Not shared

我想知道额外的角色是什么(你不必说已经看过了)。我将您的数组代码
$datearray+=$date[$I]
更新为
$datearray+=[int][char]$date[$I]
。截断的输出显示了两个奇怪的
8207
8206
,它们分别转换为从左到右的标记和从右到左的标记。它们通常与html相关联。不幸的是,我无法提供对他们存在的见解。好消息是它们很容易移除

$date = ($date -replace [char]8206) -replace [char]8207
[datetime]::ParseExact($date,"g",$null)
哪一个抵消了产出

Thursday, March 26, 2009 1:43:00 PM
希望这是一个有点接近你想要的。我试图寻找出现这些ascii码的原因,但没有发现任何有用的东西

其他读者的额外信息

我这样做是因为我不知道索引
12
是什么。因此,我制作了一个数组,其中包含所有可能的文件元数据的友好名称(288个条目!)。为了简洁起见,我找到了here字符串

有了这个,我就用我的一张图片来测试下面的代码

$objShell = New-Object -ComObject Shell.Application
$objFolder = $objShell.namespace("C:\Temp\")
0..$Meta.GetUpperBound(0)| %{
    $metaValue = $objFolder.GetDetailsOf($objFolder.Items().Item(2), $_)
    If ($metaValue) {Write-Host "$_ - $($meta[$_]) - $metaValue"}
    } 
$Meta
是我前面提到的数组。 代码将循环浏览我的文件的所有详细信息,由
项目(2)
指示,写入到包含值的所有文件详细信息的屏幕中。最后有一行将字符串转换为日期值。下面是脚本输出

0 - Name - IMG_0571.JPG
1 - Size - 3.12 MB
2 - Item type - JPEG image
3 - Date modified - 3/26/2009 3:34 PM
4 - Date created - 8/24/2014 5:19 PM
5 - Date accessed - 8/24/2014 5:19 PM
6 - Attributes - A
9 - Perceived type - Image
10 - Owner - TE_ST\Cameron
11 - Kind - Picture
12 - Date taken - ‎3/‎26/‎2009 ‏‎1:43 PM
19 - Rating - Unrated
30 - Camera model - Canon EOS DIGITAL REBEL XS
31 - Dimensions - ‪3888 x 2592‬
32 - Camera maker - Canon
53 - Computer - TE_ST (this computer)
155 - Filename - IMG_0571.JPG
160 - Bit depth - 24
161 - Horizontal resolution - ‎72 dpi
162 - Width - ‎3888 pixels
....output truncated....
247 - Program mode - Normal program
250 - White balance - Auto
269 - Sharing status - Not shared

您为什么使用Shell.Application而不是依靠PowerShell查找修改日期?在很大程度上,这是因为我正在寻找一种方法来提取文件上的元数据,包括DateTake字段。看起来修改、创建和访问的日期也不是我想要的,因为它们不准确。创建的日期似乎是我从相机复制到计算机的日期,修改的日期最接近,但只有在我没有对文件做任何操作(例如旋转)的情况下,访问的日期似乎与创建的日期一致。通过我的搜索,找到图片上的exif数据或图片上的元数据的唯一方法