簡體   English   中英

使用WPD(Windows便攜設備)Apis傳輸圖像文件時出錯

[英]Errors while using WPD (Windows Portable Device) Apis for transferring image files

我一直在嘗試使用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設備的制造商/型號等,將會很有幫助。

此錯誤相當通用,可能意味着參數格式不正確,或者您在調用CreateObjectWithPropertiesAndData時給出了范圍參數。 如果是這種情況,那么它將有助於顯示您傳遞到設備中的參數的值。

我一直在研究同樣的錯誤已經有一段時間了,我想我可能已經找到了它。 就我而言,問題出在代碼設置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 );

無論如何,我希望這有幫助!

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();

我搜索了很長時間才找到一個完整的解決方案,這就是。

我首先想給Christophe Geer一個非常大的手。 他是我發現的唯一一個在c#中使用WPD(Windows便攜設備)將數據傳輸到手機的人。

我只需要修復一些錯誤,並且只添加了一些我添加的重要功能,例如文件大小和復制文件夾。

結果是一組PortableDevice文件,可用於執行大多數所需的CRUD操作。

查看我的github網站以獲取代碼和更多詳細信息:

https://github.com/pstorli/WPDFileTransfer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM