在 C# 中开发类似 iTunes 的应用程序

Posted

技术标签:

【中文标题】在 C# 中开发类似 iTunes 的应用程序【英文标题】:Developing iTunes like application in c# 【发布时间】:2013-11-07 04:37:58 【问题描述】:

我需要用 c# 开发一个应用程序,它可以在 iPhone 连接到系统时自动检测它并读取 iPhone 文件系统的特定文件。我基本上希望这个文件自动从设备下载到 PC。我使用了 USBpcap 工具,该工具建议 iTunes 使用某种 XML 格式连接到手机。非常感谢任何帮助或见解。是否有任何第三方 API 文档可以帮助我入门?有一些应用程序可以复制 iTunes 功能,例如 Copytrans

Apple 是否提供任何协议或 API?

我一直在挖掘互联网并找到此链接Layered communication for iPhone。 此外,我正在使用 LibUsbDotNet 库与 USB 设备进行通信(Example)。任何人都可以建议应该使用哪些端点。

在我看来,我必须在 Windows 应用程序中实现 usbmuxd。它是一个多层协议。一定有一些库实现了usbmuxd(我认为我不必自己实现协议)

我不太了解 iTunes 通信以及 USB 通信。我正在尽可能多地添加信息(当然还有我在研发中提出的东西)。非常感谢任何帮助。

public static DateTime LastDataEventDate = DateTime.Now;
    public static UsbDevice MyUsbDevice;

    #region SET YOUR USB Vendor and Product ID!

    public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1452, 4768);

    #endregion

    private void LibUSB()
    
        ErrorCode ec = ErrorCode.None;

        try
        
            // Find and open the usb device.
            MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

            // If the device is open and ready
            if (MyUsbDevice == null)
                throw new Exception("Device Not Found.");

            // If this is a "whole" usb device (libusb-win32, linux libusb)
            // it will have an IUsbDevice interface. If not (WinUSB) the 
            // variable will be null indicating this is an interface of a 
            // device.
            IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
            if (!ReferenceEquals(wholeUsbDevice, null))
            
                // This is a "whole" USB device. Before it can be used, 
                // the desired configuration and interface must be selected.

                // Select config #1
                wholeUsbDevice.SetConfiguration(1);

                // Claim interface #0.
                wholeUsbDevice.ClaimInterface(0);
            

            // open read endpoint 1.
            UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep03);

            // open write endpoint 1.
            UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep02);


                int bytesWritten;
                ec = writer.Write(usbmux_header.GetBytes(), 2000, out bytesWritten);
                if (ec != ErrorCode.None)
                    throw new Exception(UsbDevice.LastErrorString);

                byte[] readBuffer = new byte[1024];
                while (ec == ErrorCode.None)
                
                    int bytesRead;

                    // If the device hasn't sent data in the last 100 milliseconds,
                    // a timeout error (ec = IoTimedOut) will occur. 
                    ec = reader.Read(readBuffer, 10000, out bytesRead);

                    if (ec == ErrorCode.Win32Error)
                        throw new Exception("port not open");
                    if (bytesRead == 0)
                        throw new Exception("No more bytes!");

                    // Write that output to the console.
                    Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
                

        
        catch (Exception ex)
        
            Console.WriteLine();
            Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
        
        finally
        
            if (MyUsbDevice != null)
            
                if (MyUsbDevice.IsOpen)
                
                    // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
                    // it exposes an IUsbDevice interface. If not (WinUSB) the 
                    // 'wholeUsbDevice' variable will be null indicating this is 
                    // an interface of a device; it does not require or support 
                    // configuration and interface selection.
                    IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
                    if (!ReferenceEquals(wholeUsbDevice, null))
                    
                        // Release interface #0.
                        wholeUsbDevice.ReleaseInterface(0);
                    

                    MyUsbDevice.Close();
                
                MyUsbDevice = null;

                // Free usb resources
                UsbDevice.Exit();

            
        
    

class usbmux_header

    public static UInt32 length = 10;   // length of message, including header
    public static UInt32 reserved = 0;  // always zero
    public static UInt32 type = 3;       // message type
    public static UInt32 tag = 2;   // responses to this query will echo back this tag

    public static byte[] GetBytes()
    
        byte[] lgth = BitConverter.GetBytes(length);
        byte[] res = BitConverter.GetBytes(reserved);
        byte[] tpe = BitConverter.GetBytes(type);
        byte[] tg = BitConverter.GetBytes(tag);

        byte[] retArray = new byte[16];
        lgth.CopyTo(retArray, 0);
        res.CopyTo(retArray, 4);
        tpe.CopyTo(retArray, 8);
        tg.CopyTo(retArray, 12);

        return retArray;
    
;

我一直在尝试向 iPhone 发送 hello 数据包字节,但我无法从手机读取任何响应。

【问题讨论】:

我也在尝试这样做。你有什么运气吗? 【参考方案1】:

您可以使用imobiledevice-net。它提供了一个 C# API 来使用您的 PC 连接到 ios 设备。

例如,要列出连接到您的 PC 的所有 iOS 设备,您可以运行以下命令:

ReadOnlyCollection<string> udids;
int count = 0;

var idevice = LibiMobileDevice.Instance.iDevice;
var lockdown = LibiMobileDevice.Instance.Lockdown;

var ret = idevice.idevice_get_device_list(out udids, ref count);

if (ret == iDeviceError.NoDevice)

    // Not actually an error in our case
    return;


ret.ThrowOnError();

// Get the device name
foreach (var udid in udids)

    iDeviceHandle deviceHandle;
    idevice.idevice_new(out deviceHandle, udid).ThrowOnError();

    LockdownClientHandle lockdownHandle;
    lockdown.lockdownd_client_new_with_handshake(deviceHandle, out lockdownHandle, "Quamotion").ThrowOnError();

    string deviceName;
    lockdown.lockdownd_get_device_name(lockdownHandle, out deviceName).ThrowOnError();

    deviceHandle.Dispose();
    lockdownHandle.Dispose();

【讨论】:

【参考方案2】:

据我了解,一次只有一个客户端可以使用 USB 连接到 iOS。在 macOS 和 Windows 上,一个客户端是 usbmux。该库与更高级别的客户端多路复用 TCP 连接,包括 iTunes、Photos 和(在 macOS 上)开源 peertalk 库。

因此,在 Windows 上,您不想实现自己的 usbmux,而是希望在其之上实现一个客户端,类似于 peertalk。我还没有看到任何开源软件可以做到这一点,但许多开发人员已经使用他们自己的专有软件完成了它。

如果其他人有关于在 Windows 上使用 usbmux 的建议,我很想听听。

——戴夫

【讨论】:

【参考方案3】:

要玩 ipod 你可以使用SharePodLib

【讨论】:

以上是关于在 C# 中开发类似 iTunes 的应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C# 在 WPF 中开发类似 Google Chrome 浏览器的应用程序

如何从网页启动/传递值到 Windows C# 应用程序? (似乎有可能与 iTunes 的歌曲链接)?

使用 iTunes SDK 播放音频文件

iTunes 整合建议

使用 Application Loader 将二进制文件上传到 iTunes 商店时出错

如何在 iTunes 应用描述中插入水平线?