Window becomes temporarily unresponsive during script

First off, I want to thank everyone here for their contributions. I needed to make an ASOC program recently and ran into about a dozen issues, all of which I was able to solve due to the resources here. Kudos!

At any rate, I have an issue now that I haven’t been able to find a solution to. I think it may be expected behaviour but in case I’m missing something I figured I should ask…

I have an app that basically takes a bunch of user-changeable options and upon clicking a “Start” button it runs a series of shell scripts to partition a USB drive in a specific fashion, copy over various files and software packages, and modify the partition table. In total there are up to about 30 shell scripts that run, depending on the options selected, most of which take only a second or so to complete. However there are 3 or 4 commands (mainly diskutil commands) which can take a while. While these scripts are running if I cmd-tab to another window and try to cmd-tab back the program’s window won’t come to the front until the current script is finished.

Is there any way around this behaviour?


The solution is to move from using do shell script and start using NSTask. It’s a bit more complex to set up – you need to use NSPipes and NSFileHandles – but it moves the shell command on to its own thread. This also make your app no longer susceptible to the escape-key bug.

Here’s a snippet from my book – you need to pass the path to the shell command, and the arguments as a list:

on runATask_withArguments_(thePath, theArgList)
-- create pipe for standard output, then get a file handle for reading from it
tell current application's NSPipe to set outPipe to pipe()
set outFileHandle to outPipe's fileHandleForReading()
-- create pipe for standard error, then get a file handle for reading from it
tell current application's NSPipe to set errPipe to pipe()
set errFileHandle to errPipe's fileHandleForReading()
-- make task and launch it
tell current application's NSTask to set theTask to alloc()'s init()
tell theTask
end tell
-- read standard output and standard error; result is data
tell outFileHandle to set outData to readDataToEndOfFile()
tell errFileHandle to set errData to readDataToEndOfFile()
-- make sure it's finisihed
tell theTask to waitUntilExit()
-- check if all went OK
if (theTask's terminationStatus()) as integer = 0 then
set didSucceed to true
set didSucceed to false
set outData to errData
end if
-- convert data to string
set theString to current application's NSString's alloc()'s initWithData_encoding_(outData,
current application's NSUTF8StringEncoding)
return {didSucceed, theString}
end runATask_withArguments_

Ok, thanks. I’ve written some code in the past in Obj-C that used NSTask so I’m somewhat familiar with the process. I had thought about it when I ran into this problem but I read a few older posts on here that seemed to suggest that there were issues calling NSTask from ASOC. I’m glad to hear that I can use it.

On a side note, after your mention of a book I google’d your name and found it. Looks great! I was looking for a good reference on the subject, so I’ll definitely be checking it out.

Thanks again!