Генерация 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 больше не может прерывать поток, который в настоящее время находится в собственном методе.