Add-Type " using System; using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential)] public struct SystemHandleEntry { public int OwnerProcessId; public byte ObjectTypeNumber; public byte Flags; public ushort Handle; public IntPtr Object; public int GrantedAccess; } public enum SYSTEM_INFORMATION_CLASS { SystemBasicInformation = 0, SystemPerformanceInformation = 2, SystemTimeOfDayInformation = 3, SystemProcessInformation = 5, SystemProcessorPerformanceInformation = 8, SystemHandleInformation = 16, SystemInterruptInformation = 23, SystemExceptionInformation = 33, SystemRegistryQuotaInformation = 37, SystemLookasideInformation = 45, SystemExtendedHandleInformation = 64 } public enum OBJECT_INFORMATION_CLASS { ObjectBasicInformation = 0, ObjectNameInformation = 1, ObjectTypeInformation = 2, ObjectAllTypesInformation = 3, ObjectHandleInformation = 4 } public enum NT_STATUS { STATUS_SUCCESS = 0x00000000, STATUS_BUFFER_OVERFLOW = unchecked((int)0x80000005L), STATUS_INFO_LENGTH_MISMATCH = unchecked((int)0xC0000004L) } public static class NtDll { [DllImport(`"ntdll.dll`")] public static extern NT_STATUS NtQueryObject( [In] IntPtr Handle, [In] OBJECT_INFORMATION_CLASS ObjectInformationClass, [In] IntPtr ObjectInformation, [In] int ObjectInformationLength, [Out] out int ReturnLength); [DllImport(`"ntdll.dll`")] public static extern NT_STATUS NtQuerySystemInformation( [In] SYSTEM_INFORMATION_CLASS SystemInformationClass, [In] IntPtr SystemInformation, [In] int SystemInformationLength, [Out] out int ReturnLength); } public static class Kernel32 { [DllImport(`"kernel32.dll`")] public static extern int CloseHandle(IntPtr hObject); [DllImport(`"kernel32.dll`", SetLastError = true)] public static extern IntPtr OpenProcess( [In] int dwDesiredAccess, [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, [In] int dwProcessId); [DllImport(`"kernel32.dll`", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DuplicateHandle( [In] IntPtr hSourceProcessHandle, [In] IntPtr hSourceHandle, [In] IntPtr hTargetProcessHandle, [Out] out IntPtr lpTargetHandle, [In] int dwDesiredAccess, [In, MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, [In] int dwOptions); [DllImport(`"kernel32.dll`", SetLastError = true)] public static extern uint QueryDosDevice(string lpDeviceName, System.Text.StringBuilder lpTargetPath, int ucchMax); } " function Get-ObjectName { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline=$true)] [SystemHandleEntry]$entry ) Process { $handleDuplicate = [IntPtr]::Zero $sourceProcessHandle = [Kernel32]::OpenProcess(0x40, $false, $entry.OwnerProcessId) try { if (-not [Kernel32]::DuplicateHandle($sourceProcessHandle, [IntPtr]$entry.Handle, (Get-Process -Id $pid).Handle, [ref]$handleDuplicate, 0, $false, 2)) { return "" } } finally { [Kernel32]::CloseHandle($sourceProcessHandle) | Out-Null } $length = 0 [NtDll]::NtQueryObject($handleDuplicate, [OBJECT_INFORMATION_CLASS]::ObjectNameInformation, [IntPtr]::Zero, 0, [ref]$length) | Out-Null $ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($length) try { if ([NtDll]::NtQueryObject($handleDuplicate, [OBJECT_INFORMATION_CLASS]::ObjectNameInformation, $ptr, $length, [ref]$length) -ne [NT_STATUS]::STATUS_SUCCESS) { return "" } $name = [System.Runtime.InteropServices.Marshal]::PtrToStringUni([IntPtr]([long]$ptr + 2 * [IntPtr]::Size)) } finally { [Kernel32]::CloseHandle($handleDuplicate) | Out-Null [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) } return $name } } $gw2 = (Get-Process -Name Gw2 -ErrorAction Ignore) if (-not $gw2) { $gw2 = (Get-Process -Name Gw2-64 -ErrorAction Ignore) } if ($gw2) { $infoLength = 0x10000 $ptr = [IntPtr]::Zero try { while ($true) { $ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($infoLength) $length = 0 $result = [NtDll]::NtQuerySystemInformation([SYSTEM_INFORMATION_CLASS]::SystemHandleInformation, $ptr, $infoLength, [ref] $length) if ($result -eq [NT_STATUS]::STATUS_INFO_LENGTH_MISMATCH) { $infoLength = [Math]::Max($infoLength, $length) [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) $ptr = [IntPtr]::Zero } elseif ($result -eq [NT_STATUS]::STATUS_SUCCESS) { break } else { return } } if ([IntPtr]::Size -eq 4) { $handleCount = [System.Runtime.InteropServices.Marshal]::ReadInt32($ptr) } else { $handleCount = [System.Runtime.InteropServices.Marshal]::ReadInt64($ptr) } $offset = [IntPtr]::Size $entry = New-Object -TypeName SystemHandleEntry $size = [System.Runtime.InteropServices.Marshal]::SizeOf($entry) for ($i = 0; $i -lt $handleCount; $i++) { $entry = [SystemHandleEntry][System.Runtime.InteropServices.Marshal]::PtrToStructure([IntPtr]([long]$ptr + $offset),[Type]$entry.GetType()) if ($gw2.Id -eq $entry.OwnerProcessId) { $name = Get-ObjectName($entry) if ($name -match "AN-Mutex-Window-Guild Wars 2") { $handleDuplicate = [IntPtr]::Zero if ([Kernel32]::DuplicateHandle($gw2.Handle, [IntPtr]$entry.Handle, (Get-Process -Id $pid).Handle, [ref]$handleDuplicate, 0, $false, 1)) { echo "Killed: $name" [Kernel32]::CloseHandle($handleDuplicate) | Out-Null } break } } $offset += $size } } finally { if ($ptr -ne [IntPtr]::Zero) { [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr) } } } start-process -FilePath '.\Gw2.exe' -ArgumentList $args