2012-03-11 74 views
4

我想啓動一個具有指定應用程序的文件,並且我希望啓動的程序立即成爲最前面的窗口。獲取最近啓動的應用程序的PID的最簡單方法

我知道我能做到這一點,如下所示:

[[NSWorkspace sharedWorkspace] openFile:fileName withApplication:appName]; 

然後,如果我可以得到啓動的應用程序的PID,然後我就可以做到這一點,使該應用程序最前面:

NSRunningApplication* app = [NSRunningApplication 
          runningApplicationWithProcessIdentifier: PID]; 
[app activateWithOptions: NSApplicationActivateAllWindows]; 

我有這樣的問題:什麼是最簡單,最快和最可靠的方式來獲得此應用程序的PID啓動後立即,所以我可以確保這個應用程序是最前面的?

這並不像第一眼那樣直截了當。例如,我需要一個進程名稱才能使用Carbon調用獲取PID,或通過可通過NSRunningApplication訪問的應用程序字典。但是,在一般情況下,我並不總是知道進程名是什麼,在某些情況下,進程名是一個空字符串。

此外,我可能已經運行了該應用程序的其他實例,並且我總是要獲取剛啓動的應用程序的特定實例的PID。

任何人都可以提出一個確定的,百分之百可靠的方法來獲取當前啓動的應用程序的PID?

或者,有沒有辦法用指定的應用程序啓動給定的文件,這樣應用程序總是以最前面的應用程序打開?

+0

我現在意識到,爲了使我的應用程序最前面的一個更可靠的方法是通過'SetFrontProcess(PSN)',其中 「PSN」 是的'ProcessSerialNumber'推出的應用程序。但我仍然有同樣的問題,因爲我需要一個進程名來檢索應用程序的'ProcessSerialNumber',並且存在與上面描述的有關如何獲取應用程序的PID相同的競爭條件。 – HippoMan 2012-03-11 19:31:00

回答

1

您是否嘗試過使用openFile的其他版本,這將允許您停用應用程序,從而允許新應用程序獲得焦點?

[[NSWorkspace sharedWorkspace] openFile:fileName withApplication:appName andDeactivate:YES]; 
+0

謝謝。是的,我已經嘗試過,但並不總是使新推出的應用程序成爲最前端的應用程序。看來我仍然需要調用'SetFrontProcess(&psn)'或它的等價物來確保在所有情況下都發生這種情況。 – HippoMan 2012-03-11 20:18:17

1

獲取應用程序的PID肯定不容易。這就是蘋果喜歡它的原因。那些厚臉皮的混蛋。

我不得不編寫這個野獸只是爲了從我知道正在運行的應用程序的完整路徑獲取PID ..嘿它比解析ps aux更容易!

對不起,如果有我自己的一些私人功能,但你可以瞭解我是如何去做的,以及我試圖避免的方式。

+ (NSUInteger)pidFromAppPath:(NSString*)path 
{ 
    NSRunningApplication *n = [[[NSWorkspace sharedWorkspace]runningApplications] filterOne:^BOOL(NSRunningApplication *runner) { 
     // optional: avoid totally faceless apps and "Desk Accesory"-type background apps. 
     if (runner.activationPolicy == NSApplicationActivationPolicyProhibited) || 
      runner.activationPolicy == NSApplicationActivationPolicyAccessory) 
      return nil; 
     id runPath = [runner valueForKeyPath:@"bundleURL"]; 
     NSString *runString = [runPath isKindOfClass:[NSString class]] 
          ? runPath 
          : [runPath isKindOfClass:NSURL.class] ? [((NSURL*)runPath) path] 
          : nil; 
    // optional: filter out Google Chrome's mockery of a once sane process-table 
    if (!runString 
      || [[runString lastPathComponent]contains:@"Google Chrome Helper.app"]  
      || [[runString lastPathComponent]contains:@"Google Chrome Worker.app"]  
      || [[runString lastPathComponent]contains:@"Google Chrome Renderer.app"]) 
    return nil; 
    return [runString isEqualToString:path] ?: nil; // This is where you actually test to see if it's the same as the string passed in, lol. 
    }]; 
    return n ? [n processIdentifier] : 11000; // if 11000 you messed up. 
} 

,瞧... NSLOG: Pid of /Applications/Utilities/Terminal.app is 46152

相關問題