private static string TransferContentFromDevice(string saveToPath, IPortableDeviceContent content, string parentObjectID) { IPortableDeviceResources resources; content.Transfer(out resources); PortableDeviceApiLib.IStream wpdStream = null; uint optimalTransferSize = int.MaxValue; PortableDeviceApiLib._tagpropertykey property = new PortableDeviceApiLib._tagpropertykey(); property.fmtid = new Guid(0xE81E79BE, 0x34F0, 0x41BF, 0xB5, 0x3F, 0xF1, 0xA0, 0x6A, 0xE8, 0x78, 0x42); property.pid = 0; try { resources.GetStream(parentObjectID, ref property, 0, ref optimalTransferSize, out wpdStream); System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; using (FileStream targetStream = new FileStream(saveToPath, FileMode.Create, FileAccess.Write)) { int filesize = int.Parse(optimalTransferSize.ToString()); var buffer = new byte[filesize]; int bytesRead = 0; IntPtr bytesReadIntPtr = new IntPtr(bytesRead); //设备建议读取长度optimalTransferSize长度一般为262144即256k, //注释掉的sourceStream.Read不能更新bytesRead值,do循环只能执行一次即写入256k数据。 //创建nextBufferSize变量,用于每次Read后计算下一次buffer长度 int nextBufferSize = 0; do { if (bytesReadIntPtr == IntPtr.Zero) { bytesReadIntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int))); } sourceStream.Read(buffer, filesize, bytesReadIntPtr); nextBufferSize = Marshal.ReadInt32(bytesReadIntPtr); if (filesize > nextBufferSize) { filesize = nextBufferSize; } targetStream.Write(buffer, 0, filesize); } while (nextBufferSize > 0); Marshal.FreeCoTaskMem(bytesReadIntPtr); } } catch (Exception ex) { return(ex.Message); } finally { if (wpdStream != null) { Marshal.ReleaseComObject(wpdStream); } } return(string.Empty); }
// uint tmpBufferSize = 0; // uint tmpTransferSize = 0; // string tmpTransferContext = string.Empty; // { // pResults.GetStringValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_CONTEXT, out tmpTransferContext); // pResults.GetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_TOTAL_DATA_SIZE, out tmpBufferSize); // pResults.GetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_OPTIMAL_TRANSFER_BUFFER_SIZE, out tmpTransferSize); // try // { // int pValue; // pResults.GetErrorValue(PortableDevicePKeys.WPD_PROPERTY_COMMON_HRESULT, out pValue); // if(pValue!=0) // { // return null; // } // } // catch // { // } // } // pParameters.Clear(); // pResults.Clear(); // byte[] tmpData = new byte[(int)tmpTransferSize]; // //CCustomReadContext{81CD75F1-A997-4DA2-BAB1-FF5EC514E355} // pParameters.SetGuidValue(PortableDevicePKeys.WPD_PROPERTY_COMMON_COMMAND_CATEGORY, PortableDevicePKeys.WPD_COMMAND_MTP_EXT_READ_DATA.fmtid); // pParameters.SetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_COMMON_COMMAND_ID, PortableDevicePKeys.WPD_COMMAND_MTP_EXT_READ_DATA.pid); // pParameters.SetStringValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_CONTEXT, tmpTransferContext); // pParameters.SetBufferValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_DATA, ref tmpData[0], (uint)tmpTransferSize); // pParameters.SetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_TO_READ, (uint)tmpTransferSize); // pParameters.SetIPortableDevicePropVariantCollectionValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_OPERATION_PARAMS, propVariant); // portableDeviceClass.SendCommand(0, pParameters, out pResults); // uint cbBytesRead = 0; // try // { // int pValue = 0; // pResults.GetErrorValue(PortableDevicePKeys.WPD_PROPERTY_COMMON_HRESULT, out pValue); // if (pValue != 0) // return null; // } // catch(Exception ex) // { // } // // 24,142,174,9 // // 18, 8E // GCHandle pinnedArray = GCHandle.Alloc(imgdate, GCHandleType.Pinned); // IntPtr ptr = pinnedArray.AddrOfPinnedObject(); // uint dataread =0; // pResults.GetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_NUM_BYTES_READ, out dataread); // pResults.GetBufferValue(ref PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_DATA, ptr, out cbBytesRead); // IntPtr tmpPtr = new IntPtr(Marshal.ReadInt64(ptr)); // byte[] res = new byte[(int)cbBytesRead]; // for (int i = 0; i < cbBytesRead; i++) // { // res[i] = Marshal.ReadByte(tmpPtr, i); // } // pParameters.Clear(); // pResults.Clear(); // { // pParameters.SetGuidValue(PortableDevicePKeys.WPD_PROPERTY_COMMON_COMMAND_CATEGORY, PortableDevicePKeys.WPD_COMMAND_MTP_EXT_END_DATA_TRANSFER.fmtid); // pParameters.SetUnsignedIntegerValue(ref PortableDevicePKeys.WPD_PROPERTY_COMMON_COMMAND_ID, PortableDevicePKeys.WPD_COMMAND_MTP_EXT_END_DATA_TRANSFER.pid); // pParameters.SetStringValue(PortableDevicePKeys.WPD_PROPERTY_MTP_EXT_TRANSFER_CONTEXT, tmpTransferContext); // } // portableDeviceClass.SendCommand(0, pParameters, out pResults); // Marshal.FreeHGlobal(tmpPtr); // pinnedArray.Free(); // //Marshal.FreeHGlobal(ptr); // try // { // int tmpResult = 0; // pResults.GetErrorValue(ref PortableDevicePKeys.WPD_PROPERTY_COMMON_HRESULT, out tmpResult); // if(tmpResult!=0) // { // } // } // catch // { // } // return res; //} /// <summary> /// Transfer from device to computer /// Source : http://cgeers.com/2011/08/13/wpd-transferring-content/ /// </summary> /// <param name="deviceObject"></param> /// <param name="fileName"></param> public void SaveFile(PortableDeviceObject deviceObject, string fileName) { IPortableDeviceContent content; portableDeviceClass.Content(out content); IPortableDeviceResources resources; content.Transfer(out resources); PortableDeviceApiLib.IStream wpdStream = null; uint optimalTransferSize = 0; var property = PortableDevicePKeys.WPD_RESOURCE_DEFAULT; try { resources.GetStream(deviceObject.ID, ref property, 0, ref optimalTransferSize, out wpdStream); } catch (COMException comException) { // check if the device is busy, this may hapen when a another transfer not finished if ((uint)comException.ErrorCode == PortableDeviceErrorCodes.ERROR_BUSY) { Thread.Sleep(500); SaveFile(deviceObject, fileName); return; } throw comException; } System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; FileStream targetStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); unsafe { var buffer = new byte[1024 * 256]; int bytesRead; do { sourceStream.Read(buffer, buffer.Length, new IntPtr(&bytesRead)); targetStream.Write(buffer, 0, bytesRead); } while (bytesRead > 0); targetStream.Close(); } }
/// <summary> /// 写入数据 /// </summary> /// <param name="sourceFile"></param> /// <param name="parentId"></param> public bool TransferContentToDevice(string sourceFile, string parentId) { bool bRet = true; IPortableDeviceValues values = GetRequiredPropertiesForContentType(sourceFile, parentId); PortableDeviceApiLib.IStream tempStream = null; uint optimalTransferSize = 0; try { deviceContent.CreateObjectWithPropertiesAndData(values, out tempStream, ref optimalTransferSize, null); System.Runtime.InteropServices.ComTypes.IStream targetStream = (System.Runtime.InteropServices.ComTypes.IStream)tempStream; using (FileStream sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read)) { int filesize = (int)optimalTransferSize; int bytesRead = 0; IntPtr pcbWritten = IntPtr.Zero; do { byte[] buffer = new byte[filesize]; bytesRead = sourceStream.Read(buffer, 0, filesize); targetStream.Write(buffer, bytesRead, pcbWritten); }while (bytesRead > 0); } targetStream.Commit(0); } catch (Exception) { bRet = false; } finally { Marshal.ReleaseComObject(tempStream); } return(bRet); }
/** * Copy To Phone */ public void TransferContentToDevice(PortableDeviceFolder parentFolder, string filePath) { PortableDeviceApiLib.IStream tempStream = null; System.Runtime.InteropServices.ComTypes.IStream targetStream = null; try { string fileName = PortableDeviceFolder.last(filePath, "\\"); // Remove existing remote file, if it exists. parentFolder.DeleteFile(this, fileName); // make sure that we are not holding on to a file. DisconnectConnect(); string parentObjectId = parentFolder.Id; IPortableDeviceContent content = getContents(); IPortableDeviceValues values = GetRequiredPropertiesForContentType(filePath, parentObjectId); uint optimalTransferSizeBytes = 0; content.CreateObjectWithPropertiesAndData( values, out tempStream, ref optimalTransferSizeBytes, null); targetStream = (System.Runtime.InteropServices.ComTypes.IStream)tempStream; long length = new System.IO.FileInfo(filePath).Length; long written = 0; long lPCt = 0; using (var sourceStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var buffer = new byte[optimalTransferSizeBytes]; int bytesRead; do { bytesRead = sourceStream.Read(buffer, 0, (int)optimalTransferSizeBytes); IntPtr PCbWritten = IntPtr.Zero; targetStream.Write(buffer, bytesRead, PCbWritten); written += bytesRead; long PCt = length > 0 ? (100 * written) / length : 100; if (PCt != lPCt) { lPCt = PCt; Console.WriteLine("Progress: " + lPCt); } } while (bytesRead > 0); } targetStream.Commit(0); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } finally { if (null != targetStream) { Marshal.ReleaseComObject(targetStream); } if (null != tempStream) { Marshal.ReleaseComObject(tempStream); } Disconnect(); } }
private bool TransferContentFromDevice(string toFile, string objectId, bool isReadNew = false) { bool bRet = true; string oldFile = Path.GetDirectoryName(toFile) + "\\" + Path.GetFileNameWithoutExtension(toFile) + "_old" + Path.GetExtension(toFile); FileStream fsOld = null; byte[] bufferOld = null; int bytesReadOld = 0; bool isFileNew = false; string folder = Path.GetDirectoryName(toFile); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } if (isReadNew) { if (File.Exists(oldFile)) { File.Delete(oldFile); } if (File.Exists(toFile)) { File.Move(toFile, oldFile); } else { File.Create(oldFile); } fsOld = new FileStream(oldFile, FileMode.Open, FileAccess.Read); bufferOld = new byte[512 * 1024]; } if (File.Exists(toFile)) { File.Delete(toFile); } IPortableDeviceResources resources; deviceContent.Transfer(out resources); PortableDeviceApiLib.IStream wpdStream = null; uint optimalTransferSize = int.MaxValue; try { //设备建议读取长度optimalTransferSize长度一般为262144即256k, resources.GetStream(objectId, ref pKey.WPD_RESOURCE_DEFAULT, 0, ref optimalTransferSize, out wpdStream); System.Runtime.InteropServices.ComTypes.IStream sourceStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; string filename = Path.GetFileName(toFile); FileStream targetStream = new FileStream(toFile, FileMode.Create, FileAccess.Write); { int filesize = (int)optimalTransferSize; byte[] buffer = new byte[filesize]; int bytesRead = 0; IntPtr bytesReadIntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(bytesRead)); do { sourceStream.Read(buffer, filesize, bytesReadIntPtr); bytesRead = Marshal.ReadInt32(bytesReadIntPtr); if (filesize > bytesRead) { filesize = bytesRead; } if (isReadNew && isFileNew == false) { bytesReadOld = fsOld.Read(bufferOld, 0, bytesRead); if (bytesReadOld != bytesRead || IsDataDiff(buffer, bufferOld, bytesRead)) { isFileNew = true; } } targetStream.Write(buffer, 0, filesize); } while (bytesRead > 0); targetStream.Close(); targetStream.Dispose(); Marshal.FreeCoTaskMem(bytesReadIntPtr); } } catch (Exception) { bRet = false; } finally { //若不添此行,在本方法执行一次后再次执行时会报资源占用错误 Marshal.ReleaseComObject(wpdStream); if (isReadNew) { fsOld.Close(); File.Delete(oldFile); bRet = (isFileNew == false && bRet == false ? false : true); } } return(bRet); }
internal void CopyToDevice(string source, string destination, bool overwrite) { IPortableDeviceContent content; ComDeviceObject.Content(out content); string parentObjectId = null; FindParentObjectId(Path.GetDirectoryName(destination), ref parentObjectId); if (string.IsNullOrEmpty(parentObjectId)) { throw new Exception("destination folder has not been found."); } IPortableDeviceValues values = GetRequiredPropertiesForContentType(source, destination, parentObjectId); PortableDeviceApiLib.IStream wpdStream = null; uint optimalTransferSize = 0; content.CreateObjectWithPropertiesAndData( values, out wpdStream, ref optimalTransferSize, null); System.Runtime.InteropServices.ComTypes.IStream targetStream = null; try { targetStream = (System.Runtime.InteropServices.ComTypes.IStream)wpdStream; FileStream sourceStream = new FileStream(source, FileMode.Open, FileAccess.Read); unsafe { try { var buffer = new byte[optimalTransferSize]; int bytesRead; do { bytesRead = sourceStream.Read(buffer, 0, (int)optimalTransferSize); IntPtr pcbWritten = IntPtr.Zero; if (bytesRead < (int)optimalTransferSize) { targetStream.Write(buffer, bytesRead, pcbWritten); } else { targetStream.Write(buffer, (int)optimalTransferSize, pcbWritten); } } while (bytesRead > 0); targetStream.Commit(0); } catch (ArgumentException e) { throw new Exception("Some argument has problem, remember this API can't overwrite" + "file on the device side! message: " + e.Message); } finally { sourceStream.Close(); } } } finally { Marshal.ReleaseComObject(wpdStream); Marshal.ReleaseComObject(targetStream); } }