AppleScript to modify disk images...?

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