2010-11-30 121 views
3

我正在開發一個具有Objective-C守護程序的Cocoa GUI應用程序。守護進程由LaunchDaemon啓動,GUI使用每個用戶的loginItems啓動。從根帳戶啓動應用程序

當更新部署時,我需要更新守護進程,這很簡單,並更新GUI。我希望能夠退出GUI,替換應用程序,並在當前正在運行的每個用戶帳戶上重新啓動它。我想從守護進程中完成所有這些,當然這是以root身份運行的。

我該如何: 1)以root用戶身份退出,然後在另一個用戶界面重新啓動應用程序? 2)以root用戶身份退出,然後爲當前登錄的每個用戶重新啓動一個特定的loginItem?

我嘗試過搜索,並且有很多討論,包括similar question,但似乎沒有可用的工作解決方案。

任何幫助,非常感謝。

回答

3

所以我用一個支持請求與蘋果得到最好的答案,與一些在線調查相結合。

攻擊的基本計劃是讓每個GUI實例在守護進程告訴它時自行重啓。

首先,我讓守護程序替換GUI的包(.app文件夾)。您可以在應用程序仍在運行時執行此操作。這正是Apple支持幫助的地方。我仍然感到驚訝的是,一個應用程序可以在運行時被替換,但他們告訴我這樣做,那樣會好的。

然後我讓守護進程啓動了一個DistributedNotification到GUI並帶有一條消息來重啓它自己。爲了讓GUI能夠正確響應,我創建了restarter類,它將獲取它自己的pid和bundle路徑,然後我在內存中構建了一個shell腳本,它殺死了pid,等了10秒鐘,然後執行了一個shell「open bundlepath.app」重新啓動。

我用NSTask調用 「內存」 中的shell腳本,這真的只是一個@ 「殺%@;睡10;打開%@」,PID,bundlePath ....

工作得!

感謝您的建議!

0

在Apple的文檔中查找「授權服務」。

+0

謝謝,我已經看過「授權服務」,正如你所提到的,但它似乎是用來提升根權限。我已經在後臺以root用戶身份運行,需要從我的根特權後臺任務啓動用戶登錄會話中的應用程序。 – Dave 2010-12-01 14:31:37

3

我相信NSDistributedNotificationCenter應該爲此工作。請注意,使用NSDistributedNotificationCenter在不同用戶帳戶中的進程之間進行通信本身並不需要root權限。

爲了幫助用戶帳戶之間的協調,它可能有助於區分GUI應用程序和守護程序當前處於活動狀態和處於控制狀態的哪個實例以及哪些實例是被動的。您可以使用NSWorkspace的通知(NSWorkspaceSessionDidBecomeActiveNotification,NSWorkspaceSessionDidResignActiveNotification)來確定用戶何時在用戶帳戶之間切換,並讓您的實例相應地進行設置。

假設您的GUI應用程序和守護程序在3個不同的用戶帳戶中運行實例。例如,如果在活動用戶帳戶中想要開始更新過程,則可以使用NSDistributedNotificationCenter輕鬆地告知所有其他實例立即關閉。要做到這一點,你需要定義如下的內容。

在.h文件中,聲明你通知不同的名稱:

extern NSString * const MDShouldTerminateImmediatelyNotification; 
在(一)實現文件

,創建名稱,並設置等級可達感興趣由分佈式通知名字,等:

NSString * const MDShouldTerminateImmediatelyNotification = @"MDShouldTerminateImmediately"; 


- (id)init { 
    if (self = [super init]) { 
     [[NSDistributedNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(shouldTerminateImmediately:) 
     name:MDShouldTerminateImmediatelyNotification 
     object:nil]; 
    } 
    return self; 
} 

- (void)dealloc { 
    [[NSDistributedNotificationCenter defaultCenter] removeObserver:self]; 
    [super dealloc]; 
} 

- (void)shouldTerminateImmediately:(NSNotification *)notification { 
    if (ourInstanceIsInControl == NO) { 
    [NSApp terminate:nil]; 
    } 
} 

在將啓動更新過程中,你會做這樣的事情來發送通知類:

- (void)beginUpdate { 
    [[NSDistributedNotificationCenter defaultCenter] 
    postNotificationName:MDShouldTerminateImmediatelyNotification 
     object:[self description] // or just nil 
     userInfo:nil 
     options:NSNotificationDeliverImmediately | NSNotificationPostToAllSessions]; 
    // continue 

} 

這至少應該是一個開始一起工作,我想....

其實,如果你正在討論的root身份運行,做的所有用戶帳戶都一個單一的守護進程的實例,您可能需要考慮將該部分分解爲Launchd Agent類型進程(後臺進程,以用戶級別運行,每個用戶帳戶都有自己的實例)。

欲瞭解更多信息:

Technical Note TN2083 Daemons and Agents

Root and Login Sessions

Creating launchd Daemons and Agents

+0

謝謝你。現在我有很多閱讀資料!我正在使用分佈式對象進行通信。有一個守護程序實例,並且可能是每個用戶的GUI實例。我可以通過發送通知讓GUI退出,但這不是真正的問題。真正的問題是,一旦守護程序指示GUI退出並更新實際的GUI應用程序包,如何讓守護程序重新啓動GUI的所有實例而不打擾用戶? - 我正在閱讀你的鏈接,看看我能否在那裏找到一些東西。再次感謝。 – Dave 2010-12-01 17:15:11

相關問題