如何正确释放SafeHandleZeroOrMinusOneIsInvalid或SafeHandle?

Ole*_*sii 2 .net c# 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

主要问题在ReleaseHandle方法中。我已经以这种方式使用过它,但我很好奇这是否是正确的使用方式?可能还有另一种正确的方法来释放句柄并清除此类?

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

Process p = Process.Start(processName);
MySafeHandleOperator mh = new MySafeHandleOperator(p.MainWindowHandle);
Run Code Online (Sandbox Code Playgroud)

如果有人能看一下并说我是否做对了一切,或者这个方法需要重写,我将不胜感激。

Han*_*ant 5

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

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

长话短说,因为包装它没有意义,IntPtr 没问题