我在 WPF 应用程序中遇到自定义游标问题。我使用以下代码创建 Cursor
对象:
[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 开始清理垃圾时,它会抛出一个异常:
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:
我通过在 if (handle.IsClosed)
上放置断点并使用即时窗口调用 handle.Close()
进行了进一步调查。一些 SafeFileHandle
的关闭很好,其他的则抛出相同的异常 — 在句柄创建后立即。
为了让事情变得有趣, Handlebars 本身也能正常工作。 IsInvalid
为假,IsClosed
为假,光标出现。只是有些句柄永远关不上。
因为我从未打算手动关闭句柄,并且它们只会在应用程序关闭时 Cursor
对象的最终确定期间关闭,所以我可以忽略它们。我没有尝试过 VS2010 之外的发布版本,我不知道这是否会导致出现崩溃对话框。但即使我可以忽略它们,它仍然很乱。
所以基本上我正在寻找任何关于这里可能出现问题的信息,在哪里尝试和调试它......一切似乎都在 native 代码或 GC 中,我无法调试它们中的任何一个。
最佳答案
您将从 CreateIconIndirect
返回的 HICON
包装在 SafeFileHandle
中,释放时调用 CloseHandle
在 HICON
而不是所需的 DestroyIcon
上。不要将 HICON
包装在 SafeFileHandle
中,而是将其包装在自己的专用 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);
}
}
关于c# - SafeFileHandle.Close 抛出异常但句柄有效且有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9218029/