2012-03-11 83 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

相关问题