4

我一直在尝试使用 WPD API 在 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);
4

4 回答 4

2

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

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

于 2012-09-10T18:35:38.800 回答
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 );

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

于 2014-06-18T17:10:33.787 回答
0

万斯帕拉西奥的答案有效!

您可以从此处 ( 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();
于 2015-12-01T01:06:26.430 回答
-1

我找了很长时间想出一个完整的解决方案,就是这样。

我首先想给 Christophe Geer 一个很大的帮助。他是我发现的唯一一个在 c# 中使用 WPD(Windows 便携式设备)将数据传输到手机的示例。

我只需要修复一些错误,并且只添加了一些缺少的重要功能,例如文件大小和复制文件夹。

结果是一组可用于执行大部分所需 CRUD 操作的 PortableDevice 文件。

查看我的 github 站点以获取代码和更多详细信息:

https://github.com/pstorli/WPDFileTransfer

于 2019-03-11T22:52:43.340 回答