如何正确释放SafeHandleZeroOrMinusOneIsInvalid或SafeHandle?

时间:2015-01-18 18:36:15

标签: c# .net unmanaged handle intptr

我已经阅读了一些文档,这里是类,我正在使用IntPtr操作来使它们更安全:

internal class MySafeHandleOperator : SafeHandleZeroOrMinusOneIsInvalid
{
    public MySafeHandleOperator(IntPtr handle) : base(true)
    {
        SetHandle(handle);
    }

    public IntPtr GetPtr()
    {
        return this.handle;
    }

    protected override bool ReleaseHandle()
    {
        this.Dispose(true);
        return true;
    }
}

主要问题在于ReleaseHandle方法。我已经以这种方式使用它了,但如果这是一种正确的使用方式我会被诅咒吗?可能有另一个正确的方法来释放句柄并清除这个类吗?

我想以类似的方式使用这个类(一个简单的例子):

Process p = Process.Start(processName);
MySafeHandleOperator mh = new MySafeHandleOperator(p.MainWindowHandle);

如果有人看一看并说我做的一切正确,或者这种方法需要重新编写,我将不胜感激。

1 个答案:

答案 0 :(得分:4)

不,这看起来不太好。 SafeHandle的目的是确保在将句柄传递给本机代码时不会破坏类对象。这可能很讨厌,你的终结器被调用,本机代码继续使用无效的句柄。除了可能导致的运行时故障和损坏之外,还有一个非常可怕的句柄回收攻击场景,由此启用。

然而,您完全无法控制该窗口句柄的生命周期。你不能阻止它被摧毁,也不能做任何事情来自己摧毁它。好吧,假设您不打算使用终结器杀死进程。你可以通过没有ReleaseHandle()的有用覆盖来找到的东西。例如,使用SafeFileHandle class作为实际派生类的示例。 .NET Framework有很多,一个好的反编译器是找到它们的绝佳方法。

长话短说,因为包装它没有意义,IntPtr很好