本文介绍了SafeFileHandle.Close抛出一个异常,但手柄是有效的,作品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与在WPF应用程序自定义光标一个问题。我用下面的代码来创建光标对象:

I'm having a problem with custom cursors in a WPF application. I use the following code to create the Cursor objects:

[DllImport("user32.dll")]
private static extern IntPtr CreateIconIndirect(ref IconInfo icon);

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetIconInfo(IntPtr hIcon, ref IconInfo pIconInfo);

private static Cursor CreateCursor(string cursorName, System.Drawing.Bitmap bmp,
    int xHotspot, int yHotspot, out SafeFileHandle handle)
{
    IconInfo tmp = new IconInfo();
    GetIconInfo(bmp.GetHicon(), ref tmp);
    tmp.xHotspot = xHotspot;
    tmp.yHotspot = yHotspot;
    tmp.fIcon = false;

    IntPtr ptr = CreateIconIndirect(ref tmp);
    handle = new SafeFileHandle(ptr, true);

    if (handle.IsClosed)
    {
        return null;
    }

    Cursor cur = CursorInteropHelper.Create(handle);

    return cur;
}

当我关闭我的应用程序和GC开始拿起垃圾桶,它抛出一个例外:

When I close my application and GC starts picking up the trash, it throws an exception:

System.Runtime.InteropServices.SEHException was unhandled
  Message=External component has thrown an exception.
  Source=mscorlib
  ErrorCode=-2147467259
  StackTrace:
       at Microsoft.Win32.Win32Native.CloseHandle(IntPtr handle)
       at Microsoft.Win32.SafeHandles.SafeFileHandle.ReleaseHandle()
       at System.Runtime.InteropServices.SafeHandle.InternalDispose()
       at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
       at System.Runtime.InteropServices.SafeHandle.Dispose()
       at System.Windows.Input.Cursor.Finalize()
  InnerException:

我没有通过放置如果(handle.IsClosed)断点,并使用即时窗口调用 handle.Close一些进一步的调查( )。有些 SafeFileHandle 的亲密就好,别人抛出同样的异常—后,立即把手已创建。

I did some further investigation by placing a breakpoint on if (handle.IsClosed) and using the immediate window to call handle.Close(). Some of the SafeFileHandle's close just fine, others throw the same exception — immediately after the handle was created.

而只是为了让事情有趣,在处理自己的工作就好了。 IsInvalid 为假, isClosed返是假的,光标出现。这只是一些把手不能被关闭。

And just to make things fun, the handles themselves work just fine. IsInvalid is false, IsClosed is false, and the cursors appear. It's just that some of the handles can never be closed.

由于我从来没有打算手动关闭句柄,他们将只在<$ C定稿过程中被关闭$ C>光标对象的应用程序关闭时,我也许可以不理会他们。我没有试过一个发布版本外VS2010,我不知道这是否会导致出现崩溃对话框。但是,即使我可以忽略它们,它仍然是混乱的。

As I never intend to close the handles manually, and they will only be closed during finalization of the Cursor objects when the application closes, I might be able to just ignore them. I haven't tried a Release build outside VS2010 and I don't know if that will cause a crash dialog to appear. But even if I can ignore them, it's still messy.

所以基本上我在寻找什么可能会在这里走错了,在这里任何信息看,试图这个调试......一切似乎都在本机代码或GC,我不能调试任何它。

So basically I'm looking for any info on what might be going wrong here, where to look to try and debug this... everything seems to be in native code or GC and I can't debug any of it.

推荐答案

您'重新包装的惠康 CreateIconIndirect 在返回 SafeFileHandle 其中,在释放,来电 CloseHandle的上的惠康而不是所需要的 DestroyIcon 。不裹惠康 SafeFileHandle ,而是在自己的专业的SafeHandle

You're wrapping the HICON returned from CreateIconIndirect in a SafeFileHandle which, on releasing, calls CloseHandle on the HICON instead of the needed DestroyIcon. Don't wrap HICON in SafeFileHandle but instead in an own, specialized SafeHandle:

class SafeIconHandle : SafeHandleZeroOrMinusOneIsInvalid
{
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool DestroyIcon(
        [In] IntPtr hIcon);

    private SafeIconHandle()
        : base(true)
    {
    }

    public SafeIconHandle(IntPtr hIcon)
        : base(true)
    {
        this.SetHandle(hIcon);
    }

    protected override bool ReleaseHandle()
    {
        return DestroyIcon(this.handle);
    }
}

这篇关于SafeFileHandle.Close抛出一个异常,但手柄是有效的,作品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 14:49