Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Sparkle relaunch is failing - but I got it to work by adding a sleep in a Sparkle Updater delegate method. (timing issue) #273

Closed
brantmerryman opened this Issue · 3 comments

1 participant

@brantmerryman

Hi. I'm trying to use Sparkle to update my app.

The problem I was having was that when I would click "Install and Relaunch", the app exit and then the app would not restart. In my Application Support folder, I would see that finish_installation.app was there, an unzipped copy of my app was there, etc. This led me to believe that finish_installation.app was not properly launched.

In trying to figure out what was going on, I added some debug output using fprintf statements into the method:
- (void)installWithToolAndRelaunch:(BOOL)relaunch
in the file SUBasicUpdateDriver.m

I then compiled a Sparkle.framework and replaced the copy that was in my application bundle on my test machine. This time, the update worked and the debug output confirmed that all of my code was executed and things happened in the way I would want them to happen.

Next, I re-installed a fresh copy of my app and tried the update again. This time, again, the update did not succeed, and the same files were present in my Application Support folder.

I examined the installWithToolAndRelaunch method thinking I might want to rule out my fprintf calls introducing a timing issue. I noticed that right before NSTask is called, it calls the delegate method pathToRelaunchForUpdater:

I went to my delegate and added to this method a call usleep(200); to sleep for 200 microseconds.

I then recompiled my app. I made sure I was not using a modified version of Sparkle - but a release build of Sparkle that was made from an unmodified source from the default branch (the same copy as in the scenario where the update failed before), and tried the update again. This time the update succeeded and the app was re-launched - the same as
when I used the modified copy of Sparkle.

The result to this was that the update succeeded and my app was relaunched.

I notice that Sparkle is checking to make sure that the relaunch path exists in SUBasicUpdateDriver.m:338
if(!relaunchPath || ![[NSFileManager defaultManager] fileExistsAtPath:relaunchPath])

but this does not check to see if the actual executable in the bundle exists - merely that the folder finish_installation.app exists.

The only thing that makes sense to me is if the call on line 229,
[SUPlainInstaller copyPathWithAuthentication: relaunchPathToCopy overPath: targetPath temporaryName: nil error: &error]
is somehow an asynchronous copy operation. This doesn't make a lot of sense that it would be implemented this way, but I also don't understand why there would be a timing issue otherwise.

@brantmerryman

I'm getting an exception that says "launch path not accessible" when sparkle is attempting to launch finish_launching.app/Contents/MacOS/finish_launching.

I've checked and the path is good - just not launching. I tried modifying sparkle to move the NSTask call to a separate block - but no effect.

@brantmerryman brantmerryman reopened this
@brantmerryman

Oops. Didn't mean to close - just comment.

@brantmerryman

The problem was caused by my source code repository removing the execution permissions from the finish_launching executable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.