2015-05-09 56 views
2

我試圖通過電纜將Android設備連接到一個(64位Windows 7)PC,然後從Android編程方式檢索一些文件到PC。 (注:我需要一個特定的設備,Moverio BT-200,並且我遇到了驅動程序問題;所以不建議使用adb ;-)我知道這是簡單和快速的方式,但它不是可行)如何將文件從Android設備使用USB傳輸到PC和/或WPD

我發現,我的設備可以被看作是一個Windows便攜式設備(WPD)。我在C#中找到了一些非常好的代碼示例,它使我可以使用detect WPDs,enumerate their contentstransfer the contents。我還在C++中找到了一些代碼,其代碼爲all of the above and much more。所有這些例子的作用就像一個魅力,只要我連接一個單一的SD卡或一個USB密鑰(即:只要我有一個設備被Windows識別並獲得一個字母作爲正確的驅動器),我得到目前文件的完整列表及其絕對路徑。但是,如果我嘗試連接Android設備,並列出內容,我得到的東西,我不明白:

embt2 
SD Card 
o15F9A 
o15F9B 
o15F9C 
o15F9D 
o15F9E 
...etc 
Internal Storage 
o1 
o2 
o3 
o4 
o5 
o6 
oD1F 
oD20 
oD24 
o7 
o8 
o1E78 
o9 
...etc 

這怎麼可能?瀏覽C#代碼(第二個鏈接,上面),我發現,在某些點,代碼創建了幾個GUID對象,每個都與一些稍有不同的參數:

// Identify the property to retrieve 
var property = new _tagpropertykey(); 
property.fmtid = new Guid(0x26D4979A, 0xE643, 0x4626, 0x9E, 0x2B, 
             0x73, 0x6D, 0xC0, 0xC9, 0x2F, 0xDC); 
property.pid = 12; 

[...] 

// Get the name of the object 
string name; 
var property = new _tagpropertykey(); 
property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
            0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C); 
property.pid = 4; 

[...] 

// Get the type of the object 
property = new _tagpropertykey(); 
property.fmtid = new Guid(0xEF6B490D, 0x5CD8, 0x437A, 0xAF, 0xFC, 
            0xDA, 0x8B, 0x60, 0xEE, 0x4A, 0x3C); 
property.pid = 7; 

[...] 

var folderType = new Guid(0x27E2E392, 0xA111, 0x48E0, 0xAB, 0x0C, 
            0xE1, 0x77, 0x05, 0xA0, 0x5F, 0x85); 
var functionalType = new Guid(0x99ED0160, 0x17FF, 0x4C44, 0x9D, 0x98, 
             0x1D, 0x7A, 0x6F, 0x94, 0x19, 0x21); 

但我無法弄清楚如何將這些exadecimal值工作。網上的文件似乎很少。我發現我的設備guid與設備管理器({eec5ad98-8080-425f-922a-dabf3de3f69a} ),但每次我試圖用我自己的GUID替換之一,我得到一個COMException。

我是否找對了地方?我需要設置一些GUID還是其他?

我標記這個問題,C#和C++,因爲我發現這兩種語言的一些代碼示例,但我願意解決任何語言問題(使用Java,Python,...)

+0

我不認爲所顯示的代碼可以編譯,因爲它重新聲明瞭名稱「property」。無論如何,它只是創建'Guid'對象。閱讀Wikipedia中的GUID。 –

+0

@Cheers這不是確切的代碼:我只是複製粘貼來自原始項目中不同位置的代碼塊。閱讀第二個鏈接以獲得完整的解釋。 (是的,它會編譯,因爲這是一段精確的代碼,只是覆蓋相同的變量)。我真的不認爲維基百科頁面可以解決我的問題。所有的GUID都是我的猜測,我不確定我的問題在那裏。 – ocramot

+0

*如果它不是用於多個「var」,它會進行編譯。我的錯。 – ocramot

回答

1

爲了記錄,我最終使用了一些可怕的黑客來解決我的問題。 因爲我知道在哪裏存儲我找,我從克里斯托夫吉爾的博客使用的功能EnumerateContent文件,並修改了路徑,以檢查是否當前文件夾中有我在尋找的名字:

如果,例如,我感興趣的文件是在Sd Card/path/to/directory/,然後我適應這樣的代碼:而不是調用方法EnumerateContents,我調用該方法EnumerateContentsInTargetDirectory

private static void EnumerateContentsInTargetDirectory(ref IPortableDeviceContent content, PortableDeviceFolder parent) 
{ 
    // Get the properties of the object 
    IPortableDeviceProperties properties; 
    content.Properties(out properties); 

    // Enumerate the items contained by the current object 
    IEnumPortableDeviceObjectIDs objectIds; 
    content.EnumObjects(0, parent.Id, null, out objectIds); 

    uint fetched = 0; 
    do 
    { 
     string objectId; 

     objectIds.Next(1, out objectId, ref fetched); 
     if (fetched > 0) 
     { 
      var currentObject = WrapObject(properties, objectId); 

      if (currentObject is PortableDeviceFolder) 
      { 
       if (currentObject.Name.Equals("SD Card") || currentObject.Name.Equals("path") || currentObject.Name.Equals("to")) 
       { 
        parent.Files.Add(currentObject); 
        EnumerateContentsInTargetDirectory(ref content, (PortableDeviceFolder)currentObject); 
       } 
       else if (currentObject.Name.Equals("directory")) 
       { 
        parent.Files.Add(currentObject); 
        // This is the same original method of Christophe Geer. 
        EnumerateContents(ref content, (PortableDeviceFolder)currentObject); 
       } 
      } 
     } 
    } while (fetched > 0); 

}

1

什麼與所有奇怪的文件名?你貼了很多與o後跟一個十六進制數字開頭的條目的第一個單子都是PTP/MTP物品惟一標識符,讓你可以參考文件的遠程設備上的項目。這些都是正常的並且是PTP和MTP協議的一部分,它們是PTP和MTP協議中全部項目枚舉和文件傳輸系統的許多數據片段之一。

什麼是與所有的GUID和細微變化的交易嗎?這基本上是USB HID(硬件識別)協議在封面下的工作原理 - 具體說明Microsoft如何實現它。 GUID是Microsoft代碼,鏈接到USB驅動程序中的HID路徑,然後調用USB設備獲取信息(獲取或設置信息)。每個HID命令還使用PID(產品標識符)來尋址HID路徑或命令中的特定內存位置,因此在HID命令中傳遞不同的PID會導致在USB設備上獲取/設置不同的數據。

什麼是有點悲哀和可怕的是微軟如何揭露了這個非常低級的互動達到高水平的工程師和程序。他們的文檔並沒有提供很多有用的背景信息或解釋這些東西是什麼和手段。如果你想要更多可靠的示例代碼和背景,我強烈建議檢查Christophe Geer's blogs關於在C#/ .Net中使用WPD - 他們真的幫了我很多。看到他的follow-up blog on transferring content更多的好東西。

另一條建議可能會有所幫助 - 您可以在整個PID範圍內找到哪些信息。只要包裝你的偷看和戳在try/catch塊,以防他們失敗。我爲來自Christophe Geer的代碼構建了一個額外的小竅門,在他的示例中窺探了所有HID GUID的PID 0-31,並發現了大量額外且有用的信息。

+0

嗨tpartee,謝謝!你的回答並沒有真正幫我解決我的問題,但肯定包含了很多有趣的信息! (除了這兩個鏈接,你可能沒有注意到,我已經把它們自己鏈接起來了,在我的第一個問題中;-))。謝謝你的時間。我已經解決了一些可怕的黑客攻擊。 – ocramot

+1

這讓我很難過,但整個系統對微軟來說似乎是一個可怕的破解。所以任何能夠發揮作用的東西都必然會成爲黑客。 ;)目前我試圖找到一個解決方法的最大問題是,Windows WPD和WIA似乎只能夠支持USB 1.0速度 - 連接USB 3.0設備和電纜不會提高速度。 = / – tpartee

相關問題