I would like to know if it is possible to automate the following with thousands of disk image files.
-Open/mount each disk image in turn from a folder of disk images, reserving the disk image’s filename
-Save the contents of the disk image to a new temporary location
-Remove a particular file from the newly saved contents, in this case a .url location file
-Recreate the disk image file from the modified contents with the same name as the original
Any help anyone could provide in pointing me in the right direction would be greatly appreciated.
Thanks,
William Buckingham
Model: MacBook Pro
AppleScript: 1.10.6
Browser: Safari 416.13
Operating System: Mac OS X (10.4)
This is quick and dirty, but it shows how to do it (to test it, replace my reference to the file with your own):
set f to alias "path to a disk image file"
tell application "Finder"
set Was to name of disks
set CW to count of Was
open f -- unfortunately, doesn't seem to return a reference to the result
repeat -- wait for it to mount
set temp to name of disks
if (count of temp) > CW then exit repeat -- there it is
end repeat
set NewDisks to disks -- get it's coordinates
set tDMG to item -1 of NewDisks -- the last item in the list
set tFiles to files of entire contents of tDMG -- all the files (including nested in folders)
-- do stuff to tFiles
eject tDMG
end tell
The trick here, neglected in the script above is that after you’ve modified the contents of the .dmg you’ve mounted (by replacing a file) you’ll have to close it and then create a new one overwriting the old (which must be closed to over write it). I have not done this, but I think a do shell script using ‘hdiutil create’ will be required (see man: hdiutil).
Much Later
Here’s a script that does it:
set f to "ACB-G5_1:Downloads:ASTranslate.dmg"
-- obviously f has to be a file in a list of files you want to fix as part of a repeat loop.
set nF to alias "ACB-G5_1:Users:bellac:Desktop:MoveBrowser.scpt"
-- this must point to the replacement for the file to be changed
set tDMG to do shell script "hdiutil attach " & POSIX path of f -- mounts the image, returns path
set tName to word -1 of tDMG -- the name of the image
-- do the shuffle
tell application "Finder"
set af to files of disk tName as alias list -- assumes the one you want is at top level
set tmp to (make new folder at (path to desktop folder) with properties {name:tName}) as alias
duplicate af to tmp with replacing -- move the goodies
duplicate nF to tmp with replacing -- make the swap
end tell
tell application "Finder" to eject disk tName -- toss the mounted image
do shell script "hdiutil create -srcfolder " & POSIX path of tmp & " ~/Desktop/" & tName
-- this makes a new image with the contents and name of the temp folder
tell application "Finder" to delete tmp -- toss the temp folder
-- at this point you would move the .dmg from the desktop back where it was with replacing. I didn't do that with my test .dmg
What can I say but WOW!
I can’t wait to get to the files tomorrow and give it a test drive.
That’s excellent work.
Thanks so much for your efforts on this and I’ll come back with my final version once I get it implemented.
Kind regards,
William Buckingham
We’ll see about ‘excellent work’ right after it works for you. For heaven’s sake, try it with some duplicates!
Here’s an alternative that uses shell scripts instead of the Finder:
set f to "ACB-G5_1:Downloads:ASTranslate.dmg"
set fName to last word of f
set text item delimiters to ".dmg"
set tName to text item 1 of fName
set text item delimiters to ""
-- obviously f has to be a file in a list of files you want to fix as part of a repeat loop.
set nF to "ACB-G5_1:Users:bellac:Desktop:Resize.scpt"
-- this must point to the replacement for the file to be changed
do shell script "hdiutil attach " & POSIX path of f -- path to a disk image file
try
do shell script "ditto -rsrc /volumes/" & tName & " ~/Desktop/" & tName
end try
do shell script "ditto -rsrc " & POSIX path of nF & " ~/Desktop/" & tName
tell application "Finder" to eject disk tName
do shell script "hdiutil create -srcfolder " & " ~/Desktop/" & tName & " ~/Desktop/" & tName
tell application "Finder" to delete alias ((path to desktop folder as text) & tName)
-- at this point you would move the .dmg from the desktop back where it was with replacing. I didn't do that with my test .dmg
And with a bit more fiddling, the shell script portion can be set up as a string and then executed - shell script calls are slow.
Adam,
It took quite a bit of fiddling to get the script to do what I needed, but I have finally have a working version. The final product is actually an amalgam of Finder and shell scripts, but seems to work quickly on my test folder of ten disk images.
Your suggestions definitely pointed me in the right direction-especially determining the newly mounted volume name of the just opened disk image.
We use DropDMG to create our disk images with our company information/icon, so I was able to use that application to create the new image file.
Here’s the final script:
set orig_folder to (choose folder with prompt "Choose the Folder with the disk images in it:")
set dest_folder to (choose folder with prompt "Choose the Destination Folder into which the new disk images will be duplicated:")
set orig_folder2 to quoted form of POSIX path of orig_folder
set dest_folder to POSIX path of dest_folder
with timeout of 5000 seconds
tell application "Finder"
set theitemlist to paragraphs of (do shell script "find " & orig_folder2 & " -iname *.dmg | sed 's/\\(.*\\)\\/\\/\\(.*\\)/\\1" & "\\/" & "\\2/'")
end tell
end timeout
repeat with i from 1 to (the count of theitemlist)
set f to item i of theitemlist
set fPath to f as POSIX file as string
set fname to (do shell script "basename " & fPath)
set text item delimiters to ".dmg"
set tName to text item 1 of fname
set text item delimiters to ":"
set tName to last text item of tName
set text item delimiters to ""
tell application "Finder"
set Was to name of disks
set CW to count of Was
open alias fPath
repeat
set temp to name of disks
if (count of temp) > CW then exit repeat
end repeat
set NewDisks to disks
set tDMG to item -1 of NewDisks
set tDMGName to name of tDMG
set tFiles to entire contents of tDMG
set tmpFolder to (make new folder at (path to desktop folder) with properties {name:tDMGName}) as alias
duplicate tFiles to tmpFolder
set tmpPOSIX to quoted form of POSIX path of tmpFolder
try
do shell script "mv " & tmpPOSIX & "*.url ~/.Trash"
end try
eject tDMG
end tell
tell application "DropDMG"
create image from path POSIX path of tmpFolder base name tName with delete original
set newDMG to result
end tell
do shell script "mv " & newDMG & " " & dest_folder
end repeat
Hopefully our efforts will help someone else in a similar predicament in the future.
Thanks again for your assistance with this. Now I get to write something similar for .zip files for Windows versions-the fun never stops…
Regards,
William Buckingham