14

WindowsポータブルデバイスAPIとこのAPIが提供するPortableDeviceManagerを使用して、Windowsで接続されているポータブルデバイスを列挙しようとしています。

MSDNのドキュメントリンクとさまざまなブログのリンクに従ってデバイスIDの列挙を実装しましたが、すべて同じ問題が発生します。複数のデバイスが接続されている場合にのみ、 1つのデバイスのIDを取得できます。

これが私が使用しているC#コードのスニペットです:

PortableDeviceManagerClass deviceManager = new PortableDeviceManagerClass();
deviceManager.RefreshDeviceList();  

uint numberOfDevices = 1;            
deviceManager.GetDevices(null, ref numberOfDevices);

if (numberOfDevices == 0)
{
    return new string[0];
}

string [] deviceIds = new string[numberOfDevices];
deviceManager.GetDevices(ref deviceIds[0], ref numberOfDevices);

return deviceIds;

コンピューターに2つのデバイスが接続されています。1つはリムーバブルUSBメモリスティックで、もう1つはデジタルカメラです。両方がアクティブな場合、カメラのデバイスIDのみが返されます。カメラを無効にすると、リムーバブルUSBスティックのデバイスIDが返されます。

私が間違っていることの方向に私を向けることができるこのAPIの経験を持つ人はいますか?

4

6 に答える 6

19

ジャラン、

WPD チームによる次の投稿を見てください。相互運用アセンブリを修正する方法が記載されています。

http://blogs.msdn.com/b/dimeby8/archive/2006/12/05/enumerating-wpd-devices-in-c.aspx

完全にするために、ここでも答えを述べます。

これは、マーシャリングの制限によるものです。このサンプル コードは、1 つのデバイスのみを検出します。相互運用アセンブリを手動で修正する必要があります。

  • 次のコマンドを使用して、PortableDeviceApi Interop アセンブリを逆アセンブルします。

    ildasm Interop.PortableDeviceApiLib.dll /out:pdapi.il

  • IL をメモ帳で開き、次の文字列を検索します。

    instance void GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs,

  • 上記の文字列のすべてのインスタンスを次の文字列に置き換えます。

    instance void GetDevices([in][out] string[] marshal([]) pPnPDeviceIDs,

  • IL を保存し、次のコマンドを使用して相互運用機能を再アセンブルします。

    ilasm pdapi.il /dll /output=Interop.PortableDeviceApiLib.dll

プロジェクトを再構築します。最初GetDevicesNULLパラメーターを使用して呼び出してデバイスの数を取得し、次に配列を使用して再度呼び出してデバイス ID を取得できるようになりました。

お役に立てれば。

于 2011-05-29T07:34:49.210 に答える
3

受け入れられた回答の更新のみ。

正しい置き換えは次のとおりです。

GetDevices([in][out] string& marshal( lpwstr) pPnPDeviceIDs,

GetDevices([in][out] string[] marshal( lpwstr[]) pPnPDeviceIDs,

アンドリュー・トレバロウによると。

于 2015-11-12T01:31:55.123 に答える
0

githubWPD-.NET-Wrapper - デバイスを列挙し、ファイルを正常にコピーできます。コーディングに時間を費やす必要がありません。開いて、接続して、コピーするだけです...

https://github.com/kumushoq/WPD-.NET-Wrapper/blob/2d502d883b981b8bc57d32389e8280877632f6de/WindowsPortableDeviceNet/Utility.cs

于 2015-07-03T09:39:42.167 に答える
-1

たぶん私は間違っているかもしれdeviceManager.GetDevices(ref deviceIds[0], ref numberOfDevices);ませんが、その行は私には意味がありません。文字列の配列を埋めたい場合は、1 つの文字列だけでなく、配列全体を渡す必要があります。

配列全体が渡される blgs.msdn.comの投稿を見つけました。

string[] deviceIDs = new string[cDevices];
devMgr.GetDevices(deviceIDs, ref cDevices);

ただしあくまで推測です。お役に立てば幸いです。

編集:最初の項目ではなく配列全体が渡さ れるいくつかのコード サンプルを見つけました。-6447ad9fa48d

そして、PortableDeviceApiLib のインポートで VB.NETの問題で正しくない相互運用性が生成されることがわかりました。既定の相互運用性アセンブリが正しくないようです。おそらく、成功する方法は、誰かから正しい相互運用アセンブリを取得して使用することです。または、マネージ コード (C#/VB.NET/...) とネイティブ コードの間に別のブリッジを使用します。C++\CLI は、C++ に十分慣れている場合に適しています。

CodePlex でPortable Device Libプロジェクトを見つけました。これが正しいブリッジである可能性があります。

于 2011-05-28T14:04:48.873 に答える