工作尝试(种类)最后我实际上并不需要Yahia.当我需要远程控制器时,我正在使用本地"控制器.基本上,我的意思是必须使用NtQuerySystemInformation查找HandleValue并使用该句柄,而不是OpenMutex/CreateMutex返回的那个.当然,我无法在某些应用程序上运行它(在屏幕键盘上运行osk.exe),但它在我想要的应用程序上起作用,以防万一有人想要进一步推广它而发布代码.using System;using System.Collections.Generic;using System.Runtime.InteropServices;using System.Diagnostics;using System.Text;using System.Threading;using System.Security.AccessControl;using System.Security.Principal;namespace FileLockInfo{ public class Win32API { [DllImport("ntdll.dll")] public static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax); [DllImport("ntdll.dll")] public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr OpenMutex(UInt32 desiredAccess, bool inheritHandle, string name); [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] public static extern int CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); [DllImport("kernel32.dll")] public static extern IntPtr GetCurrentProcess(); public enum ObjectInformationClass : int { ObjectBasicInformation = 0, ObjectNameInformation = 1, ObjectTypeInformation = 2, ObjectAllTypesInformation = 3, ObjectHandleInformation = 4 } [Flags] public enum ProcessAccessFlags : uint { All = 0x001F0FFF, Terminate = 0x00000001, CreateThread = 0x00000002, VMOperation = 0x00000008, VMRead = 0x00000010, VMWrite = 0x00000020, DupHandle = 0x00000040, SetInformation = 0x00000200, QueryInformation = 0x00000400, Synchronize = 0x00100000 } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_BASIC_INFORMATION { // Information Class 0 public int Attributes; public int GrantedAccess; public int HandleCount; public int PointerCount; public int PagedPoolUsage; public int NonPagedPoolUsage; public int Reserved1; public int Reserved2; public int Reserved3; public int NameInformationLength; public int TypeInformationLength; public int SecurityDescriptorLength; public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime; } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_TYPE_INFORMATION { // Information Class 2 public UNICODE_STRING Name; public int ObjectCount; public int HandleCount; public int Reserved1; public int Reserved2; public int Reserved3; public int Reserved4; public int PeakObjectCount; public int PeakHandleCount; public int Reserved5; public int Reserved6; public int Reserved7; public int Reserved8; public int InvalidAttributes; public GENERIC_MAPPING GenericMapping; public int ValidAccess; public byte Unknown; public byte MaintainHandleDatabase; public int PoolType; public int PagedPoolUsage; public int NonPagedPoolUsage; } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_NAME_INFORMATION { // Information Class 1 public UNICODE_STRING Name; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct UNICODE_STRING { public ushort Length; public ushort MaximumLength; public IntPtr Buffer; } [StructLayout(LayoutKind.Sequential)] public struct GENERIC_MAPPING { public int GenericRead; public int GenericWrite; public int GenericExecute; public int GenericAll; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SYSTEM_HANDLE_INFORMATION { // Information Class 16 public int ProcessID; public byte ObjectTypeNumber; public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT public ushort Handle; public int Object_Pointer; public UInt32 GrantedAccess; } public const int MAX_PATH = 260; public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; public const int DUPLICATE_SAME_ACCESS = 0x2; public const int DUPLICATE_CLOSE_SOURCE = 0x1; } public class Win32Processes { const int CNST_SYSTEM_HANDLE_INFORMATION = 16; const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004; public static string getObjectTypeName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process) { IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id); IntPtr ipHandle = IntPtr.Zero; var objBasic = new Win32API.OBJECT_BASIC_INFORMATION(); IntPtr ipBasic = IntPtr.Zero; var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION(); IntPtr ipObjectType = IntPtr.Zero; IntPtr ipObjectName = IntPtr.Zero; string strObjectTypeName = ""; int nLength = 0; int nReturn = 0; IntPtr ipTemp = IntPtr.Zero; if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS)) return null; ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic)); Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength); objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType()); Marshal.FreeHGlobal(ipBasic); ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength); nLength = objBasic.TypeInformationLength; while ((uint)(nReturn = Win32API.NtQueryObject( ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(ipObjectType); ipObjectType = Marshal.AllocHGlobal(nLength); } objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType()); if (Is64Bits()) { ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32); } else { ipTemp = objObjectType.Name.Buffer; } strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1); Marshal.FreeHGlobal(ipObjectType); return strObjectTypeName; } public static string getObjectName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process) { IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id); IntPtr ipHandle = IntPtr.Zero; var objBasic = new Win32API.OBJECT_BASIC_INFORMATION(); IntPtr ipBasic = IntPtr.Zero; IntPtr ipObjectType = IntPtr.Zero; var objObjectName = new Win32API.OBJECT_NAME_INFORMATION(); IntPtr ipObjectName = IntPtr.Zero; string strObjectName = ""; int nLength = 0; int nReturn = 0; IntPtr ipTemp = IntPtr.Zero; if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS)) return null; ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic)); Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength); objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType()); Marshal.FreeHGlobal(ipBasic); nLength = objBasic.NameInformationLength; ipObjectName = Marshal.AllocHGlobal(nLength); while ((uint)(nReturn = Win32API.NtQueryObject( ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation, ipObjectName, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(ipObjectName); ipObjectName = Marshal.AllocHGlobal(nLength); } objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType()); if (Is64Bits()) { ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32); } else { ipTemp = objObjectName.Name.Buffer; } if (ipTemp != IntPtr.Zero) { byte[] baTemp2 = new byte[nLength]; try { Marshal.Copy(ipTemp, baTemp2, 0, nLength); strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32())); return strObjectName; } catch (AccessViolationException) { return null; } finally { Marshal.FreeHGlobal(ipObjectName); Win32API.CloseHandle(ipHandle); } } return null; } public static List<Win32API.SYSTEM_HANDLE_INFORMATION> GetHandles(Process process = null, string IN_strObjectTypeName = null, string IN_strObjectName = null) { uint nStatus; int nHandleInfoSize = 0x10000; IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize); int nLength = 0; IntPtr ipHandle = IntPtr.Zero; while ((nStatus = Win32API.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); } Win32API.SYSTEM_HANDLE_INFORMATION shHandle; List<Win32API.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<Win32API.SYSTEM_HANDLE_INFORMATION>(); for (long lIndex = 0; lIndex < lHandleCount; lIndex++) { shHandle = new Win32API.SYSTEM_HANDLE_INFORMATION(); if (Is64Bits()) { shHandle = (Win32API.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 = (Win32API.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; } 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); lstHandles.Add(shHandle); } return lstHandles; } public static bool Is64Bits() { return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false; } } class Program { static void Main(string[] args) { String MutexName = "MSCTF.Asm.MutexDefault1"; String ProcessName = "notepad"; try { Process process = Process.GetProcessesByName(ProcessName)[0]; var handles = Win32Processes.GetHandles(process, "Mutant", "\\Sessions\\1\\BaseNamedObjects\\" + MutexName); if (handles.Count == 0) throw new System.ArgumentException("NoMutex", "original"); foreach (var handle in handles) { IntPtr ipHandle = IntPtr.Zero; if (!Win32API.DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_CLOSE_SOURCE)) Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error()); Console.WriteLine("Mutex was killed"); } } catch (IndexOutOfRangeException) { Console.WriteLine("The process name '{0}' is not currently running", ProcessName); } catch (ArgumentException) { Console.WriteLine("The Mutex '{0}' was not found in the process '{1}'", MutexName, ProcessName); } Console.ReadLine(); } }}解决方案为此您需要提升的特权-特别是DEBUG特权.请参阅: 在托管代码中可靠,安全且有效地处理特权 (MSDN) 调试权限 (MSDN) Windows访问控制模型第3部分 Simon Mourier对堆栈溢出问题的回答如何在不诉诸P/Invoke或反射的情况下在.NET中启用SeCreateGlobalPrivilege? 对象安全方法 (MSDN)Using the topic Overview - Handle Enumeration, number 5, the attempt Close mutex of another process and and information from Mutex analysis, the canary in the coal mine and discovering new families of malware/, I have came up with:Attempt 1: http://pastebin.com/QU0WBgE5You must open Notepad first. Needless to say, this is not working for me. I need better error checking to figure out what's going on. I don't know how to get mutex pointers in the format I see them in Process Explorer.My goal is to be able to delete/kill of the mutex handles created by a process so more than one instance can be open. I can do this manually using Process Explorer, but I want to do it programmatically.(Based on Yahia's notes, I need more permissions.)Attempt 2: http://pastebin.com/yyQLhesPAt least now I have some sort of error checking, most of the time DuplicateHandle returns 6 or 5, which is an invalid handle and access denied respectfully.Working attempt (kind of):I actually didn't require anything Yahia stated in the end. I was getting a "local" handle when I needed a remote one. Basically, what I mean is that you have to find the HandleValue using NtQuerySystemInformation and use that handle, not the one returned by OpenMutex / CreateMutex.Granted, I can't get it to work on some applications (osk.exe -- on screen keyboard), but it worked for the application I was going for, posting code in case someone wants to take it further.using System;using System.Collections.Generic;using System.Runtime.InteropServices;using System.Diagnostics;using System.Text;using System.Threading;using System.Security.AccessControl;using System.Security.Principal;namespace FileLockInfo{ public class Win32API { [DllImport("ntdll.dll")] public static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax); [DllImport("ntdll.dll")] public static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr OpenMutex(UInt32 desiredAccess, bool inheritHandle, string name); [DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] public static extern int CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, ushort hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); [DllImport("kernel32.dll")] public static extern IntPtr GetCurrentProcess(); public enum ObjectInformationClass : int { ObjectBasicInformation = 0, ObjectNameInformation = 1, ObjectTypeInformation = 2, ObjectAllTypesInformation = 3, ObjectHandleInformation = 4 } [Flags] public enum ProcessAccessFlags : uint { All = 0x001F0FFF, Terminate = 0x00000001, CreateThread = 0x00000002, VMOperation = 0x00000008, VMRead = 0x00000010, VMWrite = 0x00000020, DupHandle = 0x00000040, SetInformation = 0x00000200, QueryInformation = 0x00000400, Synchronize = 0x00100000 } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_BASIC_INFORMATION { // Information Class 0 public int Attributes; public int GrantedAccess; public int HandleCount; public int PointerCount; public int PagedPoolUsage; public int NonPagedPoolUsage; public int Reserved1; public int Reserved2; public int Reserved3; public int NameInformationLength; public int TypeInformationLength; public int SecurityDescriptorLength; public System.Runtime.InteropServices.ComTypes.FILETIME CreateTime; } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_TYPE_INFORMATION { // Information Class 2 public UNICODE_STRING Name; public int ObjectCount; public int HandleCount; public int Reserved1; public int Reserved2; public int Reserved3; public int Reserved4; public int PeakObjectCount; public int PeakHandleCount; public int Reserved5; public int Reserved6; public int Reserved7; public int Reserved8; public int InvalidAttributes; public GENERIC_MAPPING GenericMapping; public int ValidAccess; public byte Unknown; public byte MaintainHandleDatabase; public int PoolType; public int PagedPoolUsage; public int NonPagedPoolUsage; } [StructLayout(LayoutKind.Sequential)] public struct OBJECT_NAME_INFORMATION { // Information Class 1 public UNICODE_STRING Name; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct UNICODE_STRING { public ushort Length; public ushort MaximumLength; public IntPtr Buffer; } [StructLayout(LayoutKind.Sequential)] public struct GENERIC_MAPPING { public int GenericRead; public int GenericWrite; public int GenericExecute; public int GenericAll; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SYSTEM_HANDLE_INFORMATION { // Information Class 16 public int ProcessID; public byte ObjectTypeNumber; public byte Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT public ushort Handle; public int Object_Pointer; public UInt32 GrantedAccess; } public const int MAX_PATH = 260; public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; public const int DUPLICATE_SAME_ACCESS = 0x2; public const int DUPLICATE_CLOSE_SOURCE = 0x1; } public class Win32Processes { const int CNST_SYSTEM_HANDLE_INFORMATION = 16; const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004; public static string getObjectTypeName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process) { IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id); IntPtr ipHandle = IntPtr.Zero; var objBasic = new Win32API.OBJECT_BASIC_INFORMATION(); IntPtr ipBasic = IntPtr.Zero; var objObjectType = new Win32API.OBJECT_TYPE_INFORMATION(); IntPtr ipObjectType = IntPtr.Zero; IntPtr ipObjectName = IntPtr.Zero; string strObjectTypeName = ""; int nLength = 0; int nReturn = 0; IntPtr ipTemp = IntPtr.Zero; if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS)) return null; ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic)); Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength); objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType()); Marshal.FreeHGlobal(ipBasic); ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength); nLength = objBasic.TypeInformationLength; while ((uint)(nReturn = Win32API.NtQueryObject( ipHandle, (int)Win32API.ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(ipObjectType); ipObjectType = Marshal.AllocHGlobal(nLength); } objObjectType = (Win32API.OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType()); if (Is64Bits()) { ipTemp = new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32); } else { ipTemp = objObjectType.Name.Buffer; } strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1); Marshal.FreeHGlobal(ipObjectType); return strObjectTypeName; } public static string getObjectName(Win32API.SYSTEM_HANDLE_INFORMATION shHandle, Process process) { IntPtr m_ipProcessHwnd = Win32API.OpenProcess(Win32API.ProcessAccessFlags.All, false, process.Id); IntPtr ipHandle = IntPtr.Zero; var objBasic = new Win32API.OBJECT_BASIC_INFORMATION(); IntPtr ipBasic = IntPtr.Zero; IntPtr ipObjectType = IntPtr.Zero; var objObjectName = new Win32API.OBJECT_NAME_INFORMATION(); IntPtr ipObjectName = IntPtr.Zero; string strObjectName = ""; int nLength = 0; int nReturn = 0; IntPtr ipTemp = IntPtr.Zero; if (!Win32API.DuplicateHandle(m_ipProcessHwnd, shHandle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_SAME_ACCESS)) return null; ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic)); Win32API.NtQueryObject(ipHandle, (int)Win32API.ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength); objBasic = (Win32API.OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType()); Marshal.FreeHGlobal(ipBasic); nLength = objBasic.NameInformationLength; ipObjectName = Marshal.AllocHGlobal(nLength); while ((uint)(nReturn = Win32API.NtQueryObject( ipHandle, (int)Win32API.ObjectInformationClass.ObjectNameInformation, ipObjectName, nLength, ref nLength)) == Win32API.STATUS_INFO_LENGTH_MISMATCH) { Marshal.FreeHGlobal(ipObjectName); ipObjectName = Marshal.AllocHGlobal(nLength); } objObjectName = (Win32API.OBJECT_NAME_INFORMATION)Marshal.PtrToStructure(ipObjectName, objObjectName.GetType()); if (Is64Bits()) { ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32); } else { ipTemp = objObjectName.Name.Buffer; } if (ipTemp != IntPtr.Zero) { byte[] baTemp2 = new byte[nLength]; try { Marshal.Copy(ipTemp, baTemp2, 0, nLength); strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32())); return strObjectName; } catch (AccessViolationException) { return null; } finally { Marshal.FreeHGlobal(ipObjectName); Win32API.CloseHandle(ipHandle); } } return null; } public static List<Win32API.SYSTEM_HANDLE_INFORMATION> GetHandles(Process process = null, string IN_strObjectTypeName = null, string IN_strObjectName = null) { uint nStatus; int nHandleInfoSize = 0x10000; IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize); int nLength = 0; IntPtr ipHandle = IntPtr.Zero; while ((nStatus = Win32API.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); } Win32API.SYSTEM_HANDLE_INFORMATION shHandle; List<Win32API.SYSTEM_HANDLE_INFORMATION> lstHandles = new List<Win32API.SYSTEM_HANDLE_INFORMATION>(); for (long lIndex = 0; lIndex < lHandleCount; lIndex++) { shHandle = new Win32API.SYSTEM_HANDLE_INFORMATION(); if (Is64Bits()) { shHandle = (Win32API.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 = (Win32API.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; } 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); lstHandles.Add(shHandle); } return lstHandles; } public static bool Is64Bits() { return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false; } } class Program { static void Main(string[] args) { String MutexName = "MSCTF.Asm.MutexDefault1"; String ProcessName = "notepad"; try { Process process = Process.GetProcessesByName(ProcessName)[0]; var handles = Win32Processes.GetHandles(process, "Mutant", "\\Sessions\\1\\BaseNamedObjects\\" + MutexName); if (handles.Count == 0) throw new System.ArgumentException("NoMutex", "original"); foreach (var handle in handles) { IntPtr ipHandle = IntPtr.Zero; if (!Win32API.DuplicateHandle(Process.GetProcessById(handle.ProcessID).Handle, handle.Handle, Win32API.GetCurrentProcess(), out ipHandle, 0, false, Win32API.DUPLICATE_CLOSE_SOURCE)) Console.WriteLine("DuplicateHandle() failed, error = {0}", Marshal.GetLastWin32Error()); Console.WriteLine("Mutex was killed"); } } catch (IndexOutOfRangeException) { Console.WriteLine("The process name '{0}' is not currently running", ProcessName); } catch (ArgumentException) { Console.WriteLine("The Mutex '{0}' was not found in the process '{1}'", MutexName, ProcessName); } Console.ReadLine(); } }} 解决方案 You need elevated privileges for that - especially DEBUG privilege.See:Manipulate Privileges in Managed Code Reliably, Securely, and Efficiently (MSDN)Debug Privilege (MSDN)The Windows Access Control Model Part 3Simon Mourier's answer to Stack Overflow question How to enable the SeCreateGlobalPrivilege in .NET without resorting to P/Invoke or reflection?ObjectSecurity Methods (MSDN) 这篇关于从另一个进程删除互斥锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-23 05:44