如何在Qt应用程序中使用OS X上的Login Items API?

时间:2014-11-13 03:16:07

标签: macos qt qmake

我希望我的应用程序在此列表中注册自己:

System Preferences -> Accounts -> (your name) -> Login Items

我了解到这样做的方法是使用LSSharedFileList.h进行一些函数调用来执行此操作。当我尝试这样做时:

#include <LSSharedFileList.h>

我得到了

fatal error: 'LSSharedFileList.h' file not found

搜索我的硬盘,我看到这个文件在这里:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LSSharedFileList.h

我是否需要在.pro文件中添加内容才能检测到此框架?我注意到如果我对构建的可执行文件执行otool -L,则链接这些框架:

/System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices (compatibility version 1.0.0, current version 48.0.0)
/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 62.0.0)

所以我有这个问题,不知道如何让构建系统找到头文件。

更有帮助的是,C ++ / Qt代码演示了如何将应用程序添加到“登录项目”列表,以及如何将其从列表中删除。

2 个答案:

答案 0 :(得分:0)

这是我到目前为止所得到的。我对那条硬编码的包含路径不满意。在.pro文件中:

INCLUDEPATH +=\
    /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers

然后安装Login Items条目的代码:

void installRunOnLoginHook(QString app_path) {
    QString app_name = QApplication::instance()->applicationName();
    QByteArray app_path_byte_array = app_path.toLocal8Bit();
    CFURLRef url = CFURLCreateFromFileSystemRepresentation(
        NULL, (const UInt8 *)app_path_byte_array.constData(), app_path_byte_array.size(), false);
    if (!url) {
        qWarning("unable to create CFURLRef");
        return;
    }
    LSSharedFileListRef login_items = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
    if (!login_items) {
        qWarning("unable to get login items");
        return;
    }

    CFArrayRef login_items_array = LSSharedFileListCopySnapshot(login_items, NULL);
    if (!login_items_array) {
        qWarning("unable to get login items array");
        CFRelease(login_items);
        return;
    }
    CFIndex count = CFArrayGetCount(login_items_array);
    CFStringRef url_string = CFURLGetString(url);
    CFURLRef item_url = NULL;
    for (CFIndex i = 0; i < count; i += 1) {
        LSSharedFileListItemRef item = (LSSharedFileListItemRef) CFArrayGetValueAtIndex(login_items_array, i);
        if (LSSharedFileListItemResolve(item, 0, &item_url, NULL) != 0) {
            qWarning("unable to resolve login item");
            CFRelease(login_items_array);
            CFRelease(login_items);
            return;
        }
        CFStringRef item_url_string = CFURLGetString(item_url);
        CFComparisonResult result = CFStringCompare(url_string, item_url_string, 0);
        CFRelease(item_url);
        if (result == kCFCompareEqualTo) {
            qWarning("found in login items already");
            CFRelease(login_items_array);
            CFRelease(login_items);
            return;
        }
    }

    LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(
        login_items, kLSSharedFileListItemLast, app_name.toCFString(), NULL, url, NULL, NULL);
    if (!item) {
        qWarning("Unable to add to login items");
        CFRelease(login_items_array);
        CFRelease(login_items);
        return;
    }
    CFRelease(item);
    CFRelease(login_items_array);
    CFRelease(login_items);
}

答案 1 :(得分:0)

尝试将以下内容放入.pro文件中:

macx {
    LIBS += -framework CoreServices
}

并添加到包含:

#include <CoreServices/CoreServices.h>