2017-02-27 48 views
1

我需要枚舉MTP android設備的內容並將文件從設備傳輸到Windows PC。WPD API - 無法傳輸來自設備的內容(包含SSCCE)

按照這裏找到的指南Transferring Content from a Device to a PC我試圖將簡單的文本文檔轉移到指定的目錄。但是,輸出文件總是空,即使在返回值指出X number of bytes have been written.

我只使用了推薦的Windows API調用來輕鬆地重現該問題創造了一個SSCCE。我使用API​​文檔和official sample project作爲參考。

main.cpp

Qt project file

爲了測試,我已經通過MTP連接上稱爲testFolder根文件夾的Android手機和裏邊有一個文件testfile.txt與文本hello world。在運行此應用程序時,輸出表明已寫入11個字節,但文件爲空。請自己嘗試一下嗎?

我似乎無法理解爲什麼文件總是空的。有任何想法嗎?

謝謝你的時間。

+0

與Qt沒有太大的關係,但是使用Win32 API。很難認識到你的代碼出了什麼問題,但你可以嘗試獲得最後的錯誤和描述:https://msdn.microsoft.com/en-us/library/windows/desktop/ms680582(v=vs.85 ).aspx – AlexanderVX

+0

@AlexanderVX謝謝!剛剛實施,並沒有錯誤。還調用'GetLastError()'返回0.我最大的困難是該文件已創建,並且StreamCopy報告已寫入8個字節。這是我直接從示例https://github.com/pauldotknopf/WindowsSDK7-Samples/blob/master/multimedia/wpd/wpdapisample/cpp/ContentTransfer.cpp#L80 – mrg95

+0

這個我的確切實現也許that outputPath.toStdWString( ).c_str()使wchar_t的寬字符字符串,但流預計字符?然後寬字符的一個字節的零出現並且被轉換爲字符串的結尾? – AlexanderVX

回答

2
hr = SHCreateStreamOnFile(strOriginalFileName, STGM_CREATE|STGM_WRITE, &finalFileStream); 

它通常有助於識別常見的編碼模式。無論何時創建文件,都必須始終關閉文件。在C語言中你有fopen(),你必須調用fclose()。在winapi中你有CreateFile(),你必須調用CloseHandle()。即使在很多資源管理是自動化的運行時環境中,如.NET,創建FileStream時,也必須調用Close()或使用聲明來使用

該代碼沒有做任何事情明確關閉finalFileStream

這有後果,你找到了一個。由於內存泄漏,SHCreateStreamOnFile的實現不知道何時將任何緩衝但尚未寫入的數據刷新到文件中。所以你最終得到一個沒有內容的文件。

任何接口指針(如IStream)的合同都是您總是必須顯式調用其Release()函數。請注意,代碼忘記了這一點,它始終如一地使用所有它使用的接口指針。不是唯一的問題,當你調用CoInitialize/Ex()時,你必須調用CoUninitialize()。只要使用黃金法則,你總是必須在這樣的代碼中明確清理。

修復:

hr = StreamCopy(finalFileStream, ...); 
    if (FAILED(hr)) saysomething(hr);   // Forgotten in original code 
    finalFileStream->Release();    // Now it is good. 

您可以在C使用智能指針類型++像CComPtr<>得到它自動地完成。

+0

啊!現在有道理。我現在看到API說要使用CComPtr <>,我正在爲Windows 7開發,這不是一個選項。我會試一試,然後接受答案。非常感謝! – mrg95