简体   繁体   English

iTunesMobileDevice.dll的自定义实现将引发NullReferenceException

[英]custom implementation of iTunesMobileDevice.dll throws NullReferenceException

I had intended to implement the Manzana.dll library in order to detect iPhone connection events and interact with the device. 我本打算实现Manzana.dll库,以便检测iPhone连接事件并与设备进行交互。 The problem is that it only seems to work if the client machine has the iTunes dlls and resources installed, which I cannot rely on. 问题在于,只有在客户端计算机安装了iTunes dll和资源(我不能依靠)的情况下,它似乎才起作用。 Therefore I am trying to use a custom implementation of the Manzana source code to point it's references to the necessary iTunes files that I am including with the project. 因此,我试图使用Manzana源代码的自定义实现,以指向对项目中包含的必要iTunes文件的引用。

Although everything looks ok the compiled library throws a NullReferenceException when used from my application. 尽管一切正常,但从我的应用程序使用时,编译后的库将引发NullReferenceException。 The application load and initializes ok, but when an iPhone is connected the connectedevent throws an exception. 应用程序加载并初始化ok,但是当连接iPhone时,connectedevent会引发异常。

The actual error is: 实际错误是:

System.TypeInitializationException: The type initializer for 'istreamwrapper.MobileDevice' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at istreamwrapper.MobileDevice..cctor()
--- End of inner exception stack trace ---
at istreamwrapper.MobileDevice.AMDeviceNotificationSubscribe(DeviceNotificationCallback callback, UInt32 unused1, UInt32 unused2, UInt32 unused3, Void*& am_device_notification_ptr)
at istreamwrapper.iPhone.doConstruction()

I was able to use that to narrow down the problem to to this method from my iPhone class 我可以用它来将问题缩小到我的iPhone类中的这种方法

private unsafe void doConstruction()
    {
        void* voidPtr;
        this.dnc = new DeviceNotificationCallback(this.NotifyCallback);
        this.drn1 = new DeviceRestoreNotificationCallback(this.DfuConnectCallback);
        this.drn2 = new DeviceRestoreNotificationCallback(this.RecoveryConnectCallback);
        this.drn3 = new DeviceRestoreNotificationCallback(this.DfuDisconnectCallback);
        this.drn4 = new DeviceRestoreNotificationCallback(this.RecoveryDisconnectCallback);
        int num = MobileDevice.AMDeviceNotificationSubscribe(this.dnc, 0, 0, 0, out voidPtr);
        if (num != 0)
        {
            throw new Exception("AMDeviceNotificationSubscribe failed with error " + num);
        }
        num = MobileDevice.AMRestoreRegisterForDeviceNotifications(this.drn1, this.drn2, this.drn3, this.drn4, 0, null);
        if (num != 0)
        {
            throw new Exception("AMRestoreRegisterForDeviceNotifications failed with error " + num);
        }
        this.current_directory = "/";               
        }
    }

The issue comes from 问题来自

num = MobileDevice.AMDeviceNotificationSubscribe(this.dnc, 0, 0, 0, out voidPtr);

which points to this code which is located in my MobileDevice class 指向位于我的MobileDevice类中的此代码

 [DllImport("iTunesMobileDevice.dll", CallingConvention = CallingConvention.Cdecl)]
    public static unsafe extern int AMDeviceNotificationSubscribe(DeviceNotificationCallback callback, uint unused1, uint unused2, uint unused3, out void* am_device_notification_ptr);

That in turn seems to reference this in it's own class 反过来似乎在自己的类中引用了这个

namespace istreamwrapper
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void DeviceNotificationCallback(ref AMDeviceNotificationCallbackInfo callback_info);
}

which then points to another class with: 然后指向带有以下内容的另一个类:

namespace istreamwrapper
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct AMDeviceNotificationCallbackInfo
  {
    internal unsafe void* dev_ptr;
    public NotificationMessage msg;

    public unsafe void* dev
    {
        get
        {
            return this.dev_ptr;
        }
    }
  }
}

The vast majority of this code was copied straight from the Manzana.dll, the only thing I changed was where the itunesmobiledevice files are located (which is now a set path, rather detected at run time) 该代码的绝大多数直接从Manzana.dll复制而来,我唯一更改的是itunesmobiledevice文件所在的位置(现在是设置的路径,而不是在运行时检测到的)

Old code: 旧代码:

namespace Manzana
{
  internal class MobileDevice
  {
private static readonly FileInfo iTunesMobileDeviceFile = new FileInfo(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Inc.\\Apple Mobile Device Support\\Shared", "iTunesMobileDeviceDLL", (object) "iTunesMobileDevice.dll").ToString());
private static readonly DirectoryInfo ApplicationSupportDirectory = new DirectoryInfo(Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Apple Inc.\\Apple Application Support", "InstallDir", (object) Environment.CurrentDirectory).ToString());
private const string DLLName = "iTunesMobileDevice.dll";

static MobileDevice()
{
  string str = MobileDevice.iTunesMobileDeviceFile.DirectoryName;
  if (!MobileDevice.iTunesMobileDeviceFile.Exists)
  {
    str = Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles) + "\\Apple\\Mobile Device Support\\bin";
    if (!File.Exists(str + "\\iTunesMobileDevice.dll"))
      str = "C:\\Program Files\\Common Files\\Apple\\Mobile Device Support";
  }
  Environment.SetEnvironmentVariable("Path", string.Join(";", new string[3]
  {
    Environment.GetEnvironmentVariable("Path"),
    str,
    MobileDevice.ApplicationSupportDirectory.FullName
  }));
}

New code: 新代码:

namespace istreamwrapper
{
class MobileDevice
{
    static MobileDevice()
    {

       string str = "[XX_MYPATHHERE_XX]\\Apple\\Mobile Device Support";
       string AppSuppDirectory = @"[XX_MYPATHHERE_XX]\Apple\Apple Application Support";
       Environment.SetEnvironmentVariable("Path", string.Join(";", new string[3] { Environment.GetEnvironmentVariable("Path"), str, AppSuppDirectory }));

    }

Is there something I'm missing that is causing that call to return null? 我是否缺少导致该调用返回null的内容? I'll admit I don't fully understand everything that is happening in the above code so it's entirely possible it's something simple. 我承认我不完全理解上述代码中发生的所有事情,因此这很可能很简单。

Yes, I believe the answer was really that the path was incorrect and thus could not find the file. 是的,我相信答案确实是路径不正确,因此找不到文件。 I just didn't realize this because the error it was throwing was too generic. 我只是没有意识到这一点,因为它引发的错误太笼统了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM