Hi guys,
Thought i'd share some code to help people getting the tool to run on windows.
The code I think is self explanatory.
- Without downloading the script...
powershell -nop -c "iex(New-Object Net.WebClient).DownloadString('https://exiftool.org/forum/index.php?action=dlattach;topic=8113.0;attach=2004')
- Downloading to disk...
Download file
Open "cmd"
"powershell -executionpolicy unrestricted -file get-exiftool.ps1"
- From powershell
Open powershell
Copy and paste the following
Function UnzipFile($argVar){
write-host $argVar
$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace($argVar)
Write-Host "Uncompressing the Zip file to $($targetondisk)" -ForegroundColor Cyan
$destination = $shell_app.namespace($targetondisk)
$destination.Copyhere($zip_file.items(), 0x10)
$shell_app = $null
}
$destDir = "$env:temp\" ; $targetondisk = "$env:USERPROFILE\apps\exiftool";
wget "http://www.exiftool.org/ver.txt" -OutFile "$targetondisk\ver.txt"
$ver = (gc "$targetondisk\ver.txt"); $url = "http://www.exiftool.org/exiftool-$ver.zip"; #thanks to Phil Harvey for the heads up
if (!(Test-Path $targetondisk)){New-Item -ItemType Directory -Force -Path $targetondisk | out-null};
$parsed = $url.Substring($url.LastIndexOf("/") + 1); $file = "$destDir$parsed";
if (!(Test-Path $file)){ start-bitstransfer -Destination $destDir $url };
if (!(Test-Path "$targetondisk\exiftool.exe")){ UnzipFile $file; Rename-Item "$targetondisk\exiftool(-k).exe" "$targetondisk\exiftool.exe" };
To run simply execute from command line:
%USERPROFILE%\apps\exiftool\exiftool.exe
Note: Tested on windows 10
Cheers
Thanks for the post.
You could make the script more useful if it could first download "http://www.exiftool.org/ver.txt" to get the current ExifTool version number, then use that to download/install the most recent version of ExifTool.
- Phil
Thanks Phil.
Firstly for this wonderful tool, and for the version check heads up. Updated script and post accordingly
Cheers
Nice.
Might I suggest replacing wget with invoke-webrequest, since that is the actual command being called? Powershell uses wget (and curl) as an alias for invoke-webrequest and is incompatible with actual wget command line options for those who actually use the real wget command.
I do want to thank you for this, careto. This script gave me the foundation for an auto-update script for exiftool, something I've wanted for a while. Powershell isn't my thing so my addition may be a bit raw, but I added a version check and removal of the files the script creates. Also made my previously mentioned change from wget to invoke-webrequest. It currently overwrites the previously installed exiftool, but I think a rename to backup the older version might be in order.
Function UnzipFile($argVar){
write-host $argVar
$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace($argVar)
Write-Host "Uncompressing the Zip file to $($targetondisk)" -ForegroundColor Cyan
$destination = $shell_app.namespace($targetondisk)
$destination.Copyhere($zip_file.items(), 0x10)
$shell_app = $null
}
$destDir = "$env:temp\" ; $targetondisk = "$env:USERPROFILE\apps\exiftool";
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
invoke-webrequest "http://www.exiftool.org/ver.txt" -OutFile "$targetondisk\ver.txt"
$ver = (gc "$targetondisk\ver.txt"); $url = "http://www.exiftool.org/exiftool-$ver.zip"; #thanks to Phil Harvey for the heads up
#version check
if (Test-Path "$targetondisk\exiftool.exe") {$currentVer = & "$targetondisk\exiftool.exe" "-ver" ; if ($currentVer -ge $ver) {Write-Host "Exiftool is up to date"; exit;} }
Write-Host "Updating exiftool from version $currentVer to $ver";
if (!(Test-Path $targetondisk)){New-Item -ItemType Directory -Force -Path $targetondisk | out-null};
$parsed = $url.Substring($url.LastIndexOf("/") + 1); $file = "$destDir$parsed";
if (!(Test-Path $file)){ start-bitstransfer -Destination $destDir $url };
UnzipFile $file; Move-Item -Force "$targetondisk\exiftool(-k).exe" "$targetondisk\exiftool.exe" ;
#cleanup
Remove-Item $file
Remove-Item $targetondisk\ver.txt
Minor update. My update script failed today with a "The request was aborted: Could not create SSL/TLS secure channel" error. It looks like www.sno.phy.queensu.ca has had a security update as following the answer in this StackOverflow answer (https://stackoverflow.com/questions/41618766/powershell-invoke-webrequest-fails-with-ssl-tls-secure-channel) fixed it. All that needs to be done was add the [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 line. I'll edit my post in include it.
love this script, which I used as basis for a function below
additionally, this function renames the previous exe with a version number for backup as suggested
if it does not find Exiftool in the path, it will download the latest version anyway
Function Update-ExifTool($exiftoolPath){
# init
$url_ver = "http://www.exiftool.org/ver.txt"
$exiftoolParent = Split-Path $exiftoolPath -Parent
$exiftoolExe = Split-Path $exiftoolPath -Leaf
$unzipped_filename = "$exiftoolParent\exiftool(-k).exe"
# get existing version information locally
if (test-path $exiftoolPath) { $existing_ver = ExifTool -Arguments "-ver" ; write-host "existing ExifTool version: $($existing_ver.Trim())" -f Green}
else { $existing_ver = $null ; write-host "ExifTool not found" -f Green ; if (!(Test-Path $exiftoolParent)) { New-Item $exiftoolParent -ItemType Directory | Out-Null } }
# get latest version information online
$latest_ver = invoke-webrequest $url_ver -UseBasicParsing | select -ExpandProperty Content
write-host "latest ExifTool version: $latest_ver" -f Green
# update if required
if ($latest_ver -gt $existing_ver) {
$download_url = "http://www.exiftool.org/exiftool-$latest_ver.zip"
$zip_filename = "$exiftoolParent\exiftool-$latest_ver.zip"
if ($existing_ver -ne $null){
$backup_filename = $exiftoolPath.Replace(".exe",".$($existing_ver.Trim())"+".old.exe")
if (!(Test-Path $backup_filename)) { Rename-Item -Path $exiftoolPath -NewName $backup_filename }
else { Remove-Item -Path $exiftoolPath -Force -Confirm:$false }
}
Start-BitsTransfer -Destination $exiftoolParent $download_url
$shell_app = new-object -com shell.application
$zip_obj = $shell_app.namespace($zip_filename)
$destination = $shell_app.namespace($exiftoolParent)
$destination.Copyhere($zip_obj.items(), 0x10)
$shell_app = $null
Remove-Item -Path $zip_filename -Force -Confirm:$false
Rename-Item -Path $unzipped_filename -NewName $exiftoolPath
Write-Host "updated to the latest version" -f Green
}
# no update required
else { Write-Host "using latest version no update required" -f Green }
}
Update-ExifTool -exiftoolPath "C:\Exiftool\Exiftool.exe"
This download and update script does not work anymore since ExifTool version 12.88 and the new (not so convenient anymore) package.
I assume, it's caused by the added _32 and _64 download file name suffixes.
And because of the more complicated structure of the package content.
Could you please have a look at it @Beehaus?
It looks like Beehaus hasn't been back to these forums since that post, so I doubt there will be a response.
Fixing the download part shouldn't be too hard. All that's needed is to insert _32/_64 after $latest_ver in the $download_url assignment. The trouble I'm having is that part needs to be separated from the $latest_ver variable somehow and I don't know enough about PS to be able to do it.
Extracting the from the zip might also be a problem due to the different structure. Again, I don't know enough about PS to fix.
...
Actually, the download part turns out to be an easy fix, with ChatGPT's help. This line
$download_url = "http://www.exiftool.org/exiftool-$latest_ver.zip"
should be changed to this (change 64 to 32 for 32 bit version)
$download_url = "http://www.exiftool.org/exiftool-$($latest_ver)_64.zip"
Moving the files to the proper place will be more difficult, as they are now in a directory in the archive. Also, renaming the older version as a backup is more difficult due to the new file structure.
Are you sure the two "$" are necessary? This looks just wrong to me.
- Phil
Quote from: Phil Harvey on July 14, 2024, 01:55:08 PMAre you sure the two "$" are necessary? This looks just wrong to me.
I know. But it is PowerShell and the writes just had to do things differently. That part now works on my version of the script using the
$($ setup.
Searching around, Microsoft shows the same thing here (https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-string-substitutions?view=powershell-7.4#delineation-with-braces) as the "alternate approach". I could have sworn that I had actually tried to use the curly braces as in the first example there, but the command failed. Maybe I should double check.
This is a slightly adapted version that should work:
Function Update-ExifTool($exiftoolPath){
# init
$url_ver = "http://www.exiftool.org/ver.txt"
# Get latest ExifTool version information online
$latest_ver = invoke-webrequest $url_ver -UseBasicParsing | select -ExpandProperty Content
write-host "Latest ExifTool version: $latest_ver" -f Green
# Get current ExifTool version from existing exiftool(-k).exe
$exiftoolParent = Split-Path $exiftoolPath -Parent
$exiftoolExe = Split-Path $exiftoolPath -Leaf
if (test-path $exiftoolPath) { $existing_ver = (Get-Item $exiftoolPath).VersionInfo.ProductVersion ; Write-Host "Existing ExifTool version: $($existing_ver)" -f Green}
else { $existing_ver = $null ; Write-Host "Local ExifTool not found at $exiftoolPath" -f Green }
# Check if latest online version is greater than local tool version
if ($latest_ver -gt $existing_ver) {
# Prepare Download if local tool version is smaller
$download_url = "http://www.exiftool.org/exiftool-$($latest_ver)_64.zip"
$zip_filename = "$exiftoolParent\exiftool-$($latest_ver)_64.zip"
# If local version was found
if ($existing_ver -ne $null) {
# Rename local directory with a suffix .old / Don't delete it
$backup_directoryname = $exiftoolParent + ".old"
if (!(Test-Path $backup_directoryname)) { Rename-Item -Path $exiftoolParent -NewName $backup_directoryname }
else
{ Write-Host "New name for old directory name $backup_directoryname already exists!" -f Red }
}
$destinationPath = Split-Path $exiftoolParent -Parent
# Prepare unzipping of freshly downloaded ExifTool-Archive
$zipFilePath = $destinationPath + "\exiftool-$($latest_ver)_64.zip"
# If the new destination path not yet exists, expand the ZIP archive to this folder
if (!(Test-Path $destinationPath\exiftool-$($latest_ver)_64)) {
# Download will only be executed if new destination path not yet exists
$currentTime = Get-Date -Format "HH:mm:ss"
Write-Host "$currentTime Download started for latest ExifTool version $latest_ver"
Start-BitsTransfer -Source $download_url -Destination $destinationPath
$currentTime = Get-Date -Format "HH:mm:ss"
Write-Host "$currentTime Download finished for latest ExifTool version $latest_ver"
# Exanding/Unpacking downloaded archive
Expand-Archive -Path $zipFilePath -DestinationPath $destinationPath
Write-Host "Extracted latest ExifTool version to $destinationPath\exiftool-$($latest_ver)_64" -f Green
Remove-Item -Path $zipFilePath -Force -Confirm:$false
Write-Host "Removed ExifTool $zipFilePath" -f Green
}
else
{ Write-Host "Destination directory $destinationPath\exiftool-$($latest_ver)_64 to unpack ExifTool already exists!" -f Red }
}
# no update required
else { Write-Host "Already using latest version $latest_ver - No update required" -f Green }
}
Update-ExifTool -exiftoolPath "C:\Temp\exiftool-13.10_64\exiftool(-k).exe"
There is still room for improvements, especially the last line that has to be modified everytime you run this PowerShell script to your existing path and version.
Maybe some kind of semi-automatically search for exiftool(-k).exe could help?
Feel free to modify it to your needs. No mention or permission is required from my side.