1

我在 C# 中实现了一个基于 GUID 枚举设备的 SetupAPI 包装器。我或多或少地将 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);

我的回调定义如下:

    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