使用WPD(Windows便携设备)Apis传输图像文件时出错

我一直在尝试使用WPD Apis在c#中编写一个示例应用程序,用于将图像文件传输到连接的WPD支持的设备。 我一直关注这个链接。 我的问题是每次我尝试传输文件时我都会收到错误:值不在预期范围内。 有没有人试过成功做同样的事情。 任何指针都非常感谢。

下面是我面临错误的代码片段

IPortableDeviceContent content; this._device.Content(out content); IPortableDeviceValues values = GetRequiredPropertiesForContentType(fileName, parentObjectId); PortableDeviceApiLib.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 (var sourceStream = new FileStream(fileName, 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, (int)optimalTransferSizeBytes, pcbWritten); } while (bytesRead > 0); } targetStream.Commit(0); } finally { Marshal.ReleaseComObject(tempStream); } 

错误出现在targetStream.Write行中(…以下是我如何设置参数。我认为我设置的参数有问题,或者我错过了一些必需的参数。

 IPortableDeviceValues values = new PortableDeviceTypesLib.PortableDeviceValues() as IPortableDeviceValues; var 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, parentObjectId); FileInfo fileInfo = new FileInfo(fileName); var 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; values.SetUnsignedLargeIntegerValue(WPD_OBJECT_SIZE, (ulong) fileInfo.Length); var 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(fileName)); var 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(fileName)); var WPD_OBJECT_FORMAT = new _tagpropertykey(); WPD_OBJECT_FORMAT.fmtid = new Guid(0xef2107d5, 0xa52a, 0x4243, 0xa2, 0x6b, 0x62, 0xd4, 0x17, 0x6d, 0x76, 0x03); WPD_OBJECT_FORMAT.pid = 6; values.SetGuidValue(WPD_OBJECT_FORMAT, WPD_OBJECT_FORMAT.fmtid); 

我一直在研究同样的错误已经有一段时间了,我想我可能已经找到了它。 就我而言,问题出在代码设置WPD_PARENT_OBJECT_ID中

在大多数示例中,我看到每个人都像这样设置对象ID:

 string parentObjectId = "InternalStorage/SomeFolder/Parent"; var 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, parentObjectId); 

但实际上,他们确实需要文件夹的id,这与文件夹路径完全不同。

 //The object id depends on what the device assigns to the folder string parentObjectId = "o6AC"; //Just as an example from my device var 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 ; 

当我以这种方式设置我的值时,目标流没有写入设备的问题。

只是为了获得一些额外的背景信息,对象id来自IPortableDeviceContent变量

 IPortableDeviceContent content; Device.Content( out content ); //Device should be set elseware IEnumPortableDeviceObjectIDs objectIds; content.EnumObjects( 0, parent.Id, null, out objectIds ); //objectIds is a collection of all the objects uint fetched; //lets us know if an object was grabbed or not //This is the actual Object Id of that specific folder on the device //Populated by the ObjectIds.Next function string ActualObjectId; objectIds.Next( 1, out ActualObjectId, ref fetched ); 

无论如何,我希望这有帮助!

如果您可以提供更多详细信息,例如代码的哪一行给出此错误,您尝试使用的WPD设备的制造商/型号等,将会很有帮助。

此错误相当通用,可能意味着参数格式不正确,或者您在调用CreateObjectWithPropertiesAndData时给出了范围参数。 如果是这种情况,那么它将有助于显示您传递到设备中的参数的值。

Valence Palacio的答案有效!

您可以从此处下载该示例的源代码,以使用WPDApi将文件传输到便携式设备( https://dl.dropboxusercontent.com/u/40603470/WPDTransferToDevice.zip )。 只需记住使用文件夹的ID(例如o6AC)而不是完整路径。

 var devices = new PortableDeviceCollection(); devices.Refresh(); var kindle = devices.First(); kindle.Connect(); kindle.TransferContentToDevice(@"d:\temp\Kindle_Users_Guide.azw", "06AC"); kindle.Disconnect();