GUID に基づいてデバイスを列挙する SetupAPI ラッパーを C# で実装しました。私は多かれ少なかれ、MSDN にある DevCon の c++ サンプル コードを C# に変換しました (はい、.NET でこれを行うのは非常に困難であることは十分承知していますが、楽しくてやりがいがあります)。
特定のデバイスに関するすべての適切な情報を取得できますが、「SetupScanFileQueue」メソッドに到達したときに問題が発生しました。
「SetupScanFileQueue」を作成してコールバックを呼び出すことができないようです。メソッドは true を返すので、機能しているようです。
私の最終目標は、特定のデバイスのドライバー ファイルを取得することです。
追加情報: ファイルは FileQueue に正しく追加されているように見えます。正しいファイルをコピーしているように見えるこのポップアップ ウィンドウが表示されます。
// create a file queue so we can look at this queue later
var queueHandler = SetupOpenFileQueue();
if (queueHandler == IntPtr.Zero)
return false;
// modify flags to indicate we're providing our own queue
var deviceInstallParams = new SP_DEVINSTALL_PARAMS();
deviceInstallParams.cbSize = Marshal.SizeOf(deviceInstallParams);
if (!SetupDiGetDeviceInstallParams(handle, ref devInfo, ref deviceInstallParams))
{
error = Marshal.GetLastWin32Error();
return false;
}
// we want to add the files to the file queue, not install them!
deviceInstallParams.FileQueue = queueHandler;
deviceInstallParams.Flags |= DI_NOVCP;
if (!SetupDiGetDeviceInstallParams(handle, ref devInfo, ref deviceInstallParams))
{
error = Marshal.GetLastWin32Error();
return false;
}
// now fill queue with files that are to be installed
// this involves all class/co-installers
if (!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, handle, ref devInfo))
{
error = Marshal.GetLastWin32Error();
return false;
}
// we now have a list of delete/rename/copy files
// iterate the copy queue twice - 1st time to get # of files
// 2nd time to get files
// (WinXP has API to get # of files, but we want this to work
// on Win2k too)
var scanResult = 0;
var count = 0;
var callback = new PSP_FILE_CALLBACK(PSP_FILEFOUND_CALLBACK);
var t = SetupScanFileQueue(queueHandler, SPQ_SCAN_USE_CALLBACK, IntPtr.Zero,
callback, ref count, ref scanResult);
SetupDiDestroyDriverInfoList(handle, ref devInfo, SPDIT_CLASSDRIVER);
if (queueHandler != IntPtr.Zero)
SetupCloseFileQueue(queueHandler);
私の Callback の定義は次のとおりです。
public delegate uint PSP_FILE_CALLBACK(uint context, uint notifaction, IntPtr param1, IntPtr param2);
public static uint PSP_FILEFOUND_CALLBACK(uint context, uint notifaction, IntPtr param1, IntPtr param2)
{
//This callback is never triggered
return 0;
}
「SetupScanFileQueue」関数で私が間違っていること、およびコールバックが呼び出されない理由について何か提案はありますか?
どんな助けでも大歓迎です!
編集:
SetupScanFileQueue 関数の DllImport も追加する必要がありました。
[DllImport("setupapi.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
private static extern uint SetupScanFileQueue(IntPtr QueueHandle,
int Flags,
IntPtr Window,
PSP_FILE_CALLBACK CallbackRoutine,
int CallbackContext,
out int ScanResult
);
CallingConvention なしでも試してみました。