2015-02-08 76 views
1

我正在处理基于EXIF数据重命名文件的脚本。关闭由.NET打开的文件句柄

param([string]$path) 

# http://blogs.technet.com/b/jamesone/archive/2007/07/13/exploring-photographic-exif-data-using-powershell-of-course.aspx 
[reflection.assembly]::loadfile("C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") | out-null 

function MakeString { 
    $s="" 
    for ($i=0 ; $i -le $args[0].value.length; $i ++) { 
     $s = $s + [char]$args[0].value[$i] 
    } 
    return $s 
} 

$files = Get-ChildItem -Path $path 
foreach ($file in $files) { 
    if ($file.Extension -ne ".jpg") { continue } 
    if ($file.Name -match "^(\d+)-(\d+)-(\d+)") { continue } 
    $exif = New-Object -TypeName system.drawing.bitmap -ArgumentList $file.FullName 
    $captureDate = MakeString $exif.GetPropertyItem(36867) 
    $captureDate = ($captureDate -replace ":", '-').Substring(0,19) 
    $newFilename = $captureDate + " " + $file.Name.Trim() 
    $file.Name + " -> " + $newFilename 
    $file |Rename-Item -NewName $newFilename 
} 

阅读从EXIF的日期是没有问题的,但是当我尝试重命名文件,我得到这个错误信息:

Rename-Item : The process cannot access the file because it is being used by another process. 
At D:\Norwegen\RenamePhotos.ps1:25 char:12 
+  $file |Rename-Item -NewName $newFilename 
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : WriteError: (D:\Norwegen\P1270465 (1920x1433).jpg:String) [Rename-Item], IOException 
    + FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand 

当我将procmon监控目录,我可以看到,该文件被关闭,而后期:

enter image description here

(看高亮线,它来自当前正在处理的文件的条目中间的较早文件)

那么,如何关闭该文件(可能仍然从EXIF读取打开),以便我可以重命名它?

我已经尝试关闭打开的文件:

Remove-Variable exif 
$file.Close() 
+1

['$ exif.Dispose()'](https://msdn.microsoft.com/en-US/library/system.drawing.bitmap_methods(V = VS.80)的.aspx)?虽然我不确定是否需要先调用Save()。 – 2015-02-08 18:12:11

回答

2

既然你只能从文件中读取,然后Dispose()调用应该做的伎俩。防爆。

foreach ($file in $files) { 
    if ($file.Extension -ne ".jpg") { continue } 
    if ($file.Name -match "^(\d+)-(\d+)-(\d+)") { continue } 
    $exif = New-Object -TypeName system.drawing.bitmap -ArgumentList $file.FullName 
    $captureDate = MakeString $exif.GetPropertyItem(36867) 

    #Disposing object as soon as possible 
    $exif.Dispose() 

    $captureDate = ($captureDate -replace ":", '-').Substring(0,19) 
    $newFilename = $captureDate + " " + $file.Name.Trim() 
    $file.Name + " -> " + $newFilename 
    $file |Rename-Item -NewName $newFilename 
}