howto: create windows shortcuts for exiftool.exe dynamically using vbs

Started by Silvio, September 29, 2011, 02:34:39 AM

Previous topic - Next topic

Silvio

Hello all together,

personally I'm using a set of shortcuts which execute exiftool.exe with different parameters. This allows me to simply drag & drop a selection of photos over one of these shortcuts to execute a predefined operation, e.g. adding a special keyword or adding copyright information.

As you can image it could be annoying to create more than 100 different shortcuts manually. Therefore I've created a VisualBasic-Script for this task. I hope this script will be useful for your own purposes:

The script itself should be named "etsccfg.vbs" and can be executed within Windows. Just copy the following vbs-code into the script-file:

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' This VBScript is related to the ExifTool. It creates some pre-defined and dynamic   ''
'' Windows-shortcuts for the "exiftool.exe" (which will execute this command using     ''
'' different arguments) to cover a lot of useful tasks related to metadata of photos   ''
'' (like adding keywords). These shortcuts will be created in folders within the main  ''
'' ExifTool-directory. - Simply drag and drop some photo-files over a shortcut to      ''
'' execute the related command.                                                        ''
'' This VBScript is not very flexible. It's designed to cover the way I'm working with ''
'' the metadata of my photo-files. However you may find this script helpful.           ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' Use the file $myDynConfFile (default = "etsccfg.dat" in the same directory like     ''
'' this VBScript-file) to define individual items. Allowed items and usage:            ''
'' - CRP is used for photographers (to add xmp:creator and xmp:rights). Usage:         ''
''   CRP :: <subfolder of "Creators"> :: <name>                                        ''
'' - KEY is used for keywords (to add xmp:subject) Usage:                              ''
''   KEY :: <subfolder of "Keywords"> :: <keyword>                                     ''
'' - LOC is used for locations (to add xmp:country|state|city|location and xmp:subject ''
''       if required, shortcuts are using subfolders of "Locations"). Usage:           ''
''   LOC :: Country  :: <country>  :: <keyword or "none">                              ''
''   LOC :: State    :: <state>    :: <keyword or "none">                              ''
''   LOC :: City     :: <city>     :: <keyword or "none">                              ''
''   LOC :: Location :: <location> :: <keyword or "none">                              ''
'' (lines starting with # are comments, :: is a delimiter for columns)                 ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

public myExifToolPath, objFSO, myDynConfFile, noLnkCreated

set objFSO    = CreateObject ("Scripting.FileSystemObject")
myDynConfFile = "etsccfg.dat"
noLnkCreated  = 0

'run unit
SetExifToolPath
ExifToolLnkStandard
ExifToolLnkDynamic

MsgBox noLnkCreated & " shortcuts created.", 0, "ExifTool Config"

set objFSO = nothing



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' removes "\" from the beginning and ending of a path to get a standard format        ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
function ConvertPath (thisPath)
  'remove "\" at the end of the path string
  if Right (thisPath, 1) = "\" then
    thisPath = Left (thisPath, Len (thisPath) - 1)
  end if
  'remove "\" at the start of the path string
  if Left (thisPath, 1) = "\" then
    thisPath = Right (thisPath, Len (thisPath) - 1)
  end if
  'return path
  ConvertPath = thisPath
end function



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' recursively creates folders of a path if they don't exist                           ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub CreatePath (thisPath)
  'check last folder of a path, if it doesn't exists recursively check parent folder
  if objFSO.FolderExists (thisPath) then exit sub
  if not objFSO.FolderExists (objFSO.GetParentFolderName(thisPath)) then call CreatePath (objFSO.GetParentFolderName(thisPath))
  'create folder
  objFSO.CreateFolder (thisPath)
end sub



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' user input to set the path to "exiftool.exe"                                        ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub SetExifToolPath ()
  'enter path to exiftool.exe via inputbox
  myExifToolPath = InputBox ("Full path to 'exiftool.exe':","ExifTool Config","C:\Temp")
  'abort if cancel button was activated
  if myExifToolPath = FALSE then WScript.Quit
  'abort if folder doesn't exist
  if not objFSO.FolderExists (myExifToolPath) then
    MsgBox "Path " & myExifToolPath & " doesn't exist!", 0, "ExifTool Config - Error"
    WScript.Quit
  end if
  'convert path
  myExifToolPath = ConvertPath (myExifToolPath)
  'show path
  MsgBox "Path: " & myExifToolPath, 0, "ExifTool Config"
end sub



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' creates a shortcut to "exiftool.exe" using additional arguments                     ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub CreateExifToolShortcut (thisLnkPath, thisLnkName, thisExifToolArgs)
  dim objShell, objShortCut, lnkFile
  'convert relative path of the shortcut
  thisLnkPath = ConvertPath (thisLnkPath)
  'create path of the shortcut file
  CreatePath (myExifToolPath & "\" & thisLnkPath)
  'create shortcut
  set objShell                 = WScript.CreateObject ("WScript.Shell")
  set objShortCut              = objShell.CreateShortcut (myExifToolPath & "\" & thisLnkPath & "\" & thisLnkName & ".lnk")
  'set shortcut properties
  objShortCut.TargetPath       = myExifToolPath & "\exiftool.exe "
  objShortCut.Arguments        = thisExifToolArgs
  objShortCut.WorkingDirectory = myExifToolPath
  'save shortcut
  objShortCut.Save
  noLnkCreated = noLnkCreated + 1
  set objShell    = nothing
  set objShortCut = nothing
end sub



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' creates standard exiftool shortcuts                                                 ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub ExifToolLnkStandard ()
  'create exiftool argument files used for some of the following shortcuts
  ExifToolArgCfg
  'create some standard shortcuts for the exiftool
  CreateExifToolShortcut "Basics" , "View Metadata"                         , "-k"
  CreateExifToolShortcut "Basics" , "Rename Photos (Timestamp to Filename)" , "-FileName<CreateDate -d %Y-%m-%d_%H-%M-%S.%%le -k"
  CreateExifToolShortcut "Special", "Filename to XMP Title"                 , "-@ default.cfg -filename>xmp:title"
  CreateExifToolShortcut "Special", "XMP State to XMP Keyword"              , "-@ default.cfg  -xmp:state+>xmp:subject"
  CreateExifToolShortcut "Special", "Delete IPTC and XMP Metadata"          , "-@ default.cfg  -XMP:All= -IPTC:All="
  CreateExifToolShortcut "Special", "Post-Processing (cfg)"                 , "-@ " & myExifToolPath & "\_cfg\postprocessing.cfg"
  CreateExifToolShortcut "Special", "Copyright Information (cfg)"           , "-@ " & myExifToolPath & "\_cfg\copyright.cfg"
end sub



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' create default exiftool argument files with .cfg as extension                       ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub ExifToolArgCfg ()
  dim file
  'create path
  CreatePath (myExifToolPath & "\_cfg")
  'create default.cfg
  set file   = objFSO.CreateTextFile (myExifToolPath & "\_cfg\default.cfg", TRUE)
  file.WriteLine("-k")
  file.WriteLine("-overwrite_original")
  file.Close
  set file   = nothing
  'copy default.cfg to exiftool root folder
  objFSO.CopyFile myExifToolPath & "\_cfg\default.cfg", myExifToolPath & "\"
  'create postprocessing.cfg
  set file   = objFSO.CreateTextFile (myExifToolPath & "\_cfg\postprocessing.cfg", TRUE)
  file.WriteLine("-k")
  file.WriteLine("-overwrite_original")
  file.WriteLine("")
  file.WriteLine("-d")
  file.WriteLine("%Y:%m:%d")
  file.WriteLine("-xmp:datecreated<$createdate")
  file.WriteLine("")
  file.WriteLine("-xmp:title>xmp:headline")
  file.WriteLine("-xmp:title>xmp:description")
  file.WriteLine("")
  file.WriteLine("-xmp:category=myCategory")
  file.WriteLine("")
  file.WriteLine("-XPTitle=")
  file.WriteLine("-XPComment=")
  file.WriteLine("-XPAuthor=")
  file.WriteLine("-XPKeywords=")
  file.WriteLine("-XPSubject=")
  file.Close
  set file   = nothing
  'create copyright.cfg
  set file   = objFSO.CreateTextFile (myExifToolPath & "\_cfg\copyright.cfg", TRUE)
  file.WriteLine("-xmp:instructions=You are not allowed to modify or distribute this photo without permission of the creator.")
  file.Close
  set file   = nothing
end sub



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'' create exiftool shortcuts with dynamic information stored in file myDynConfFile     ''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
sub ExifToolLnkDynamic ()
  dim file, currentLine, currentCols, i, args
  'open file for reading
  set file   = objFSO.OpenTextFile (myDynConfFile, 1)
  'read file line by line
  do while not file.AtEndOfStream
    currentLine = Trim (file.ReadLine)
    'check for comments
    if not Left (currentLine, 1) = "#" then
      'split string into substrings
      currentCols = Split (currentLine, "::")
      'trim each substring (column)
      for i = 0 to UBound (currentCols)
        currentCols(i) = Trim (currentCols(i))
      next
      'check for empty rows or rows which are not containing more than 2 columns
      if UBound (currentCols) = 2 then
        'create shortcut for creators (copyright)
        if currentCols(0) = "CRP" then
          args = "-@ default.cfg -d %Y -xmp:rights<""Copyright (c) $createdate " & currentCols(2) & ". All rights reserved."" -xmp:creator=""" & currentCols(2) & """"
          CreateExifToolShortcut "Creators\" & currentCols(1), "(c) " & currentCols(2), args
        end if
        'create shortcut for keywords
        if currentCols(0) = "KEY" then
          args = "-@ default.cfg -xmp:subject+=""" & currentCols(2) & """"
          CreateExifToolShortcut "Keywords\" & currentCols(1), currentCols(2), args
        end if
      elseif UBound (currentCols) = 3 then
        args = "none"
        'create shortcut for locations
        if currentCols(0) = "LOC" then
          'create 1 of 4 available location parameter
          select case currentCols(1)
            case "Country"  args = "-@ default.cfg -xmp:country="""  & currentCols(2) & """"
            case "State"    args = "-@ default.cfg -xmp:state="""    & currentCols(2) & """"
            case "City"     args = "-@ default.cfg -xmp:city="""     & currentCols(2) & """"
            case "Location" args = "-@ default.cfg -xmp:location=""" & currentCols(2) & """"
            case else MsgBox "Unknown location type (" & myDynConfFile & " > LOC)", 0, "ExifTool Config - Error"
          end select
          'create shortcut
          if not args = "none" then
            'add keyword to parameter if last column is not equal "none"
            if not currentCols(3) = "none" then
              args = args & " -xmp:subject+=""" & currentCols(3) & """"
            end if
            CreateExifToolShortcut "Locations\" & currentCols(1), currentCols(2), args
          end if
        end if
      end if
    end if
  loop
  'close file
  set file   = nothing
end sub


The 2nd file is a text-file named "etsccfg.dat" which contains all the definitions of the dynamic shortcuts. This file has to be in the same directory. The following content is an example:

# config-file for etsccfg.vbs to create dynamic shortcuts for the ExifTool
#
# use # for comments (whole line), :: is the delimiter for columns, <> are variable fields, | means OR within the <description> of a variable field
#
# CRP :: <subdirectory> :: <name of a photographer (creator, also used for copyright)>
# LOC :: <Country|State|City|Location> :: <value of the related xmp-field> :: <none|keyword>
# KEY :: <subdirectory> :: <keyword>

CRP :: Friends   :: Detlef Musterfreund
CRP :: Family    :: Karl Mustermann
CRP ::           :: Ilse Musterfrau

LOC :: Country   :: DE           :: Germany
LOC :: State     :: Bayern       :: none
LOC :: City      :: Muenchen     :: none
LOC :: Location  :: Isartor      :: none

KEY :: People    :: Silvio

KEY :: Theme     :: portrait
KEY :: Theme     :: architecture
KEY :: Theme     :: landscape

KEY :: Technique :: panorama
KEY :: Technique :: hdri

KEY :: Software  :: GIMP


Best regards,
Silvio