1

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 なしでも試してみました。

4

0 に答える 0