• c#使用PortableDeviceApiLib读取便携式设备(WPD:Windows Portable Devices)信息


    相关名词解释:

    WPD( Windows Portable Devices)

    译作Windows 便携设备 (WPD) 是一种驱动程序技术,可支持广泛的可移动设备,比如移动电话、数码相机和便携媒体播放器。WPD 提供了标准化的基础结构,以实现应用程序和连接到正在运行 Windows 的 PC 上的便携设备之间的数据传输。WPD 还可为应用程序提供设备及其内容的统一视图以及标准化机制,从而获得访问数据的权限并对数据进行传输。

    MTP(Media Transfer Protocol)模式

    MTP模式是微软制订的一套媒体传输协议,由微软公司制定的在设备之间进行多媒体文件交换的通信协议,它实现的是把简单的文件复制变成一种协议性的传输方式。MTP既可以实现在USB协议上,也可以实现在TCP/IP协议上,它属于上层的应用协议,而不关心底层传输协议。目前大部分设备的应用都是基于USB协议。

    PortableDeviceApiLib

    这是微软提供的一个COM类库可以用于获取WPD设备的信息和进行MTP模式的文件传输

    完整源码

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using PortableDeviceApiLib;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Linq;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            PortableDeviceManagerClass devMgr = new PortableDeviceApiLib.PortableDeviceManagerClass();
            IPortableDeviceValues pValues = (IPortableDeviceValues)new PortableDeviceTypesLib.PortableDeviceValuesClass();
            PortableDeviceClass pPortableDevice = new PortableDeviceClass();
            PortableDeviceClass ppDevice = new PortableDeviceClass();
            string deviceID = string.Empty;
            public Form1()
            {
                InitializeComponent();
                this.Load += new EventHandler(Form1_Load);
            }
    
            void Form1_Load(object sender, EventArgs e)
            {
                string[] deviceIds = EnumerateDevices();
                PortableDevice portableDevice;
                IPortableDeviceContent deviceContent;
                IPortableDeviceValues deviceValues = Connect(deviceIds[0], out portableDevice, out deviceContent);
                string deviceName = GetDeviceName(deviceValues);
                DeviceType deviceType = GetDeviceType(deviceValues);
                string firmwareVersion = GetFirmwareVersion(deviceValues);
                string manufacturer = GetManufacturer(deviceValues);
                string model = GetModel(deviceValues);
                List<string> storagesIds = GetChildrenObjectIds(deviceContent, "DEVICE");
                StringBuilder storagesSb = new StringBuilder();
                //设备支持WIFI则包含网络这个假设备,也是无法获取到容量的
                foreach (string storageId in storagesIds.Where(s=>!s.Contains("网络")))
                {
                    ulong freeSpace;
                    ulong storageCapacity;
                    GetStorageCapacityAnFreeSpace(deviceContent, storageId, out freeSpace, out storageCapacity);
                    storagesSb.AppendFormat("可用容量为{0}GB,总容量为{1}GB",
                        Math.Round((double)freeSpace / 1024 / 1024 / 1024, 3), Math.Round((double)storageCapacity / 1024 / 1024 / 1024, 3));
                }
                Disconnect(portableDevice);
                textBox1.AppendText(string.Format("当前设备数目:{0}个
    ", deviceIds.Length));
                textBox1.AppendText(string.Format("连接的设备名称:{0}
    ", deviceName));
                textBox1.AppendText(string.Format("连接的设备类型:{0}
    ", deviceType.ToString()));
                textBox1.AppendText(string.Format("连接的设备固件版本:{0}
    ", firmwareVersion));
                textBox1.AppendText(string.Format("连接的设备制造厂商:{0}
    ", manufacturer));
                textBox1.AppendText(string.Format("连接的设备型号:{0}
    ", model));
                textBox1.AppendText(storagesSb.ToString());
            }
    
            /// <summary>
            /// 枚举所有便携式设备(MTP模式)
            /// </summary>
            /// <returns>返回设备id数组</returns>
            public string[] EnumerateDevices()
            {
                string[] devicesIds = null;
                PortableDeviceManagerClass deviceManager = new PortableDeviceManagerClass();
                uint deviceCount = 1;//设备数目初始值必须大于0
                deviceManager.GetDevices(null, ref deviceCount);//获取设备数目必须置第一个参数为null
                if (deviceCount > 0)
                {
                    devicesIds = new string[deviceCount];
                    deviceManager.GetDevices(devicesIds, ref deviceCount);
                }
                return devicesIds;
            }
    
            /// <summary>
            /// 连接设备
            /// </summary>
            /// <param name="DeviceId"></param>
            /// <param name="portableDevice"></param>
            /// <param name="deviceContent"></param>
            /// <returns></returns>
            public IPortableDeviceValues Connect(string DeviceId, out PortableDevice portableDevice, out IPortableDeviceContent deviceContent)
            {
                IPortableDeviceValues clientInfo = (IPortableDeviceValues)new PortableDeviceTypesLib.PortableDeviceValuesClass();
                portableDevice = new PortableDeviceClass();
                portableDevice.Open(DeviceId, clientInfo);
                portableDevice.Content(out deviceContent);
    
                IPortableDeviceProperties deviceProperties;
                deviceContent.Properties(out deviceProperties);
    
                IPortableDeviceValues deviceValues;
                deviceProperties.GetValues("DEVICE", null, out deviceValues);
                return deviceValues;
            }
            /// <summary>
            /// 断开设备
            /// </summary>
            /// <param name="portableDevice"></param>
            public void Disconnect(PortableDevice portableDevice)
            {
                portableDevice.Close();
            }
    
            /// <summary>
            /// 设备类型
            /// </summary>
            public enum DeviceType
            {
                Generic = 0,
                Camera = 1,
                MediaPlayer = 2,
                Phone = 3,
                Video = 4,
                PersonalInformationManager = 5,
                AudioRecorder = 6
            };
            /// <summary>
            /// 获取设备类型
            /// </summary>
            /// <param name="DeviceValues"></param>
            /// <returns></returns>
            public DeviceType GetDeviceType(IPortableDeviceValues DeviceValues)
            {
                _tagpropertykey deviceTypeKey = new _tagpropertykey() { fmtid = new Guid("26d4979a-e643-4626-9e2b-736dc0c92fdc"), pid = 15 };
                uint propertyValue;
                DeviceValues.GetUnsignedIntegerValue(ref deviceTypeKey, out propertyValue);
                DeviceType deviceType = (DeviceType)propertyValue;
                return deviceType;
            }
            /// <summary>
            /// 获取设备名
            /// </summary>
            /// <param name="DeviceValues"></param>
            /// <returns></returns>
            public string GetDeviceName(IPortableDeviceValues DeviceValues)
            {
                _tagpropertykey property = new _tagpropertykey() { fmtid = new Guid("ef6b490d-5cd8-437a-affc-da8b60ee4a3c"), pid = 4 };
                string name;
                DeviceValues.GetStringValue(ref property, out name);
                return name;
            }
            /// <summary>
            /// 获取固件版本
            /// </summary>
            /// <param name="DeviceValues"></param>
            /// <returns></returns>
            public string GetFirmwareVersion(IPortableDeviceValues DeviceValues)
            {
                _tagpropertykey deviceTypeKey = new _tagpropertykey() { fmtid = new Guid("26d4979a-e643-4626-9e2b-736dc0c92fdc"), pid = 3 };
                string firmwareVersion;
                DeviceValues.GetStringValue(ref deviceTypeKey, out firmwareVersion);
                return firmwareVersion;
            }
            /// <summary>
            /// 获取制造商
            /// </summary>
            /// <param name="DeviceValues"></param>
            /// <returns></returns>
            public string GetManufacturer(IPortableDeviceValues DeviceValues)
            {
                _tagpropertykey property = new _tagpropertykey() { fmtid = new Guid("26d4979a-e643-4626-9e2b-736dc0c92fdc"), pid = 7 };
                string manufacturer;
                DeviceValues.GetStringValue(ref property, out manufacturer);
                return manufacturer;
            }
            /// <summary>
            /// 获取型号
            /// </summary>
            /// <param name="DeviceValues"></param>
            /// <returns></returns>
            public string GetModel(IPortableDeviceValues DeviceValues)
            {
                _tagpropertykey property = new _tagpropertykey() 
                { 
                    fmtid = new Guid("26d4979a-e643-4626-9e2b-736dc0c92fdc"), 
                    pid = 8 
                };
                string model;
                DeviceValues.GetStringValue(ref property, out model);
                return model;
            }
            /// <summary>
            /// 获取设备或设备下文件夹的所有对象(文件、文件夹)的ObjectId
            /// </summary>
            /// <param name="deviceId"></param>
            /// <param name="parentId"></param>
            /// <returns></returns>
            public List<string> GetChildrenObjectIds(IPortableDeviceContent content, string parentId)
            {
                IEnumPortableDeviceObjectIDs objectIds;
                content.EnumObjects(0, parentId, null, out objectIds);
                List<string> childItems = new List<string>();
                uint fetched = 0;
                do
                {
                    string objectId;
                    objectIds.Next(1, out objectId, ref fetched);
                    if (fetched > 0)
                    {
                        childItems.Add(objectId);
                    }
                } 
                while (fetched > 0);
                return childItems;
            }
            /// <summary>
            /// 获取总容量和可用容量
            /// </summary>
            /// <param name="deviceContent"></param>
            /// <param name="storageId"></param>
            /// <param name="freeSpace"></param>
            /// <param name="storageCapacity"></param>
            public void GetStorageCapacityAnFreeSpace(IPortableDeviceContent deviceContent, string storageId, out ulong freeSpace, out ulong storageCapacity)
            {
                IPortableDeviceProperties deviceProperties;
                deviceContent.Properties(out deviceProperties);
    
                IPortableDeviceKeyCollection keyCollection = (IPortableDeviceKeyCollection)new PortableDeviceTypesLib.PortableDeviceKeyCollectionClass();
                _tagpropertykey freeSpaceKey = new _tagpropertykey();
                freeSpaceKey.fmtid = new Guid("01a3057a-74d6-4e80-bea7-dc4c212ce50a");
                freeSpaceKey.pid = 5;
    
                _tagpropertykey storageCapacityKey = new _tagpropertykey();
                storageCapacityKey.fmtid = new Guid("01a3057a-74d6-4e80-bea7-dc4c212ce50a");
                storageCapacityKey.pid = 4;
    
                keyCollection.Add(ref freeSpaceKey);
                keyCollection.Add(ref storageCapacityKey);
    
                IPortableDeviceValues deviceValues;
                deviceProperties.GetValues(storageId, keyCollection, out deviceValues);
    
                deviceValues.GetUnsignedLargeIntegerValue(ref freeSpaceKey, out freeSpace);
                deviceValues.GetUnsignedLargeIntegerValue(ref storageCapacityKey, out storageCapacity);
            }
        }
    }

    运行截图

    一点感想

    最近在重构一个PDA程序就是WinCE的。是的老掉牙的设备(系统),工控行业有些地方还在用。早几年前就转了安卓了,这次重构这么个项目其实还是挺用心的。分层开发,用了ORM,还把PDA程序的功能做成了可配置,有时间会另外写文分享。在收集资料的时候发现网上基本上是没有可以使用的源码,现在DIY了一份,送给有缘人吧:

    PortableDeviceApiLib读取WPD设备信息

  • 相关阅读:
    201920201学期 20192410《网络空间安全专业导论》第一周学习总结
    201920201学期 20192410《网络空间安全专业导论》第二周学习总结
    Oracle trunc()函数的用法
    20130528
    让ListBox控件支持拖动
    幸福是什么
    实例解析C++/CLI程序进程之间的通讯
    Boost源码剖析之:容器赋值assign
    VC++ MFC 多线程及线程同步
    MFC下窗口分割和文字输出的实现
  • 原文地址:https://www.cnblogs.com/datacool/p/datacool_2017_WPD.html
Copyright © 2020-2023  润新知