перезапустить мое приложение после автообновления? - PullRequest
3 голосов
/ 24 ноября 2010

В OS X, как я могу автоматически перезапустить свое приложение после удаления обновленной версии?

Я просмотрел некоторые из них, и launchd, кажется, вероятный способ сделать это, но я могуКажется, я об этом не думал.Кажется, я не могу найти ни одного хорошего ресурса, говорящего об этом.решение там.

Ответы [ 3 ]

3 голосов
/ 25 ноября 2010

Отдельный процесс - хорошее решение, посмотрите на платформу Sparkle (большинство приложений используют ее для автообновления), они также используют для этого автономного приложения - https://github.com/andymatuschak/Sparkle/blob/master/relaunch.m

2 голосов
/ 03 ноября 2011

Просто подробно остановившись на ответе Джулии, так как мне пришлось перезапустить приложение по другой причине, кроме обновления, я посмотрел, как 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 );
0 голосов
/ 10 июля 2018

Источник Блог

- (void) restartOurselves
    {
       //$N = argv[N]
       NSString *killArg1AndOpenArg2Script = @"kill -9 $1 \n open \"$2\"";

       //NSTask needs its arguments to be strings
       NSString *ourPID = [NSString stringWithFormat:@"%d",
                      [[NSProcessInfo processInfo] processIdentifier]];

       //this will be the path to the .app bundle,
       //not the executable inside it; exactly what `open` wants
       NSString * pathToUs = [[NSBundle mainBundle] bundlePath];

       NSArray *shArgs = [NSArray arrayWithObjects:@"-c", // -c tells sh to execute the next argument, passing it the remaining arguments.
                    killArg1AndOpenArg2Script,
                    @"", //$0 path to script (ignored)
                    ourPID, //$1 in restartScript
                    pathToUs, //$2 in the restartScript
                    nil];
       NSTask *restartTask = [NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:shArgs];
       [restartTask waitUntilExit]; //wait for killArg1AndOpenArg2Script to finish
       NSLog(@"*** ERROR: %@ should have been terminated, but we are still running", pathToUs);
       assert(!"We should not be running!");
    }
...