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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7240117/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 08:22:12  来源:igfitidea点击:

Execute an application on Mac OS X when a particular type of USB device is connected?

macosusb

提问by ChandraSekhar

I need to implement a Mac OS X application. In my application I need to do two things:

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

  1. Execute / Open an application when a particular type of USB device is connected to the system.
  2. Read the data from USB and upload it to a web server.
  1. 当特定类型的 USB 设备连接到系统时执行/打开应用程序。
  2. 从 USB 读取数据并将其上传到 Web 服务器。

I do not have much experience in Mac OS X development. Can anyone please suggest the best documents to reach my goals?

我在 Mac OS X 开发方面没有太多经验。任何人都可以建议最好的文件来实现我的目标吗?

采纳答案by errordeveloper

It really depends on what sort of application you are looking at.

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

It does look like there is no way to do it in a similar fashion to udev for example.

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

To controversial solutions would be:

有争议的解决方案是:

  • Write a custom wrapper driver for your device
  • Use libusband have a daemon to wait for certain device.
  • 为您的设备编写自定义包装器驱动程序
  • 使用libusb并有一个守护进程来等待某个设备。

And in fact one could write a program with libusbwhich will handle this sort of tasks according to a given config file, that would be also cross-platform since libusbsupports quite a few platforms.

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

回答by Julien Pilet

You can use launchd. Try man launchd and man launchd.plist.

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

It seems that launchd can work with USB events, even though this feature is poorly documented. I found it on: man xpc_set_event_stream_handler

似乎 launchd 可以处理 USB 事件,尽管此功能的文档很少。我在以下位置找到它:man xpc_set_event_stream_handler

Here's an example. If you put the following into: ~/Library/LaunchAgents/com.example.plist, your program should start when a USB device is connected.

这是一个例子。如果您将以下内容放入: ~/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>

回答by blahdiblah

Depending on the type of device you might able to set an application to open automatically via the iPhoto/Image Capture preferences. That will work only for a limited class of devices, for an application already present on the computer and will require changing the preferences on the computer manually.

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

In general, there's no way to automatically run arbitrary applications on CD/DVD/USB insert because it's a security problem.

一般来说,没有办法在 CD/DVD/USB 插入上自动运行任意应用程序,因为这是一个安全问题。

回答by BillyRayCyrus

Julien Pilet's answer worked for me. However, to get it to not constantly relaunch the app when the device is still connected when closing the app, I had to:

Julien Pilet 的回答对我有用。但是,为了在关闭应用程序时设备仍处于连接状态时不不断地重新启动应用程序,我必须:

  • call xpc_set_event_stream_handler()in my app delegate applicationDidFinishLaunching:
  • 调用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);
    });
  • add KeepAlive/false key/value pair to the plist
  • add IOMatchLaunchStream/truekey/value pair to the com.apple.device-attachdict in the plist. This is in addition to the IOMatchStreamkey already there. Not sure why that has to be there, I found a reference to it here: http://asciiwwdc.com/2013/sessions/702
  • 将 KeepAlive/false 键/值对添加到 plist
  • IOMatchLaunchStream/true键/值对添加到com.apple.device-attachplist 中的dict。这是对IOMatchStream已经存在的密钥的补充。不知道为什么必须在那里,我在这里找到了对它的引用:http: //asciiwwdc.com/2013/sessions/702

Also don't forget to register the plist with the system using

也不要忘记使用系统向系统注册 plist

launchctl load <path to your plist>

Note that this seems to work, but I never get the NSLog message from the xpc stream handler.

请注意,这似乎有效,但我从未从 xpc 流处理程序中收到 NSLog 消息。

回答by rick

You may be able to set Folder Actions to run a command on mount. This would assume that the device always mounts in the same place, i.e. /Volumes/My\ Device/ - if peripherals were added or removed in between mounts, the mount point may change. You can learn more about Folder Actions by right clicking a directory and clicking "Folder Actions Setup". The trick would be to make sure that the device always mounts in the same place.

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

Alternatively, you may be able to use launchdto run a command on mount. This linkmay help. Lingonis a great app to edit daemons.

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

Either way, you could use the Folder Action or daemon to call a simple script to grab the contents of the device and upload them to wherever you please.

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