2013-03-09 45 views
1

我正在向Mac程序中添加一項功能,以刪除其偏好.plist文件,然後使用有效的「出廠設置」重新啓動。然而,這個客戶對使用Sparkle等外部框架持懷疑態度。我在網上查看了示例代碼,但其中大部分似乎過於複雜(例如,向NSApplication添加一個類別)。另外,當你無法使用某些API從非GUI進程啓動GUI進程時,其中一些內容在Lion或更高版本中將無法工作。如何在不使用Sparkle的情況下重新啓動Mac GUI應用程序?

那麼有沒有一種簡單的方法讓Mac GUI應用程序自行重啓?

回答

8

對於山獅至少,叉/ EXEC的略微花哨的版本正常工作:

void RelaunchCurrentApp() 
{ 
    // Get the path to the current running app executable 
    NSBundle* mainBundle = [NSBundle mainBundle]; 
    NSString* executablePath = [mainBundle executablePath]; 
    const char* execPtr = [executablePath UTF8String]; 

#if ATEXIT_HANDLING_NEEDED 
    // Get the pid of the parent process 
    pid_t originalParentPid = getpid(); 

    // Fork a child process 
    pid_t pid = fork(); 
    if (pid != 0) // Parent process - exit so atexit() is called 
    { 
     exit(0); 
    } 

    // Now in the child process 

    // Wait for the parent to die. When it does, the parent pid changes. 
    while (getppid() == originalParentPid) 
    { 
     usleep(250 * 1000); // Wait .25 second 
    } 
#endif 

    // Do the relaunch 
    execl(execPtr, execPtr, NULL); 
} 

我碰到了一個疑難雜症,這就是重新推出的應用程序可以在後颱風。否則在執行本月初修復的問題:

[[NSApplication sharedApplication] activateIgnoringOtherApps : YES]; 
+2

什麼叫點'fork()的'在所有...爲什麼不直接去'EXECL()'? – mah 2013-03-09 00:57:25

+0

@mah:在大多數情況下,你是對的 - 叉子是不需要的,我相應地修改了答案。在我的情況下,一些atexit()代碼將父進程記錄在服務之外,並且以這種方式編寫代碼更方便。 – 2013-03-12 04:54:39

相關問題