Cocoa:我能防止同一应用程序重复启动吗?

4
例如,用户将我的应用程序放在他/她的桌面上。然后他/她将其复制(而不是移动)到/Application文件夹中。
如果~/Desktop中的应用已经启动,我如何防止~/Application中的应用重复启动?有简单的方法吗?
或者,如果用户启动了/Application中的应用程序,我可以检测到预先启动的应用程序,然后立即切换到那个应用程序吗?

3
注册一个 Mach 端口。我一段时间前写了一个关于此的要点 https://gist.github.com/CodaFi/5639819 - CodaFi
我很惊讶,OS X居然在第一次启动的情况下会启动应用程序的第二个实例。 - cacau
3个回答

3
如何获取所有正在运行应用程序的列表并在您的应用程序检测到另一个实例已经在运行时立即退出?
您可以通过使用NSWorkspacerunningApplications获取所有活动应用程序的列表:
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSArray *allRunningApps = [ws runningApplications];

它将返回一个由NSRunningApplication实例组成的数组,所以您只需通过bundleIdentifier方法检查列表即可找到您的应用程序ID。

哈哈!实际上你已经解决了“检查重复”的部分。但是我还在研究“将前一个置于前面”的部分。我在这里找到了一个解决方案,但“-activateWithOptions”对我不起作用。 - Andrew Chang
我找到了另一个更适合我的问题的解决方案。但还是非常感谢你! - Andrew Chang

1

cacau的答案给了我实现目标的灵感。 这是我的代码(ARC):

- (BOOL)checkAppDuplicateAndBringToFrontWithBundle:(NSBundle *)bundle
{
    NSRunningApplication *app;
    NSArray *appArray;
    NSUInteger tmp;
    pid_t selfPid;
    BOOL ret = NO;

    selfPid = [[NSRunningApplication currentApplication] processIdentifier];
    appArray = [NSRunningApplication runningApplicationsWithBundleIdentifier:[bundle bundleIdentifier]];

    for (tmp = 0; tmp < [appArray count]; tmp++)
    {
        app = [appArray objectAtIndex:tmp];

        if ([app processIdentifier] == selfPid)
        {
            /* do nothing */
        }
        else
        {
            [[NSWorkspace sharedWorkspace] launchApplication:[[app bundleURL] path]];
            ret = YES;
        }
    }

    return ret;
}

它通过捆绑标识符检查应用程序是否重复。如果捆绑重复,则将所有其他应用程序带到前面并返回YES。收到YES后,应用程序可以终止自身。
然而,由于cacau给了我很大的帮助,我把这个问题的声望点给了他。谢谢!

谢谢!我无法弄清如何过滤掉当前正在运行的应用程序,也不知道为什么我没有想到检查pid。 - thecoolwinter

0

实际上,在NSTempDirectory内创建一个文件,检查它是否存在,如果存在,则退出,或者提供一种删除该文件的方法,这不是最简单的方法吗? 这对于在沙盒内外运行都适用。


听起来有点不正规,我们在Cocoa中有更好的可能性进行更复杂的检查。 - cacau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接