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

来源:互联网 发布:剑网3数据非法 编辑:程序博客网 时间:2024/04/24 11:48

在上节内容(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>
        /// 创建符合要求的文件夹
        /// </summary>
        /// <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);
            }
        }

2 0
原创粉丝点击