连接特定类型的USB设备时,在Mac OS X上执行应用程序?

时间:2011-08-30 07:45:19

标签: macos usb

我需要实现Mac OS X应用程序。在我的应用程序中,我需要做两件事:

  1. 当特定类型的USB设备连接到系统时执行/打开应用程序。
  2. 从USB读取数据并将其上传到网络服务器。
  3. 我在Mac OS X开发方面没有太多经验。任何人都可以建议最好的文件来实现我的目标吗?

5 个答案:

答案 0 :(得分:23)

您可以使用launchd。试试man launchd和man launchd.plist。

似乎launchd可以使用USB事件,即使此功能记录不完整。 我找到了它:man xpc_set_event_stream_handler

这是一个例子。如果您将以下内容放入:~/Library/LaunchAgents/com.example.plist,您的程序应该在连接USB设备时启动。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.program</string>
    <key>ProgramArguments</key>
    <array>
    <string>/path/to/program</string>
    </array>
    <key>LaunchEvents</key>
    <dict>
            <key>com.apple.iokit.matching</key>
            <dict>
                    <key>com.apple.device-attach</key>
                    <dict>
                            <key>idProduct</key>
                            <integer>1234</integer>
                            <key>idVendor</key>
                            <integer>1337</integer>
                            <key>IOProviderClass</key>
                            <string>IOUSBDevice</string>
                            <key>IOMatchLaunchStream</key>
                            <true/>
                    </dict>
            </dict>
    </dict>
</dict>
</plist>

答案 1 :(得分:4)

根据设备类型,您可以将应用程序设置为通过iPhoto / Image Capture首选项自动打开。这仅适用于有限类别的设备,适用于计算机上已存在的应用程序,并且需要手动更改计算机上的首选项。

一般情况下,无法在CD / DVD / USB插件上自动运行任意应用程序,因为这是一个安全问题。

答案 2 :(得分:2)

Julien Pilet的回答对我有用。但是,为了让它在关闭应用程序时仍然连接设备时不会不断重新启动应用程序,我不得不:

  • 在我的应用代理xpc_set_event_stream_handler()中致电applicationDidFinishLaunching
    xpc_set_event_stream_handler("com.apple.iokit.matching", NULL, ^(xpc_object_t event) {     
        // Every event has the key XPC_EVENT_KEY_NAME set to a string that
        // is the name you gave the event in your launchd.plist.
        const char *name = xpc_dictionary_get_string(event, XPC_EVENT_KEY_NAME);

        // IOKit events have the IORegistryEntryNumber as a payload.
        uint64_t id = xpc_dictionary_get_uint64(event, "IOMatchLaunchServiceID");
        // Reconstruct the node you were interested in here using the IOKit
        // APIs.
        NSLog(@"Received event: %s: %llu",name,id);
    });
  • 将KeepAlive / false键/值对添加到plist
  • IOMatchLaunchStream/true键/值对添加到plist中的com.apple.device-attach dict。这是已经存在的IOMatchStream密钥的补充。不确定为什么必须在那里,我在这里找到了对它的引用:http://asciiwwdc.com/2013/sessions/702

另外,不要忘记使用

在系统中注册plist
launchctl load <path to your plist>

请注意,这似乎有效,但我从来没有从xpc流处理程序获取NSLog消息。

答案 3 :(得分:1)

您可以设置文件夹操作以在mount上运行命令。这将假设设备始终安装在同一位置,即/ Volumes / My \ Device / - 如果在安装之间添加或删除外围设备,则安装点可能会发生变化。您可以通过右键单击目录并单击“文件夹操作设置”来了解有关文件夹操作的更多信息。诀窍是确保设备始终安装在同一个地方。

或者,您可以使用launchd在mount上运行命令。 This link可能有所帮助。 Lingon是一个很棒的应用程序来编辑守护进程。

无论哪种方式,您都可以使用文件夹操作或守护程序来调用简单的脚本来获取设备的内容并将其上传到任何您喜欢的位置。

答案 4 :(得分:1)

这实际上取决于您正在查看的应用程序类型。

看起来似乎没有办法以类似的方式做到这一点 例如udev。

有争议的解决方案是:

  • 为您的设备编写自定义包装驱动程序
  • 使用libusb并让守护程序等待某个设备。

事实上,人们可以编写一个带有 libusb 的程序,它将根据给定的配置文件处理这类任务, 这也是跨平台的,因为 libusb 支持相当多的平台。