我有一個類可以讓我關閉給定進程中的進程句柄。我有基礎知識,它在Win7 x64中完美運行,但是當我在WinXP x86中運行它時,它會掛起,我不明白爲什麼。我覺得我錯過了一些相當明顯的東西,在這裏。掛在WinXPx32中的NtQuerySystemInformation,但在Win7x64中工作正常
public static List<handleFinder.SYSTEM_HANDLE_INFORMATION>
GetHandles(Process process = null, string IN_strObjectTypeName = null, string IN_strObjectName = null)
{
int nLength = 0;
int nHandleInfoSize = 0x10000;
IntPtr ipHandle = IntPtr.Zero;
IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize);
uint nStatus;
while ((nStatus = handleFinder.NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer,nHandleInfoSize, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
nHandleInfoSize = nLength;
Marshal.FreeHGlobal(ipHandlePointer);
ipHandlePointer = Marshal.AllocHGlobal(nLength);
}
byte[] baTemp = new byte[nLength];
Marshal.Copy(ipHandlePointer, baTemp, 0, nLength);
long lHandleCount = 0;
if (Is64Bits())
{
lHandleCount = Marshal.ReadInt64(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8);
}
else
{
lHandleCount = Marshal.ReadInt32(ipHandlePointer);
ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4);
}
handleFinder.SYSTEM_HANDLE_INFORMATION shHandle;
List<handleFinder.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<handleFinder.SYSTEM_HANDLE_INFORMATION>();
for (long lIndex = 0; lIndex < lHandleCount; lIndex++)
{
shHandle = new handleFinder.SYSTEM_HANDLE_INFORMATION();
if (Is64Bits())
{
shHandle = (handleFinder.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 8);
}
else
{
ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle));
shHandle = (handleFinder.SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());
}
if (process != null)
{
if (shHandle.ProcessID != process.Id) continue;
}
string strObjectTypeName = "";
if (IN_strObjectTypeName != null)
{
strObjectTypeName = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
if (strObjectTypeName != IN_strObjectTypeName) continue;
}
string strObjectName = "";
if (IN_strObjectName != null)
{
strObjectName = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
if (strObjectName != IN_strObjectName) continue;
}
lstHandles.Add(shHandle);
string strObjectTypeName2 = getObjectTypeName(shHandle, Process.GetProcessById(shHandle.ProcessID));
string strObjectName2 = getObjectName(shHandle, Process.GetProcessById(shHandle.ProcessID));
Console.WriteLine("{0} {1} {2}", shHandle.ProcessID, strObjectTypeName2, strObjectName2);
}
return lstHandles;
}
public static bool Is64Bits()
{
return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false;
}
}
public class HandleKiller
{
public static void doMurderHandle()
{
String ProcessName = "xboxstat";
try
{
Process process = Process.GetProcessesByName(ProcessName)[0];
var handles = Win32Processes.GetHandles(process, "File");
if (handles.Count == 0) throw new System.ArgumentException("No handles found");
foreach (var handle in handles)
{
IntPtr ipHandle = IntPtr.Zero;
if (!handleFinder.DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, handleFinder.GetCurrentProcess(), out ipHandle, 0, false, handleFinder.DUPLICATE_CLOSE_SOURCE))
Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error());
Console.WriteLine("Handle Killed!");
}
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("The process name '{0}' is not currently running", ProcessName);
}
catch (ArgumentException)
{
Console.WriteLine("The Handle '{0}' was not found in the process '{1}'", "", ProcessName);
}
Console.ReadLine();
}
}
}
你確定這是'NtQuerySystemInformation'把懸,而不是其他像'NtQueryObject'? – Mehrdad 2013-04-21 04:28:03
是否有必要產生掛起的所有代碼?你能把它削減到基本要素嗎? – 2013-04-21 04:35:34
感謝關於刪除額外代碼的提示,我很難弄清楚它是NtQueryObject還是NtQuerySystemInformation。當我在斷點後遍歷它時,WinXP中的循環沒有問題,但是如果我嘗試過快地執行它,則會出現錯誤「無法執行操作,因爲進程正在運行」。 – user2303420 2013-04-21 04:41:36