我一直在尝试使用WPD Apis在c#中编写一个示例应用程序,用于将图像文件传输到连接的WPD支持的设备。 我一直关注THIS链接。我的问题是每次我尝试传输文件时我都会收到错误:值不在预期范围内。 有没有人试过成功做同样的事情。任何指针都非常受欢迎。
以下是我遇到错误的代码段
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);
答案 0 :(得分:2)
如果您可以提供更多详细信息,例如代码的哪一行发出此错误,您尝试使用的WPD设备的制造商/型号等,将会很有帮助。
此错误相当通用,可能意味着参数格式不正确,或者您在调用CreateObjectWithPropertiesAndData时给出了范围参数。如果是这种情况,那么将有助于显示您传入设备的参数值。
答案 1 :(得分:2)
我一直在研究同样的错误已经有一段时间了,我想我可能已经找到了它。就我而言,问题出在代码设置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 );
无论如何,我希望这有帮助!
答案 2 :(得分:0)
Valence Palacio的答案有效!
您可以从此处(https://dl.dropboxusercontent.com/u/40603470/WPDTransferToDevice.zip)下载该示例的源代码,以使用WPDApi将文件传输到便携式设备。请记住使用文件夹的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();
答案 3 :(得分:-1)
我搜索了很长时间才想出一个完整的解决方案。
我首先想给Christophe Geer很大的帮助。他是我发现的唯一一个在c#中具有使用WPD(Windows便携式设备)将数据传输到电话的示例的人。
我只有几个错误需要修复,只有几个重要的功能我没有添加,例如文件大小和复制文件夹。
结果是一组PortableDevice文件,可用于执行大多数所需的CRUD操作。
查看我的github网站以获取代码和更多详细信息: