The idea for this script was born, when I found this post at Apple Support Forum:
Problems with winmail.dat attachments (https://discussions.apple.com/thread/3035481)
Since some month, I got more and more mails born in Outlook, that contained this ugly attachment named winmail.dat, that does not easily show it’s contents.
I tested tnef’s enough, but it did not always work and I love little helpers, that can be hidden behind one click or a keyboard shortcut. So I started to learn, what’s behind this “Microhard” and finally found Mark Simmon’s tool tnef.
Resources:
-
A good explanation about the TNEF format:
http://en.wikipedia.org/wiki/Transport_Neutral_Encapsulation_Format -
Mark Simmon’s tnef tool page:
http://sourceforge.net/projects/tnef
The script’s workflow:
- check wether a mail is selected in Mail.app
- check wether it has an attachment
- check wether it is winmail.dat
- let user choose a folder for the unpacked attachments
- check wether tnef tool is available
- save the winmail.dat to the given folder
- check for attachment files in winmail.dat
- show the filenames in a list
- unpack the contained files to the folder
If one of the checks fail, the script stops with a message.
Places the script checks for the tnef tool:
- the script’s bundle/Contents/Resources (in case it is an .app as provided at the link below)
- the given folder
- the Applications folder
The script works best, if at scriptstart already a mail containing a winmail.dat attachment is selected.
It is developed and tested on Mac OS X 10.6.7 with latest app software.
# Mail should be open and a mail selected
tell application "Mail"
# get the selected mail
activate
try
set m to (get first item of (get selected messages of first message viewer))
on error
display alert "Please select a Mail with winmail.dat Attachement"
return
end try
# check attachement for existence of winmail.dat
try
set a to (get first item of (get mail attachments of m))
on error
display alert "Selected Mail has no Attachement"
return
end try
if not (name of a as text) = "winmail.dat" then
display alert "Selected Mail has no winmail.dat attachement"
return
end if
set theOutputFolder to (choose folder) as text
# in this folder the file operations take place:
# temporary save winmail.dat and unpack contained files
# look for the tnef command:
# 1. in script bundle Contents/Resources
# 2. in working folder
# 3. in /Applications folder
set tnefPath to ((path to me) as text) & "Contents:Resources:tnef"
tell application "System Events"
try
set tnefInfo to properties of alias tnefPath
on error
set tnefInfo to ""
end try
end tell
if tnefInfo = "" then
set tnefPath to theOutputFolder & "tnef"
tell application "System Events"
try
set tnefInfo to properties of alias tnefPath
end try
end tell
end if
if tnefInfo = "" then
set tnefPath to ((path to applications folder) as text) & "tnef"
tell application "System Events"
try
set tnefInfo to properties of alias tnefPath
end try
end tell
if tnefInfo = "" then
display alert "Could not find tnef" & linefeed & ¬
"in the Script Bundle" & linefeed & "nor in " & theOutputFolder ¬
& linefeed & "nor in Applications folder"
return
end if
end if
# save an existing winmail.dat to the given folder
set theSavePath to POSIX path of (theOutputFolder & (id of m as text) & (name of a))
set theSavePathMsg to POSIX path of (theOutputFolder & (id of m as text) & "message")
do shell script "rm -f " & theSavePath
try
save a in theSavePath
on error
display alert "Could not save winmail.dat" & linefeed & "at " & theSavePath ¬
& linefeed & "Check: folder exists?"
return
end try
# prepare the tnef commands
# tnef is supposed to be in the given folder
# if not, change the commands
set cmd to "cd " & (POSIX path of theOutputFolder) & linefeed
set cmd1 to (POSIX path of tnefPath) & " -t -f " & theSavePath
set cmd2 to (POSIX path of tnefPath) & " -f " & theSavePath
# check for contained files
set ret to do shell script cmd & cmd1
if ret = "" then
display alert "There are no files in winmail.dat!"
return
end if
# just for fun: make a list of contained files
set my text item delimiters to "\r"
set theLines to text items of ret
set my text item delimiters to {""}
set my text item delimiters to "\t|\t"
set theFiles to {}
repeat with f in theLines
set end of theFiles to item 1 of (text items of f)
end repeat
set my text item delimiters to {""}
set ret to ¬
(choose from list theFiles with title "Files in Attachment" OK button name ¬
"Unpack" cancel button name "Cancel" with empty selection allowed)
if ret = false then # was it canceled?
do shell script "rm " & theSavePath
return
end if
# ret contains the selected files
# TODO: only unpack the selected files:
# unpack all and delete unwanted
# unpack the contained files
set ret to do shell script cmd & cmd2
do shell script "rm " & theSavePath
display alert "Files unpacked to folder" & linefeed & theOutputFolder
end tell
The script can be downloaded as zipped application bundle (https://files.me.com/rhocke/owcno8) containing the tnef tool ready to use. If you want to edit the script, just open winmail.app in the Applescript Editor.
I have this as app in the applications folder and a shortcut defined in the launcher Butler.
Feedback and ideas, how to improve the script (e.g. make it a droplet), are welcome.