Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading SHGetFileInfo未将正确的句柄返回到图标_Multithreading_Winforms_Winapi - Fatal编程技术网

Multithreading SHGetFileInfo未将正确的句柄返回到图标

Multithreading SHGetFileInfo未将正确的句柄返回到图标,multithreading,winforms,winapi,Multithreading,Winforms,Winapi,我正在使用SHGetFileInfo函数获取文件夹和不同文件类型的图标。根据这个函数的调用应该从后台线程完成,在调用组件之前,对象模型COM必须用CoInitialize或OleInitialize初始化。 我的代码如下所示: public void SetHlinkImage(string path) { Shell32.OleInitialize(IntPtr.Zero); Task task = Task.Factory.StartNew((

我正在使用SHGetFileInfo函数获取文件夹和不同文件类型的图标。根据这个函数的调用应该从后台线程完成,在调用组件之前,对象模型COM必须用CoInitialize或OleInitialize初始化。 我的代码如下所示:

    public void SetHlinkImage(string path)
    {
        Shell32.OleInitialize(IntPtr.Zero);
        Task task = Task.Factory.StartNew(() => { LoadIcons(path); });
    }

    private void LoadIcons(string path)
    {
        image = GetHlinkImage(path);

        if (OwnerControl.InvokeRequired)
            layout.ModuleControl.BeginInvoke((MethodInvoker)delegate ()
            {
                Shell32.OleUninitialize();
            });
    }

    public Icon GetHlinkImage(string path)
    {
        uint flags = Shell32.SHGFI_ICON | Shell32.SHGFI_ATTRIBUTES | Shell32.SHGFI_SMALLICON;

        Shell32.SHFILEINFO shfi = new Shell32.SHFILEINFO();

        IntPtr result = Shell32.SHGetFileInfo(path,
                            Shell32.FILE_ATTRIBUTE_DIRECTORY,
                            ref shfi,
                            (uint)Marshal.SizeOf(shfi),
                            flags);

        Icon icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone();
        WinApi.DestroyIcon(shfi.hIcon);     // cleanup

        return icon;
    }
大多数情况下,问题出现在第一次调用代码之后,因此,当我尝试从图标句柄创建图标时,出现了一个异常:

System.ArgumentException:传递给图标的Win32句柄不正确 有效或类型错误

代码的进一步调用不会出现问题。 事实上,行为也在某种程度上取决于测试系统。在Windows10系统上很难重现此问题,但在Windows7上,这种情况经常发生


有人遇到过这个问题吗?

来自Hans Passant的评论:


调用OleInitialize是没有意义的,CLR在启动线程之前已经初始化了COM。它失败了,因为你没有检查它的返回值,所以你看不到它。不知道这一点,它只是从那里螺旋上升到无法诊断的痛苦。是的,更多关于Win7的内容。您必须提供一个STA线程,如果需要在后台运行,那么考虑。

不清楚,您是否在调用线程上正确初始化COM。@ IcTestTaby我正在初始化主线程中的COM。调用OLLIALIZITY是毫无意义的,CLR在启动线程之前已经初始化COM。它失败了,因为你没有检查它的返回值,所以你看不到它。不知道这一点,它只是从那里螺旋上升到无法诊断的痛苦。是的,更多关于Win7的内容。您必须提供一个STA线程,如果需要在后台运行,那么请考虑。每个使用COM的线程都必须初始化,并加入一个单元。@IInspectable这可能是过去,特别是将来出现许多其他问题的原因。我将努力缩小这一差距。非常感谢。