2014-12-04 138 views
0

我原本打算实现Manzana.dll库以检测iPhone连接事件并与设备进行交互。问题在于,如果客户端计算机安装了iTunes dll和资源,它似乎只能工作,这是我不能依赖的。因此,我正在尝试使用Manzana源代码的自定义实现来指向它所包含的必要iTunes文件的引用。iTunesMobileDevice.dll的自定义实现抛出NullReferenceException

虽然一切看起来都不错,但编译的库在我的应用程序中使用时会引发NullReferenceException。应用程序加载并初始化正常,但是当iPhone连接时,connectedevent会引发异常。

实际的错误是:

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() 

我可以用它来缩小问题,以这种方法从我的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 = "/";    
     } 
    } 

问题来自

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

哪指向这段代码位于我的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); 

这又似乎是在它自己的类来引用这个

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

然后指向另一个类:

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; 
     } 
    } 
    } 
} 

绝大多数这段代码被复制直接从Manzana.dll,我改变的唯一的东西是itunesmobiledevice文件所在的位置(现在是设置路径,而不是在运行时检测到)

旧代码:

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 
    })); 
} 

新代码:

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 })); 

    } 

有我丢失的东西,是造成该调用返回null?我承认我没有完全理解上述代码中发生的一切,所以完全有可能这很简单。

+0

其实,我可能已经解决了它。我无法弄清楚它为什么抛出一个generica null异常,但是我将这些代码分开并单独进行了测试,它给了我一个dllnotfound错误,这更有帮助。我已经改变了一条路,并且会在明天进行测试,看看它是否能解决问题。 – Chris2222000 2014-12-04 02:59:16

+0

我也在寻找同样的事情,你能帮我吗? – 2015-01-20 08:20:12

回答

0

是的,我相信答案确实是路径不正确,因此找不到该文件。我只是没有意识到这一点,因为它抛出的错误过于通用。

相关问题