Я прочитал некоторую документацию, и вот класс, я использую для операций 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);
Был бы признателен, если бы кто-то взглянул и сказал, если я все сделаю правильно, или этот метод нужно переадресовать.
Нет, это не выглядит хорошо. Пункт SafeHandle состоит в том, чтобы гарантировать, что ваш объект класса не будет уничтожен, пока вы передадите дескриптор на собственный код. Это может быть неприятно, ваш финализатор вызывается, а собственный код продолжает использовать недопустимый дескриптор. Помимо сбоев во время выполнения и коррупции, которые могут вызывать, существует также очень страшный сценарий атаки на перезагрузку дескриптора, который активируется этим.
Однако у вас нет абсолютно никакого контроля над временем работы этого дескриптора окна. Вы не можете остановить его от разрушения и не можете ничего сделать, чтобы уничтожить его самостоятельно. Ну, предполагая, что вы не собираетесь убивать процесс с помощью финализатора. Что-то, что вы могли обнаружить, не имея полезного переопределения для ReleaseHandle(). Используйте, скажем, класс SafeFileHandle в качестве примера практического производного класса. У.NET Framework много, хороший декомпилятор - отличный способ найти их.
Короче говоря, поскольку нет смысла обертывать его, IntPtr в порядке
SafeHandleZeroOrMinusOneIsInvalid
чтобы убедиться, что дескрипторы правильно закрыты, например, с помощьюCloseHandle
.HWND
не такая ручка. Вам не нужно наследовать от класса safehandle, чтобы передать его. Если бы это был такой тип дескриптора, вы быCloseHandle(this.handle)
изReleaseHandle
. Не пытайтесь избавиться от объекта оттуда.