如何使用USB从设备获取文件

时间:2010-03-24 03:53:36

标签: c# wpf .net-3.5 winapi usb

我正在编写一个想要访问数码相机的WPF应用程序,并疯狂地搜索解决方案,我非常满意它的全部用途。

这就是我现在所拥有的:

    private const decimal WM_DEVICECHANGE = 0x0219;
    private const int DBT_DEVTYP_HANDLE = 6;
    private const int DBT_DEVNODES_CHANGED = 7;
    private const int BROADCAST_QUERY_DENY = 0x424D5144;
    private const int DBT_DEVICEARRIVAL = 0x8000; // system detected a new device
    private const int DBT_DEVICEQUERYREMOVE = 0x8001;   // Preparing to remove (any program can disable the removal)
    private const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // removed 
    private const int DBT_DEVTYP_VOLUME = 0x00000002; // drive type is logical volume

    protected override void OnSourceInitialized(EventArgs e)
    {
        base.OnSourceInitialized(e);
        var mainFormWinInteropHelper = new System.Windows.Interop.WindowInteropHelper(this);
        System.Windows.Interop.HwndSource.FromHwnd(mainFormWinInteropHelper.Handle).AddHook(HwndHandler);
    }

    private IntPtr HwndHandler(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
    {
        ProcessWinMessage(msg, wparam, lparam);
        handled = false;
        return IntPtr.Zero;
    }

    private void ProcessWinMessage(int msg, IntPtr wparam, IntPtr lparam)
    {
        int deviceType;
        char driveLetter;

        if (msg == WM_DEVICECHANGE)
        {
            var int32 = wparam.ToInt32();

            switch (int32)
            {
                case DBT_DEVICEARRIVAL:
                    Console.WriteLine("Device Arrival");
                    break;
                case DBT_DEVICEQUERYREMOVE:
                    Console.WriteLine("Device Query Removed");
                    break;
                case DBT_DEVICEREMOVECOMPLETE:
                    Console.WriteLine("Device Removed");
                    break;
                case DBT_DEVNODES_CHANGED:
                    Console.WriteLine("Device added or removed");
                    break;
            }
        }
    }

这实际上对我的数码相机都非常有用,我可以把照片拿掉。我现在应该注意,当我插入相机时,它出现在“带有可移动存储的设备”下的窗口中,并且它有一个分配给它的驱动器号。

然而,当我插入iPhone进行测试时,iPhone不会出现在该部分下,并且似乎没有与之关联的驱动器号...

但这是我的主要问题,为什么我添加iPhone时会触发消息DBT_DEVNODES_CHANGED,但是当我添加相机时会触发DBT_DEVICEARRIVAL消息?

我非常希望能够在用户插入任何USB设备时“获取”文件。

有没有人有这方面的经验?我的Win32编程非常有限......

干杯, 标记

1 个答案:

答案 0 :(得分:2)

有两种USB媒体提供商。 USB大容量存储设备就像驱动器和Windows Media设备一样,用于简单的相机和便携式媒体播放器。

某些相机(通常是廉价相机)仅实施Windows Media Device模型,而其他相机则实施USB大容量存储模型。

根据您的解释,iPhone被视为Windows Media设备,而相机是USB Mass Storage。我知道当设备上有图片或屏幕截图时,某些Apple设备(特别是触摸生成)突然切换到WMD模型存在“问题”。尝试删除您使用iPhone拍摄的任何屏幕截图或图片,看看它是否解决了问题,如果是这样,这是因为您的代码不支持Windows Media Devices模型。

MSDN library可以帮助您解决这个烂摊子。他们多次更新API,停止使用它的某些部分,在其他地方添加更多,现在看来他们有一个新版本将修复它所有TM。