您的位置:首页 > 编程语言 > C#

c#使用wpd读取便携式设备信息二

2017-07-29 20:58 489 查看
在上节内容(c#使用wpd读取便携式设备信息一)中,我们已经获取到了设备名称,容量等信息,本节进行读写设备的存储内容操作。WPD对设备的操作都是基于对象的ID的,例如文件夹和文件都有各自的objectId,首先获取到要进行操作的对象的objectId,然后再进行读写。
这里以我的小米note手机为例,要对Android目录下的文件进行读取



需要用到的方法如下:

/// <summary>

        /// 获取设备ID

        /// </summary>

        /// <returns></returns>

        public string GetDeviceId()

        {

            uint devicesCount = 1;

            PortableDeviceManagerClass devMgr = new PortableDeviceManagerClass();

            string deviceID = string.Empty;

            //此处devicesCount为大于0的数,且只能获取一个便携式设备,如何获取多个设备会在之后的文章展现

            devMgr.GetDevices(ref deviceID, ref devicesCount);

            return deviceID;

        }

        /// <summary>

        /// 获取设备信息

        /// </summary>

        /// <param name="deviceId"></param>

        /// <returns></returns>

        public IPortableDeviceContent GetDeviceContent(string deviceId)

        {

            IPortableDeviceValues clientInfo = (IPortableDeviceValues)new PortableDeviceTypesLib.PortableDeviceValuesClass();

            PortableDeviceClass portableDevice = new PortableDeviceClass();

            portableDevice.Open(deviceId, clientInfo);

            IPortableDeviceContent content;

            portableDevice.Content(out content);

            return content;

        }

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

                // Check if anything was retrieved.

                if (fetched > 0)

                {

                    childItems.Add(objectId);

                }

            } while (fetched > 0);

            return childItems;

        }

        /// <summary>

        /// 获取名称属性

        /// </summary>

        /// <param name="deviceValues"></param>

        /// <returns></returns>

        public string GetNameProperty(IPortableDeviceValues deviceValues)

        {

            _tagpropertykey nameKey = new _tagpropertykey();

            nameKey.fmtid= new Guid("EF6B490D-5CD8-437A-AFFC-DA8B60EE4A3C");//guid唯一值

            nameKey.pid = 4;//索引

            string nameProperty = null;

            deviceValues.GetStringValue(ref nameKey, out nameProperty);

            return nameProperty;

        }

要将数据写入到设备中,首先需要创建符合要求的文件或文件夹
/// <summary>

        /// 创建符合要求的文件

        /// </summary>

        /// <param name="sourcePath"></param>

        /// <param name="parentId"></param>

        /// <returns></returns>

        private static IPortableDeviceValues GetRequiredPropertiesForContentType(string sourcePath,string parentId)

        {

            IPortableDeviceValues values = new PortableDeviceTypesLib.PortableDeviceValues() as IPortableDeviceValues;

            _tagpropertykey WPD_OBJECT_PARENT_ID = new _tagpropertykey();

            WPD_OBJECT_PARENT_ID.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_PARENT_ID.pid = 3;

            values.SetStringValue(ref WPD_OBJECT_PARENT_ID, parentId);

            _tagpropertykey WPD_OBJECT_SIZE = new _tagpropertykey();

            WPD_OBJECT_SIZE.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_SIZE.pid = 11;

            FileInfo fileInfo = new FileInfo(sourcePath);

            values.SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, (ulong)fileInfo.Length);

            _tagpropertykey WPD_OBJECT_ORIGINAL_FILE_NAME = new _tagpropertykey();

            WPD_OBJECT_ORIGINAL_FILE_NAME.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_ORIGINAL_FILE_NAME.pid = 12;

            values.SetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, Path.GetFileName(sourcePath));

            _tagpropertykey WPD_OBJECT_NAME = new _tagpropertykey();

            WPD_OBJECT_NAME.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_NAME.pid = 4;

            values.SetStringValue(WPD_OBJECT_NAME, Path.GetFileName(sourcePath));

            return values;

        }

        /// <summary>

        /// 创建符合要求的文件夹

        /// </su
4000
mmary>

        /// <param name="parentId"></param>

        /// <param name="folderName"></param>

        /// <returns></returns>

        private IPortableDeviceValues GetRequiredPropertiesForFolder(string parentId, string folderName)

        {

            IPortableDeviceValues values = new PortableDeviceTypesLib.PortableDeviceValues() as IPortableDeviceValues;

            _tagpropertykey WPD_OBJECT_PARENT_ID = new _tagpropertykey();

            WPD_OBJECT_PARENT_ID.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_PARENT_ID.pid = 3;

            values.SetStringValue(ref WPD_OBJECT_PARENT_ID, parentId);

            _tagpropertykey WPD_OBJECT_NAME = new _tagpropertykey();

            WPD_OBJECT_NAME.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_NAME.pid = 4;

            values.SetStringValue(WPD_OBJECT_NAME, folderName);

            _tagpropertykey WPD_OBJECT_ORIGINAL_FILE_NAME = new _tagpropertykey();

            WPD_OBJECT_ORIGINAL_FILE_NAME.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_ORIGINAL_FILE_NAME.pid = 12;

            values.SetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, folderName);

            _tagpropertykey WPD_OBJECT_CONTENT_TYPE = new _tagpropertykey();

            WPD_OBJECT_CONTENT_TYPE.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C);

            WPD_OBJECT_CONTENT_TYPE.pid = 12;

            values.SetStringValue(WPD_OBJECT_ORIGINAL_FILE_NAME, folderName);

            return values;

        }

创建完毕后,进行数据的写入
最后写入数据
/// <summary>

        /// 写入数据

        /// </summary>

        /// <param name="sourceFile"></param>

        /// <param name="portableDevice"></param>

        /// <param name="parentId"></param>

        public void TransferContentToDevice(string sourceFile, PortableDeviceClass portableDevice,string parentId)

        {

            IPortableDeviceContent content;

            portableDevice.Content(out content);

            IPortableDeviceValues values = GetRequiredPropertiesForContentType(sourceFile, parentId);

            IStream tempStream;

            uint optimalTransferSizeBytes = 0;

            content.CreateObjectWithPropertiesAndData(values, out tempStream, ref optimalTransferSizeBytes, null);

            System.Runtime.InteropServices.ComTypes.IStream targetStream = (System.Runtime.InteropServices.ComTypes.IStream)tempStream;

            try

            {

                using (FileStream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read))

                {

                    int bytesRead = 0;

                    do

                    {

                        int count = 1024 * 1024;

                        byte[] buffer = new byte[count];

                        bytesRead = sourceStream.Read(buffer, 0, count);

                        IntPtr pcbWritten = IntPtr.Zero;

                        targetStream.Write(buffer, bytesRead, pcbWritten);

                    }

                    while (bytesRead > 0);

                }

                targetStream.Commit(0);

            }

            finally

            {

                Marshal.ReleaseComObject(tempStream);

            }

        }

整理上述方法,调用顺序如下
 private void button2_Click(object sender, EventArgs e)

        {

            string deviceId = GetDeviceId();

            IPortableDeviceContent content = GetDeviceContent(deviceId);

            IPortableDeviceProperties properties;

            content.Properties(out properties);

            IPortableDeviceValues deviceValues;

            properties.GetValues("DEVICE", null, out deviceValues);

            

            List<string> storagesId = GetChildrenObjectIds(content, "DEVICE");//这里小米note手机由于没有外置sd卡,所以storagesId只有一个,即为内置存储

            foreach (string storageId in storagesId)

            {

                List<string> objectsId = GetChildrenObjectIds(content, storageId);

                string androidId = null;

                foreach (string objectId in objectsId)

                {

                    IPortableDeviceValues objectValues;

                    properties.GetValues(objectId, null, out objectValues);

                    string objectName = GetNameProperty(objectValues);

                    if (objectName == "android")

                    {

                        androidId = objectId;

                        break;

                    }

                }

                TransferContentToDevice(@"C:\Users\Administrator\Desktop\tmp.png", content, androidId);

            }

        }

最后结果



最后再奉上拷贝设备上的数据到PC的代码
 public void TransferContentFromDevice(string destPath,IPortableDeviceContent deviceContent,string objectId)

        {

            // TODO: Clean this up.

            IPortableDeviceResources resources;

            deviceContent.Transfer(out resources);

            IStream wpdStream = null;

            uint optimalTransferSize = 0;

            _tagpropertykey property = new _tagpropertykey { fmtid = new Guid("E81E79BE-34F0-41BF-B53F-F1A06AE87842"), pid = 0 };

            System.Runtime.InteropServices.ComTypes.IStream sourceStream = null;

            try

            {

                resources.GetStream(objectId, ref property, 0, ref optimalTransferSize, out wpdStream);

                sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream;

                FileStream targetStream = new FileStream(destPath, FileMode.Create, FileAccess.Write);

                unsafe

                {

                    try

                    {

                        var buffer = new byte[1024];

                        int bytesRead;

                        do

                        {

                            sourceStream.Read(buffer, 1024, new IntPtr(&bytesRead));

                            targetStream.Write(buffer, 0, 1024);

                        } while (bytesRead > 0);

                    }

                    finally

                    {

                        targetStream.Close();

                    }

                }

            }

            finally

            {

                Marshal.ReleaseComObject(sourceStream);

                Marshal.ReleaseComObject(wpdStream);

            }

        }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: