Генерация IntPtr с использованием Convert.ToInt64, сбои в приложениях x64

Я пытаюсь использовать код из наиболее популярного ответа на этот вопрос: используя C#, как определить, какой процесс заблокировал файл?

Я тестирую этот код в Windows 7 x64, используя VS2010 и.NET v4.

Я обнаружил, что фрагмент кода...

var baTemp = new byte[nLength];
try
{
    Marshal.Copy(ipTemp, baTemp, 0, nLength);
    strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));
}
catch (AccessViolationException)
{
    return null;
}
finally
{
    Marshal.FreeHGlobal(ipObjectName);
    Win32API.CloseHandle(ipHandle);
}

это то, что вызывает мои проблемы. Marshal.Copy может завершиться ошибкой, если ранее созданный адрес недействителен. Код, создающий адрес в системах x64...

if (Is64Bits())
{
    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
}

в одном случае мои отмеченные сбои начинаются с представления строки буфера 20588995036390572032, которое переводится в x1C92AA2089E00000. Похоже, код удаляет младшее слово, оставляя x1C92AA20 в качестве используемого адреса.

Вопрос 1: Почему бы нам просто не использовать 64-битный адрес, предоставленный объектом буфера, вместо того, чтобы смещать младшее слово и использовать только старшее слово в 64-битном приложении, работающем на 64-битной ОС?

Вопрос 2: должен ли блок try/catch/finally включать в себя больше, чем просто AccessViolationException?

1 ответ

Прочитайте комментарии к этой статье. Неработающий код. Не работает Не используйте. Даже "предложенная" исправленная версия не работает (и она не работает на моей Win8 64bit) и, по словам ее автора:

Следующее было произведено на основе дампа кода Iain Ballard. Он сломан: он иногда блокируется при получении имени дескриптора. Этот код не содержит обходных путей для этой проблемы, и.NET оставляет несколько вариантов: Thread.Abort больше не может прерывать поток, который в настоящее время находится в собственном методе.

Другие вопросы по тегам