Restart from clone

Hey, Adam.

I set it up that way so that no documents get overwritten with unwanted changes (did that a few times testing this script,) also to prevent a bunch of untitled documents with unknown paths (that too.) I might be overthinking the problem.

I think I’ll provide both options with appropriate dialog warnings. Back to the drawing board.

Thanks,

j

Hi everybody.

I’ve made a few refinements. Most notably the computer will now restart after you finish with the “flurry of save dialogs.” I still might change the order of dialogs, and maybe add the option to do a simple restart intead of opening System Preferences.



--uBoot (working title)
--With thanks to Jacques, walter, Dominik, and Adam Bell.


-------------------------------------------------------------------------------------
--***REQUIREMENTS***

--Save as an application
-- Check "Enable access for assistive devices" in the Universal Acces pane of System Preferences.

-------------------------------------------------------------------------------------

-- Substitute your password within quotations for "adminPassword" to prevent a dialog requesting it.
set myPass to "adminPassword"

set quitLast to "Finder" & "uBoot"

set bootList to {}
tell application "Finder"
	repeat with possibleBoots in (get disks whose startup is false)
		if exists folder "System:Library:CoreServices" in possibleBoots then set end of bootList to name of possibleBoots
	end repeat
end tell

set preStopSpaces to ""
repeat 5 times
	set preStopSpaces to preStopSpaces & space
end repeat
set stopSpaces to preStopSpaces
----------
set presaveSpace to ""
repeat 14 times
	set presaveSpace to presaveSpace & space
end repeat
set saveSpace to presaveSpace
-------------------------------------------------------------------------------------

if bootList is {} then
	beep
	set checkVolumesResponse to display dialog "No other bootable volumes detected." & return & stopSpaces & "Mount a volume and try again." buttons {"Open System Preferences", "Okay"} with icon stop default button "Okay"
	set checkVolumesButton to button returned of checkVolumesResponse
	if checkVolumesButton is "Open System Preferences" then
		tell application "System Preferences"
			activate
			set current pane to pane "com.apple.preference.startupdisk"
		end tell
	end if
else
	-------------------------------------------------------------------------------------
	beep
	set forewarnedResponse to button returned of (display dialog return & saveSpace & "Save open documents first." & return & return buttons {"Cancel", "Review and Save", "Auto Save"} default button "Review and Save" with icon stop)
	if forewarnedResponse is "Review and Save" then
		delay 0.25
		beep
		display dialog space & space & "The computer will restart after" & return & space & " all changes are either saved or discarded. The computer will not restart if a save dialog is canceled." buttons {"Cancel", "Okay"} default button "Okay" with icon caution
		
		tell application "Finder" to close every window
		tell application "System Events"
			tell every process to set its visible to true
			
			set quitApp to name of every process whose name is not quitLast and visible is true
		end tell
		
		repeat with anApp in quitApp
			tell application anApp to quit
		end repeat
		set bootButtons to bootList
		if (count of bootButtons) < 3 then
			set bootVolume to button returned of (display dialog "Boot from which volume?" buttons (bootButtons & "Cancel") default button "Cancel" with icon caution)
			myChangeBoot(bootVolume, myPass, quitLast)
		else
			
			set bootVolume to (choose from list bootList)
			myChangeBoot(bootVolume, myPass, quitLast)
		end if
		-------------------------------------------------------------------------------------
	else
		
		if forewarnedResponse is "Auto Save" then
			delay 0.25
			beep
		end if
		
		set bootButtons to bootList
		if (count of bootButtons) < 3 then
			set bootVolume to button returned of (display dialog "Boot from which volume?" buttons (bootButtons & "Cancel") default button "Cancel" with icon caution)
			myChangeBoot(bootVolume, myPass, quitLast)
		else
			
			set bootVolume to (choose from list bootList)
			myChangeBoot(bootVolume, myPass, quitLast)
		end if
	end if
end if
-------------------------------------------------------------------------------------

on myChangeBoot(bootVolume, myPass, quitLast)
	
	tell application "Finder" to close every window
	tell application "System Events"
		tell every process to set its visible to true
		
		set quitApp to name of every process whose visible is true and name is not quitLast
	end tell
	repeat with anApp in quitApp
		tell application anApp to quit with saving
	end repeat
	
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	do shell script rebootCommand password myPass with administrator privileges
end myChangeBoot

--END




hi J,

nice script. i really like what you’ve done with it. didn’t think i’d need this but with all the additions i’m saving it for later use. fun discussion too.

Thanks waltr,

I’m learning a lot here.

I’m feeling pretty good about the script, but I’ve spent the weekend neglecting my wife and personal hygiene to revise it more - reordering dialogs, bypassing them if there are no open documents, adding a 30 second delay before restart for a last chance to cancel, etc. - I’m working out a few kinks right now. It should be ready soon.

j

Well, I’m pretty much finished, unless anybody has any more suggestions (or spots errors.) I’ll post both scripts.

First, I fleshed out the one that switches between 2 drives. It will now ask if you would like to boot from a different drive if a default is unavailable. There is also a 30 second window during which you can choose to cancel or continue immediately. I left out the saving features (I considered adding “quit with saving”) because my reason for this precludes the need.



--jBoot (working title)
--With thanks to Jacques, walter, Dominik, and Adam Bell.


-------------------------------------------------------------------------------------

--***REQUIREMENTS***
-------------------------

--Put a copy on each default drive.
-------------------------------------------------------------------------------------

--USER SPECIFIC VARIABLES--
-------------------------

set thePass to "adminPassword" --Replace "adminPassword" with your password to prevent a dialog requesting it.
----------
set oneDisk to "Macintosh HD" --Your HD here.
----------
set twoDisk to "jClone" --Your clone or other HD choice here.
----------

--OTHER VARIABLES--

tell application "Finder" to get name of startup disk
set startDisk to result
----------
set bootList to {}
tell application "Finder"
	repeat with possibleBoots in (get disks)
		if exists folder "System:Library:CoreServices" in possibleBoots then set end of bootList to name of possibleBoots
	end repeat
end tell
-------------------------------------------------------------------------------------

--BEGIN--
-------------------------
if startDisk is oneDisk then
	set restartDisk to twoDisk
	myRestart(restartDisk, thePass)
	
else if startDisk is twoDisk then
	set restartDisk to oneDisk
	myRestart(restartDisk, thePass)
	
end if
-------------------------------------------------------------------------------------

--AUTO RESTART--
-------------------------

on myRestart(restartDisk, thePass)
	-------------------------	
	tell application "Finder" to exists disk restartDisk
	if the result is true then
		delay 0.25
		beep
		display dialog return & "Restart from" & space & "\"" & restartDisk & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & restartDisk & "\"" & space & "to restart now" buttons {"Cancel", restartDisk} default button restartDisk with icon caution giving up after 30
		
		set restartCommand to "/usr/sbin/bless -folder '/Volumes/" & restartDisk & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
		
		
		do shell script restartCommand password thePass with administrator privileges
	end if
	
end myRestart
-------------------------------------------------------------------------------------

--CHOOSE ALTERNATE DISK IF AVAILABLE--
-------------------------

myFalseStart(restartDisk, bootList)
-------------------------
on myFalseStart(restartDisk, bootList)
	
	delay 0.25
	beep
	set chooseResponse to the button returned of (display dialog return & "\"" & restartDisk & "\"" & space & "is unavailable." & return & return & "Would you like to choose a different startup disk?" buttons {"No", "Yes"} default button "Yes" with icon stop)
	
	if chooseResponse is "No" then
		false
		
	else
		delay 0.25
		beep
		set bootButtons to bootList
		if (count of bootButtons) < 3 then
			set bootVolume to button returned of (display dialog "Boot from which volume?" buttons (bootButtons & "Cancel") default button "Cancel" with icon caution)
			myChangeBoot(bootVolume, thePass)
			
		else
			set bootVolume to (choose from list bootList)
			myChangeBoot(bootVolume, thePass)
		end if
	end if
	
end myFalseStart
-------------------------------------------------------------------------------------

--RESTART FROM ALTERNATE DISK--
-------------------------

on myChangeBoot(bootVolume, myPass, quitLast)
	
	beep
	display dialog return & "Restart from" & space & "\"" & restartDisk & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & restartDisk & "\"" & space & "to restart now" buttons {"Cancel", restartDisk} default button restartDisk with icon caution giving up after 30
	
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	do shell script rebootCommand password myPass with administrator privileges
end myChangeBoot

--END jBoot--
-------------------------------------------------------------------------------------

--5/22/2006
--capitalj

The second script was driving me crazy. I wanted a way to bypass the save dialogs if no documents seemed to be open (quit with saving was to be a safety measure) but it stopped working. I had an extreme bout of typos today, and by the time I sorted them out, the bypass was broken. I left it commented out where I last attempted to work it into the script. I’m working too hard to find the problem, so I’m letting it go for now.

EDIT: The fix is in the next post.



--uBoot (working title)
--With thanks to Jacques, walter, Dominik, and Adam Bell.


-------------------------------------------------------------------------------------
--***REQUIREMENTS***
-------------------------

--Save as an application
-- Check "Enable access for assistive devices" in the Universal Acces pane of System Preferences.

-------------------------------------------------------------------------------------
--VARIABLES--
-------------------------

-- Substitute "your password here" for "adminPassword" to prevent a dialog requesting it.
set myPass to "adminPassword"
-------------------------
set quitLast to "Finder" & "uBoot(maybe)"--EDIT: THIS IS ONE OF THE OFFENDING LINES
----------
set bootList to {}
tell application "Finder"
	repeat with possibleBoots in (get disks whose startup is false)
		if exists folder "System:Library:CoreServices" in possibleBoots then set end of bootList to name of possibleBoots
	end repeat
end tell
----------
set preStopSpaces to ""
repeat 5 times
	set preStopSpaces to preStopSpaces & space
end repeat
set stopSpaces to preStopSpaces
----------
set presaveSpace to ""
repeat 14 times
	set presaveSpace to presaveSpace & space
end repeat
set saveSpace to presaveSpace
----------
set preAutoSpace to ""
repeat 12 times
	set preAutoSpace to preAutoSpace & space
end repeat
set autoSpace to preAutoSpace

-------------------------------------------------------------------------------------
--BEGIN--
-------------------------

if bootList is {} then
	beep
	set checkVolumesResponse to display dialog "No other bootable volumes detected." & return & stopSpaces & "Mount a volume and try again." buttons {"Open System Preferences", "Okay"} with icon stop default button "Okay"
	set checkVolumesButton to button returned of checkVolumesResponse
	if checkVolumesButton is "Open System Preferences" then
		tell application "System Preferences"
			activate
			set current pane to pane "com.apple.preference.startupdisk"
		end tell
	end if
else
	----------
	
	set bootButtons to bootList
	if (count of bootButtons) < 3 then
		
		beep
		set bootVolume to button returned of (display dialog "Boot from which volume?" buttons (bootButtons & "Cancel") default button "Cancel" with icon caution)
		mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	else
		beep
		set bootVolume to (choose from list bootList)
		mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	end if
	
end if
-------------------------------------------------------------------------------------

on mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	-------------------------
	
	--tell application "System Events"
	--tell every process to set its visible to true
	--set theApps to (get name of every process whose visible is true)
	
	--end tell
	
	--if theApps is quitLast then
	--delay 0.25
	--beep
	--display dialog "There appear to be no unsaved" & return & "changes.\"AutoSave\" will be used" & return & autoSpace & "as a precaution" buttons {"Cancel", "Okay"} default button "Cancel" with icon caution
	--myQuickChange(bootVolume, myPass, quitLast)
	----------
	
	--else
	delay 0.25
	beep
	set forewarnedResponse to button returned of (display dialog return & saveSpace & "Review open documents?" & return & return buttons {"Cancel", "Review and Save", "Auto Save"} default button "Review and Save" with icon stop)
	
	if forewarnedResponse is "Review and Save" then
		
		delay 0.25
		beep
		display dialog space & space & "The computer will restart after" & return & space & " all changes are either saved or discarded. The computer will not restart if a save dialog is canceled." & return & return & "Canceling a document's save dialog will leave any remaining documents open." buttons {"Cancel", "Okay"} default button "Okay" with icon caution
		
		tell application "Finder" to close every window
		tell application "System Events"
			tell every process to set its visible to true
			
			set quitApp to name of every process whose visible is true and name is not quitLast
		end tell
		repeat with anApp in quitApp
			tell application anApp to quit
		end repeat
		
		myChangeBoot(bootVolume, myPass, quitLast)
		----------
		
	else
		if forewarnedResponse is "Auto Save" then
			myQuickChange(bootVolume, myPass, quitLast)
		end if
	end if
	--end if
	
end mySaveWarning
-------------------------------------------------------------------------------------

on myChangeBoot(bootVolume, myPass, quitLast)
	-------------------------
	
	delay 0.25
	beep
	display dialog return & "Restart from" & space & "\"" & bootVolume & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & bootVolume & "\"" & space & "to restart now" buttons {"Cancel", bootVolume} default button bootVolume with icon caution giving up after 30
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	
	do shell script rebootCommand password thePass with administrator privileges
	
end myChangeBoot
-------------------------------------------------------------------------------------

on myQuickChange(bootVolume, myPass, quitLast)
	-------------------------
	
	delay 0.25
	beep
	display dialog return & "Restart from" & space & "\"" & bootVolume & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & bootVolume & "\"" & space & "to restart now" buttons {"Cancel", bootVolume} default button bootVolume with icon caution giving up after 30
	----------
	
	tell application "Finder" to close every window
	tell application "System Events"
		tell every process to set its visible to true
		
		set quitApp to name of every process whose visible is true and name is not quitLast
	end tell
	repeat with anApp in quitApp
		tell application anApp to quit with saving
	end repeat
	----------
	
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	
	do shell script rebootCommand password thePass with administrator privileges
	
end myQuickChange

--END uBoot--
-------------------------------------------------------------------------------------

--5/22/2006
--capitalj





I’m fairly pleased with myself, considering that this was my first significant effort, and very gateful for all the help and advice offered. Now to finish remodeling the bathroom…

j

Hello everybody.

I just needed to step away for a bit. The answer was embarrasingly obvious:

EDIT: WELL, PARTLY OBVIOUS - I HAD TO REPOST THE FOLLOWING AFTER FINDING ANOTHER EMBARRASSINGLY OBVIOUS MISTAKE WHILE FIXING THE PREVIOUS ONE.



--uBoot (working title)
--With thanks to Jacques, walter, Dominik, and Adam Bell.


-------------------------------------------------------------------------------------
--***REQUIREMENTS***
-------------------------

--Save as application "uBoot"
-- Check "Enable access for assistive devices" in the Universal Acces pane of System Preferences.

-------------------------------------------------------------------------------------
--VARIABLES--
-------------------------

-- Substitute "your password here" for "adminPassword" to prevent a dialog requesting it.
set myPass to "adminPassword"
-------------------------
set quitLast to {"Finder", "uBoot"}
----------
set bootList to {}
tell application "Finder"
	repeat with possibleBoots in (get disks whose startup is false)
		if exists folder "System:Library:CoreServices" in possibleBoots then set end of bootList to name of possibleBoots
	end repeat
end tell
----------
set preStopSpaces to ""
repeat 5 times
	set preStopSpaces to preStopSpaces & space
end repeat
set stopSpaces to preStopSpaces
----------
set presaveSpace to ""
repeat 14 times
	set presaveSpace to presaveSpace & space
end repeat
set saveSpace to presaveSpace
----------
set preAutoSpace to ""
repeat 12 times
	set preAutoSpace to preAutoSpace & space
end repeat
set autoSpace to preAutoSpace

-------------------------------------------------------------------------------------
--BEGIN--
-------------------------

if bootList is {} then
	beep
	set checkVolumesResponse to display dialog "No other bootable volumes detected." & return & stopSpaces & "Mount a volume and try again." buttons {"Open System Preferences", "Okay"} with icon stop default button "Okay"
	set checkVolumesButton to button returned of checkVolumesResponse
	if checkVolumesButton is "Open System Preferences" then
		tell application "System Preferences"
			activate
			set current pane to pane "com.apple.preference.startupdisk"
		end tell
	end if
else
	----------
	
	set bootButtons to bootList
	if (count of bootButtons) < 3 then
		
		beep
		set bootVolume to button returned of (display dialog "Boot from which volume?" buttons (bootButtons & "Cancel") default button "Cancel" with icon caution)
		mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	else
		beep
		set bootVolume to (choose from list bootList)
		mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	end if
	
end if
-------------------------------------------------------------------------------------

on mySaveWarning(autoSpace, saveSpace, bootVolume, myPass, quitLast)
	-------------------------
	
	tell application "System Events"
		tell every process to set its visible to true
		set theApps to (get name of every process whose visible is true)
		
	end tell
	
	if theApps = quitLast then
		delay 0.25
		beep
		display dialog "There appear to be no unsaved" & return & "changes.\"AutoSave\" will be used" & return & autoSpace & "as a precaution" buttons {"Cancel", "Okay"} default button "Cancel" with icon caution
		
		myQuickChange(bootVolume, myPass, quitLast)
		
	else
		
		
		delay 0.25
		beep
		set forewarnedResponse to button returned of (display dialog return & saveSpace & "Review open documents?" & return & return buttons {"Cancel", "Review and Save", "Auto Save"} default button "Review and Save" with icon stop)
		
		if forewarnedResponse is "Review and Save" then
			
			tell application "System Events"
				tell every process to set its visible to true
				set theApps to (get name of every process whose visible is true)
			end tell
			
			if theApps = quitLast then
				delay 0.25
				beep
				display dialog "There appear to be no unsaved" & return & "changes.\"AutoSave\" will be used" & return & autoSpace & "as a precaution" buttons {"Cancel", "Okay"} default button "Cancel" with icon caution
				
				myQuickChange(bootVolume, myPass, quitLast)
				
				
			else
				
				delay 0.25
				beep
				display dialog space & space & "The computer will restart after" & return & space & " all changes are either saved or discarded. The computer will not restart if a save dialog is canceled." & return & return & "Canceling a document's save dialog will leave any remaining documents open." buttons {"Cancel", "Okay"} default button "Okay" with icon caution
				
				tell application "Finder" to close every window
				tell application "System Events"
					tell every process to set its visible to true
					set theApps to (get name of every process whose visible is true)
					if theApps ≠ quitLast then
						set quitApp to theApps
					end if
				end tell
				
				repeat with anApp in quitApp
					tell application anApp to quit
				end repeat
				
				
			end if
			myChangeBoot(bootVolume, myPass, quitLast)
			----------
		else
			if forewarnedResponse is "Auto Save" then
				myQuickChange(bootVolume, myPass, quitLast)
			end if
		end if
	end if
	
	
	
end mySaveWarning
-------------------------------------------------------------------------------------

on myChangeBoot(bootVolume, myPass, quitLast)
	-------------------------
	
	delay 0.25
	beep
	display dialog return & "Restart from" & space & "\"" & bootVolume & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & bootVolume & "\"" & space & "to restart now" buttons {"Cancel", bootVolume} default button bootVolume with icon caution giving up after 30
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	
	do shell script rebootCommand password thePass with administrator privileges
	
end myChangeBoot
-------------------------------------------------------------------------------------

on myQuickChange(bootVolume, myPass, quitLast)
	-------------------------
	
	delay 0.25
	beep
	display dialog return & "Restart from" & space & "\"" & bootVolume & "\"" & space & "in 30 seconds" & return & return & space & "Click" & space & "\"" & bootVolume & "\"" & space & "to restart now" buttons {"Cancel", bootVolume} default button bootVolume with icon caution giving up after 30
	----------
	
	tell application "Finder" to close every window
	tell application "System Events"
		tell every process to set its visible to true
		
		set quitApp to name of every process whose visible is true and name is not quitLast
	end tell
	repeat with anApp in quitApp
		tell application anApp to quit with saving
	end repeat
	----------
	
	set rebootCommand to "/usr/sbin/bless -folder '/Volumes/" & bootVolume & "/System/Library/CoreServices' -setOF;/sbin/shutdown -r now"
	
	do shell script rebootCommand password thePass with administrator privileges
	
end myQuickChange

--END uBoot--
-------------------------------------------------------------------------------------

--5/24/2006
--capitalj
--Phew!





If I figure out a way to check “my processes” for unfinished jobs I’ll add that, too.

j

Well, it was a relief to sort that out (see my previous post for my corrected script.)

Oh, and if anybody is still following this, it occurred to me that this:

set quitLast to {"Finder", "uBoot"}

should include applications that wouldn’t have open documents or changes to save. Once I come up with a broader list than , say, Mac Help, Dictionary, etc., I’ll work them in. Any suggestions would be appreciated.

And I made a spiffy icon for when I feel ready to offer my first freeware to the handful of people who might want it.

j