【问题标题】:Enable, disable and start services programmatically in macOS在 macOS 中以编程方式启用、禁用和启动服务
【发布时间】:2018-01-18 07:41:31
【问题描述】:

我正在编写一个附带服务的程序。到目前为止,我所做的是创建一个帮助工具,它可以为我的进程运行提升的任务,并且可以通过 XPC 进行通信。

我的程序与服务捆绑在一起,我想使用帮助工具来安装和启动/停止此服务,以便我的程序可以在设置中有一个复选框“使用系统启动服务”。

我可以成功复制服务的 plist,但我找不到任何方法来以编程方式启用、禁用、启动或停止服务。我认为调用system("launchctl load /path/to/service.plist"); 的解决方案非常难看。在目标 C 中是否有任何机制来完成这项任务并获得成功或失败的结果?

【问题讨论】:

标签: objective-c macos service launchctl


【解决方案1】:

看起来有一个ServiceManagement API/Framework 用于加载 LaunchAgent。看起来SMJobBless 是唯一可用的方法

【讨论】:

    【解决方案2】:

    Apple 在launch.h 中有一个已弃用的用于启动、停止和启用已启动服务的 C API。 API 的源代码在他们的开源网站上:https://opensource.apple.com/source/launchd/launchd-442.26.2/liblaunch/

    下面是一些要求launchd启动LittleSnitchUIAgent服务的示例代码:

    #include <launch.h>
    
    int main(int argc, const char * argv[]) {
        const char *job = "at.obdev.LittleSnitchUIAgent";
        launch_data_t resp, msg;
        msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
        launch_data_dict_insert(
            msg, launch_data_new_string(job), LAUNCH_KEY_STARTJOB);
        resp = launch_msg(msg);
        launch_data_free(msg);
        return 0;
    }
    

    LittleSnitchUIAgent 不是指代——我是从本地服务列表中随机选择的。我在示例中留下了错误检查以使其保持直截了当。

    如果您还没有,我建议您仔细研究一下launchd man pagesDaemons and Services Programming Guide。 Launchd 可以启动您的进程以响应几乎任何事情:计时器、套接字连接、添加到系统的设备等等。您实际上很少需要管理自己的服务。我无法确认这一点,但我怀疑这就是他们弃用 API 的原因。

    【讨论】:

    • 非常感谢您提供此类信息。我现在确实做到了,通过打开与服务的 XPC 连接并 launchd 在传入连接时按需启动它。
    • 但是如何首先安装 .plist 呢?当我尝试将 .plist 文件从 ObjC 代码保存/复制/流式传输到 /Library/LaunchDaemon 时,它总是失败——即使我给我的应用程序“全盘访问”——以编程方式安装一个新的守护进程(在用户同意的情况下)当然)你必须至少复制一个.plist,然后以某种方式给它第一脚。该怎么做?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    相关资源
    最近更新 更多