Просто подробно остановившись на ответе Джулии, так как мне пришлось перезапустить приложение по другой причине, кроме обновления, я посмотрел, как Sparkle это делает -
В последней версии (по состоянию на 11/2011) Sparkle имеется цель проекта finish_installation.app, которая включена в каталог ресурсов платформы Sparkle. Sparkle, работающий как часть хост-приложения, копирует finish_application в каталог application_support и использует запущенный для запуска своего двоичного исполняемого файла, например, передавая идентификатор хост-процесса и путь повторного запуска:
NSString *relaunchToolPath = [NSString stringWithFormat:@"%@/finish_installation.app/Contents/MacOS/finish_installation", tempDir];
[NSTask launchedTaskWithLaunchPath: relaunchToolPath arguments:[NSArray arrayWithObjects:pathToRelaunch, [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]], tempDir, relaunch ? @"1" : @"0", nil]];
[NSApp terminate:self];
Похоже, с этой функцией, когда родительский процесс завершает работу (?), Запускается родительский файл finish_application.
finish_installation ожидает исчезновения переданного идентификатора процесса, а также имеет начальную проверку, чтобы увидеть, запущен ли его родитель (pid = 1)
if(getppid() == 1)...
if (GetProcessForPID(parentprocessid, &psn) == procNotFound)...
затем запускает приложение с:
[[NSWorkspace sharedWorkspace] openFile: appPath];
Последний интересный тидбит: если установка занимает много времени, finish_installation превращается в процесс переднего плана, чтобы пользователь мог видеть, что какое-то приложение работает:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType( &psn, kProcessTransformToForegroundApplication );