2009-08-21 15 views
7

मैं .NET से जावा प्रक्रिया ("java.exe") लॉन्च कर रहा हूं। Process.Start() का उपयोग कर। जावा प्रक्रिया के अलावा, conhost.exe नामक एक और प्रक्रिया किसी भी तरह से लॉन्च की गई है। मैं जावा प्रक्रिया से आउटपुट को .NET प्रक्रिया में रीडायरेक्ट कर रहा हूं।conhost.exe क्यों लॉन्च किया जा रहा है?

  1. conhost.exe भी लॉन्च क्यों किया जाता है?
  2. मैं इसे नेट से कैसे ट्रैक करूं? मैं इस विशिष्ट उदाहरण को ट्रैक करना चाहता हूं, और चूंकि मैं इसे सीधे नहीं बना रहा हूं (बल्कि जावा.एक्सई प्रक्रिया), मेरे पास यह पीआईडी ​​नहीं है।
+0

नहीं 100% सुनिश्चित की वजह से किसी भी Process.Start पर शुरू() ... मुझे आश्चर्य है कि प्रक्रिया की हत्या के बाद यह क्यों रहती है ... और यह आपको फ़ोल्डर को हटाने से क्यों रोक देगा। व्यक्तिगत रूप से यदि यह वास्तव में आपकी समस्या है तो मैं हैक बनाने और प्रक्रिया को मारने का सुझाव दूंगा, आपको निश्चित रूप से कोशिश करने से पहले जो कुछ भी कर सकते हैं, कोशिश करनी चाहिए (टाइपो के लिए सूखी, मैं अपने सर्वोत्तम प्रकार के लिए कर रहा हूं: पी) –

+0

आप क्यों चाहेंगे इसे ट्रैक करने के लिए? –

उत्तर

6

विंडोज के पुराने संस्करणों में, सीएसआरएसएस में कंसोल विंडो होस्ट की गईं, जो एक बेहद विशेषाधिकार, भरोसेमंद, सिस्टम महत्वपूर्ण प्रक्रिया है। Win7 पर, ऐसा प्रतीत होता है कि कंसोल विंडो अब conhost.exe में होस्ट की गई हैं, जिनके पास कम अधिकार हैं। यह शायद सुरक्षा & विश्वसनीयता कारणों के लिए किया गया था - कंसोल सिस्टम में एक सुरक्षा समस्या पूरे बॉक्स से समझौता नहीं करेगी, और कंसोल कोड में एक क्रैश सिस्टम को नीली स्क्रीन नहीं करेगा।

+0

यहां इसके बारे में कुछ पृष्ठभूमि सूचनाएं दी गई हैं: http://blogs.technet.com/b/askperf/archive/2009/10/05/windows-7- विन्डोज़- सर्वर- 2008-r2-console-host.aspx –

1

स्पष्ट होने के लिए, मुझे जावा के बारे में कुछ भी पता नहीं है, इसलिए मैं # 1 के साथ आपकी सहायता नहीं कर सकता। मैं # 2 के साथ मदद कर सकता हूं, हालांकि।

.NET के साथ इसे ट्रैक करने के लिए, आप System.Diagnostics का उपयोग कर सकते हैं।

सबसे पहले, आपको प्रत्येक प्रक्रिया को "conhost.exe" नाम से प्राप्त करना होगा, जावा लॉन्च करें, फिर सभी प्रक्रियाओं को फिर से प्राप्त करें, और तुलना करें। , प्रक्रियाओं को बंद करने

foreach (Process singleProcess in Process.GetProcessesByName("conhost")) 
{ 
    //Store the following in some kind of array 
    somePidArray[yourindex] = singleProcess.Id; 
} 

फिर जब आप चाहते हैं ठीक उसी पाश चलाने के लिए, और इस प्रक्रिया आईडी प्रारंभिक में संग्रहीत नहीं गया था:

विशिष्ट उदाहरण पाने के लिए, प्रक्रिया ID का उपयोग लूप, फिर सिंगल प्रोसेसिस कॉल करें(); इस पर। फिर आप सभी शुरुआती conhost.exe प्रक्रियाओं को जीवित रखेंगे, और केवल आपके प्रोग्राम में जावा लॉन्च करने के समय और आपके जावा प्रक्रिया से बाहर निकलने के दौरान बनाए गए लोगों को मार दें।

+0

मुझे नहीं पता कि कौन सी conhost.exe मेरा है, क्योंकि मैं इसे सीधे लॉन्च नहीं कर रहा हूं, इसलिए मेरे पास यह समझने का कोई तरीका नहीं है कि कौन सा पीआईडी ​​मेरा है। – ripper234

+0

क्या आप विंडोज 7 का उपयोग कर रहे हैं? – Breakthrough

+2

हां। मुझे यह भी नफरत है कि एसओ को टिप्पणियों में कम से कम 15 वर्णों की आवश्यकता है। – ripper234

3

अद्यतन: मुझे लगता है कि है कि आप तर्क on the oldnewthing पा सकते हैं। सुरक्षा कारणों से Windows Vista से हटाए गए कुछ कार्यक्षमता (जैसे ड्रैग और ड्रॉप) को पुनर्स्थापित करने के लिए इसे शायद जोड़ा गया था।

अद्यतन से पहले: conhost किसी भी cmd.exe खोलने पर लॉन्च प्रतीत होता है। यह शायद विंडोज 7 पर कुछ नई, अनियंत्रित चीज है।

1

यह एक प्रक्रिया है जो कंसोल विंडो होस्ट करती है। इसे विंडोज 7 (आईआईआरसी) में पेश किया गया था, पुराने संस्करणों में कार्यक्षमता csrss.exe प्रक्रिया के संदर्भ में निष्पादित की गई थी।

+0

क्षमा करें। मैंने आपकी पोस्ट को गलती से बढ़ा दिया है ... –

0

यह एक संबंधित प्रश्न उठाता है: क्या आप .NET ऐप द्वारा जावा एप्लिकेशन के लिए कंसोल विंडो चाहते हैं? यदि नहीं, तो आप java के बजाय javaw कमांड निष्पादित कर सकते हैं। मैंने Vista पर इसका प्रयोग नहीं किया है, लेकिन यह conhost.exe प्रक्रिया को समाप्त कर सकता है।

+0

मुझे कंसोल विंडो चाहिए क्योंकि मैं .NET पक्ष से अपना आउटपुट पढ़ रहा हूं। – ripper234

1

मैंने अभी प्रक्रिया के उद्देश्य को समझाने का प्रयास करने वाला एक लेख लिखा है। यह नियमित लोगों की ओर तैयार है, लेकिन चित्रण के लिए बहुत सारे स्क्रीनशॉट हैं।

What is conhost.exe and Why Is It Running?

लब्बोलुआब यह है कि conhost.exe CSRSS प्रक्रिया और cmd.exe के बीच बैठता है, तो आप खींचें & ड्रॉप फिर से उपयोग कर सकते हैं।

alt text

6

क्षमा करें, इस तरह के एक पुराने धागा necroing के लिए है, लेकिन मैंने सोचा कि सवाल रोचक और एक जवाब के लायक है।

conhost.exe भी लॉन्च क्यों किया जाता है? जैसा कि अन्य पदों में बताया गया है यह अब कंसोल अनुप्रयोगों को होस्ट करने का एक डिफ़ॉल्ट तरीका है। अधिक विवरण यहां दिए गए आलेख में दिए गए लेख में पाया जा सकता है: What is conhost.exe and Why Is It Running?

मैं इसे नेट से कैसे ट्रैक करूं? मैं इस विशिष्ट उदाहरण को ट्रैक करना चाहता हूं, और चूंकि मैं इसे सीधे नहीं बना रहा हूं (बल्कि जावा.एक्सई प्रक्रिया), मेरे पास यह पीआईडी ​​नहीं है।

जैसा कि अन्य ने नोट किया है कि कॉन्होस्ट प्रक्रिया को "ट्रैक" करने का कोई कारण नहीं होना चाहिए। ऐसा कहकर, आपके java.exe प्रक्रिया आईडी से conhost प्रक्रिया आईडी प्राप्त करने का एक तरीका है। आपको बस इतना करना है कि सभी प्रक्रिया संभालती है कि सिस्टम में प्रत्येक कॉन्होस्ट प्रक्रिया में है, और यदि इनमें से एक हैंडल आपके jawa.exe के समान आईडी के साथ एक प्रक्रिया को इंगित करता है, तो यह conhost.exe हैंडल होगा बाद। इसे प्रोसेस आईडी में कनवर्ट करें और आपको conhost.exe

के लिए पीआईडी ​​मिलता है तो यह सिद्धांत है। अभ्यास में इसे कैसे प्राप्त करें? वहां एक excellent article है जो कुछ कोड दिखाता है जो कुछ ऐसा ही कर रहा है। मैंने इस काम को हाथ में हमारे काम के अनुरूप करने के लिए थोड़ा सा संशोधित किया है। अंत में आप Utility.GetConhostIdByProcessId स्थैतिक फ़ंक्शन और अपने java.exe के पीआईडी ​​को पास करते हैं, और यह आपको प्रासंगिक conhost.exe का पीआईडी ​​वापस कर देगा। इस विधि के लिए एक टेस्ट कॉल मुख्य कार्य में नीचे दिए गए उदाहरण में पाया जा सकता है।

और अब कोड:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 

namespace SO1313195 
{ 

    class Program 
    { 
     static void Main() 
     { 
      const int processId = 6980; 
      int? result = Utility.GetConhostIdByProcessId(processId); 
      if (result.HasValue) 
      { 
       Console.WriteLine("Process {0} has conhost {1}", processId, result.Value); 
      } 
      else 
      { 
       Console.WriteLine("Unable to find conhost for process {0}", processId); 
      } 
      Console.ReadLine(); 
     } 
    } 

    public class Win32Api 
    { 
     [DllImportAttribute("kernel32.dll", EntryPoint = "GetProcessId")] 
     public static extern uint GetProcessId([In]IntPtr process); 

     [DllImport("ntdll.dll")] 
     public static extern int NtQueryObject(IntPtr objectHandle, int 
      objectInformationClass, IntPtr objectInformation, int objectInformationLength, 
      ref int returnLength); 

     [DllImport("ntdll.dll")] 
     public static extern uint NtQuerySystemInformation(int 
      systemInformationClass, IntPtr systemInformation, int systemInformationLength, 
      ref int returnLength); 

     [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] 
     public static extern void CopyMemory(byte[] destination, IntPtr source, uint length); 

     [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 
     { 
      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 
     { 
      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 
     { 
      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, 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 
     { 
      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 uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; 
     public const int DUPLICATE_SAME_ACCESS = 0x2; 
    } 

    class Utility 
    { 
     public static int? GetConhostIdByProcessId(int processId) 
     { 
      foreach (Process process in Process.GetProcessesByName("conhost")) 
      { 
       IntPtr processHwnd = Win32Api.OpenProcess(Win32Api.ProcessAccessFlags.DupHandle, false, process.Id); 
       List<Win32Api.SYSTEM_HANDLE_INFORMATION> lstHandles = GetHandles(process); 

       foreach (Win32Api.SYSTEM_HANDLE_INFORMATION handle in lstHandles) 
       { 
        int? id = GetFileDetails(processHwnd, handle); 
        if (id == processId) 
        { 
         return process.Id; 
        } 
       } 
      } 
      return null; 
     } 

     private static int? GetFileDetails(IntPtr processHwnd, Win32Api.SYSTEM_HANDLE_INFORMATION systemHandleInformation) 
     { 
      IntPtr ipHandle; 
      Win32Api.OBJECT_BASIC_INFORMATION objBasic = new Win32Api.OBJECT_BASIC_INFORMATION(); 
      Win32Api.OBJECT_TYPE_INFORMATION objObjectType = new Win32Api.OBJECT_TYPE_INFORMATION(); 
      int nLength = 0; 

      if (!Win32Api.DuplicateHandle(processHwnd, systemHandleInformation.Handle, Win32Api.GetCurrentProcess(), out ipHandle, 0, false, Win32Api.DUPLICATE_SAME_ACCESS)) return null; 

      IntPtr 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); 


      IntPtr ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength); 
      nLength = objBasic.TypeInformationLength; 
      while ((uint)(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()); 
      IntPtr ipTemp = Is64Bits() ? new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32) : objObjectType.Name.Buffer; 

      string strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1); 
      Marshal.FreeHGlobal(ipObjectType); 
      if (strObjectTypeName != "Process") return null; 

      return (int)Win32Api.GetProcessId(ipHandle); 
     } 

     private static List<Win32Api.SYSTEM_HANDLE_INFORMATION> GetHandles(Process process) 
     { 
      const int CNST_SYSTEM_HANDLE_INFORMATION = 16; 
      const uint STATUS_INFO_LENGTH_MISMATCH = 0xc0000004; 

      int nHandleInfoSize = 0x10000; 
      IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize); 
      int nLength = 0; 
      IntPtr ipHandle; 

      while ((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]; 
      Win32Api.CopyMemory(baTemp, ipHandlePointer, (uint)nLength); 

      long lHandleCount; 
      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 (shHandle.ProcessID != process.Id) continue; 
       lstHandles.Add(shHandle); 
      } 
      return lstHandles; 

     } 

     static bool Is64Bits() 
     { 
      return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false; 
     } 
    } 
} 

ध्यान दें, कि मैं केवल दोनों x86 और x64 संकलन विकल्प के साथ 64 विंडोज 7 पर इस कोड का परीक्षण किया। मैंने इसे .NET 4 के लिए VS2010 के साथ संकलित किया। यह कोड पठनीय से कम है और मैं गारंटी नहीं दे सकता कि यह सभी प्रासंगिक प्लेटफ़ॉर्म और आर्किटेक्चर पर काम करेगा। हालांकि यह यहां काम करता है (टीएम) और इस गूढ़ कार्य के लिए उपयोगी है।

+0

WinXP + के लिए SYSTEM_EXTENDED_HANDLE_INFORMATION का उपयोग करना बेहतर है क्योंकि SYSTEM_HANDLE_INFORMATION केवल 16-बिट लंबी प्रक्रिया आईडी-रिटर्न देता है। यदि सिस्टम को हैंडल के साथ भारी रूप से लोड किया जाता है तो प्रक्रिया आईडी-एस 65k से ऊपर मान शुरू करने के लिए होती है, उदाहरण के लिए 8 दशमलव अंक। सिस्टम कॉल करता है कि उपर्युक्त कोड का उपयोग केवल प्रक्रिया आईडी-एस के उच्च बिट्स को मुखौटा कर देगा। आप SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX और प्रक्रिया हैकर के स्रोत कोड में इसका उपयोग पा सकते हैं। जब मुझे समय मिलता है तो मैं अपना खुद का अद्यतन सी # कोड पोस्ट करूंगा जो आपके पर आधारित था, कुछ लॉजिक बग के साथ, और लीक तय हो गए थे। - आपके कोड के लिए बहुत बहुत धन्यवाद! –

+0

कृपया 27.06.2014 को मेरे अपडेट की जांच करें। यह 64-बिट के तहत UNICODE_STRING संरचना के पैकिंग और पढ़ने से संबंधित है, जो उपर्युक्त कोड के लिए गलत है। कृपया http://stackoverflow.com/a/19871391/193017 देखें –

2

जब कोई 'Process.Start()' का उपयोग कर प्रक्रिया शुरू करता है, तो उसे सीधे प्रक्रिया बनाने का विकल्प होता है, या 'cmd.exe' लॉन्च करने और 'cmd.exe' को विवरणों को संभालने का विकल्प होता है। 'UseShellExecute' ध्वज इसे नियंत्रित करता है। यदि आप विवरण को 'cmd.exe' पर छोड़ने का विकल्प चुनते हैं, जो स्थितियों में आम है जहां आप फ़ाइल को आमंत्रित करना चाहते हैं और शैल को इसे संभालने के लिए उपयुक्त प्रोग्राम चलाएं, उदा। एक '.txt' फ़ाइल "चल रहा" द्वारा, फिर Win7 पर यह वास्तव में 'cmd' चलाएगा, जो स्वयं 'conhost' चलाता है। यदि, दूसरी तरफ, आप 'ShellExecute' का उपयोग नहीं करते हैं तो 'स्टार्ट()' 'cmd' नहीं चलाएगा और आप परोक्ष रूप से 'conhost' लॉन्च नहीं करेंगे।

1

zespri's answer के आधार पर मैंने अद्यतन विधियों को लिखा।
यह कोड प्रक्रिया आईडी-एस को संभालने में सक्षम है जो 16-बिट से अधिक लंबा है।
इसके अलावा एक तर्क बग तय किया गया था और कुछ स्मृति और हैंडल लीक। कुछ विफलता जोड़ा गया।
मैंने मामले के लिए एक विधि जोड़ा जब conhost.exe में कई संबंधित प्रक्रियाएं हैं। ऐसा तब हो सकता है जब कोई कंसोल प्रोग्राम चल रहा हो और cmd हो।अपने माता-पिता की प्रक्रिया के रूप में exe, लेकिन कुछ अन्य मामलों, जहां संबंधित प्रक्रियाएं बच्चे-अभिभावक संबंध में भी नहीं हैं।
मूल कोड के लिए zespri के लिए बहुत बहुत धन्यवाद, इसमें से बहुत कुछ सीखना है!

विधि अपडेट के लिए अधिक स्पष्टीकरण:
WinXP के लिए + यह बाद से SYSTEM_HANDLE_INFORMATION रिटर्न केवल 16-बिट लंबी प्रक्रिया आईडी-s SYSTEM_EXTENDED_HANDLE_INFORMATION उपयोग करने के लिए बेहतर है। यदि सिस्टम को हैंडल के साथ भारी रूप से लोड किया जाता है तो प्रक्रिया आईडी-एस 65k से ऊपर मान शुरू करने के लिए होती है, उदाहरण के लिए 8 दशमलव अंक। सिस्टम कॉल करता है कि उपर्युक्त कोड का उपयोग केवल प्रक्रिया आईडी-एस के उच्च बिट्स को मुखौटा कर देगा। आप SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX और प्रक्रिया हैकर के स्रोत कोड में इसका उपयोग पा सकते हैं।

void Main() 
{ 
    //System.Diagnostics.Process.EnterDebugMode(); //TODO: is this necessary? 


    int? ConsoleHost_PId = NativeMethods.GetConhostIdByProcessId(14412376); 
    ConsoleHost_PId.Dump(); 


    int pid = 4484; 

    int? apid = NativeMethods.GetFirstConhostAssociatedProcessId(pid); 
    apid.Dump(); 

    var apids = NativeMethods.GetConhostAssociatedProcessIds(pid); 
    apids.Dump(); 
} 

public static class NativeMethods 
{ 
    [DllImport("kernel32.dll")] 
    public static extern IntPtr GetCurrentProcess(); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    public static extern bool CloseHandle(IntPtr hObject); 

    [DllImportAttribute("kernel32.dll", SetLastError = true)] 
    public static extern uint GetProcessId([In]IntPtr process); 

    [DllImport("ntdll.dll")] 
    public static extern uint NtQueryObject(IntPtr objectHandle, 
     int objectInformationClass, IntPtr objectInformation, int objectInformationLength, 
     ref int returnLength); 

    [DllImport("ntdll.dll")] 
    public static extern uint NtQuerySystemInformation(int 
     systemInformationClass, IntPtr systemInformation, int systemInformationLength, 
     ref int returnLength); 

    [DllImport("kernel32.dll")] 
    public static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, 
     IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, 
     uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions); 

    public enum ObjectInformationClass 
    { 
     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 
    { 
     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 
    { 
     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)] //, Pack = 1)] //NB! no packing! 
    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)] //NB! no packing! 
    public struct SYSTEM_HANDLE_INFORMATION 
    { 
     public ushort UniqueProcessId; 
     public ushort CreatorBackTraceIndex; 
     public byte ObjectTypeIndex; 
     public byte HandleAttributes; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT 
     public ushort HandleValue; 
     public UIntPtr Object; 
     public uint GrantedAccess; 
    } 

    //adapted from ProcessExplorer ntexapi.h 
    [StructLayout(LayoutKind.Sequential)] //, Pack = 1)] //NB! no packing! 
    public struct SYSTEM_HANDLE_INFORMATION_EX 
    { 
     public UIntPtr Object; 
     public UIntPtr UniqueProcessId; //changed ulong to IntPtr 
     public UIntPtr HandleValue; //changed ulong to IntPtr 
     public uint GrantedAccess; 
     public ushort CreatorBackTraceIndex; 
     public ushort ObjectTypeIndex; 
     public uint HandleAttributes; 
     public uint Reserved; 
    } 

    public const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004; 
    public const int DUPLICATE_SAME_ACCESS = 0x2; 

    // ############################################################################ 

    /// <summary> 
    /// Some console host processes have multiple associated processes! 
    /// </summary> 
    public static List<int> GetConhostAssociatedProcessIds(int pid) 
    { 
     List<int> result = new List<int>(); 

     IntPtr currentProcess = GetCurrentProcess(); 

     IntPtr processHandle = OpenProcess(ProcessAccessFlags.DupHandle, false, pid); 

     try 
     { 
      List<SYSTEM_HANDLE_INFORMATION_EX> lstHandles = GetHandles(pid); 

      foreach (SYSTEM_HANDLE_INFORMATION_EX handleInformation in lstHandles) 
      { 
       int? id = GetFileDetails(processHandle, handleInformation, currentProcess); 

       if (id.HasValue) 
        result.Add(id.Value); 
      } 

      return result; 
     } 
     finally 
     { 
      CloseHandle(processHandle); 
     } 
    } 

    public static int? GetFirstConhostAssociatedProcessId(int pid) 
    { 
     IntPtr currentProcess = GetCurrentProcess(); 

     IntPtr processHandle = OpenProcess(ProcessAccessFlags.DupHandle, false, pid); 

     try 
     { 
      List<SYSTEM_HANDLE_INFORMATION_EX> lstHandles = GetHandles(pid); 

      foreach (SYSTEM_HANDLE_INFORMATION_EX handleInformation in lstHandles) 
      { 
       int? id = GetFileDetails(processHandle, handleInformation, currentProcess); 

       if (id.HasValue) 
        return id; 
      } 

      return null; 
     } 
     finally 
     { 
      CloseHandle(processHandle); 
     } 
    } 

    public static int? GetConhostIdByProcessId(int processId) 
    { 
     IntPtr currentProcess = GetCurrentProcess(); 

     var processes = Process.GetProcessesByName("conhost"); 

     try 
     { 
      foreach (Process process in processes) //TODO: check that this process is really system's console host 
      { 
       IntPtr processHandle = OpenProcess(ProcessAccessFlags.DupHandle, false, process.Id); 

       try 
       { 

        List<SYSTEM_HANDLE_INFORMATION_EX> lstHandles = GetHandles(process.Id); 

        foreach (SYSTEM_HANDLE_INFORMATION_EX handleInformation in lstHandles) 
        { 
         int? id = GetFileDetails(processHandle, handleInformation, currentProcess); 

         if (id == processId) 
         { 
          return process.Id; 
         } 
        } 
       } 
       finally 
       { 
        CloseHandle(processHandle);  
       } 

      } //foreach (Process process in Process.GetProcessesByName("conhost")) 

      return null; 
     } 
     finally 
     { 
      foreach (Process process in processes) 
       process.Dispose(); 
     } 

    } //public static int? GetConhostIdByProcessId(int processId) 

    //TODO see this for possible hang under XP 32-bit: 
    //http://forum.sysinternals.com/handle-name-help-ntqueryobject_topic14435.html 
    //and https://stackoverflow.com/questions/16127948/hang-on-ntquerysysteminformation-in-winxpx32-but-works-fine-in-win7x64 

    private static int? GetFileDetails(IntPtr processHandle, SYSTEM_HANDLE_INFORMATION_EX systemHandleInformation, 
     IntPtr currentProcess) 
    { 
     IntPtr ipHandle; 
     OBJECT_BASIC_INFORMATION objBasic = new OBJECT_BASIC_INFORMATION(); 
     OBJECT_TYPE_INFORMATION objObjectType = new OBJECT_TYPE_INFORMATION(); 
     int nLength = 0; 

     if (Is64Bits()) 
     { 
      if (!DuplicateHandle(processHandle, new IntPtr(unchecked((long)systemHandleInformation.HandleValue)), currentProcess, 
             out ipHandle, 0, false, DUPLICATE_SAME_ACCESS)) 
      { 
       return null; 
      } 
     } 
     else 
     { 
      //failsafety 
      if ((systemHandleInformation.HandleValue.ToUInt64() >> 32) != 0) 
       return null; 

      if (!DuplicateHandle(processHandle, new IntPtr(unchecked((int)systemHandleInformation.HandleValue)), currentProcess, 
             out ipHandle, 0, false, DUPLICATE_SAME_ACCESS)) 
      { 
       return null; 
      } 
     } 


     try  
     { 
      IntPtr ipBasic = Marshal.AllocHGlobal(Marshal.SizeOf(objBasic)); 
      try 
      { 
       NtQueryObject(ipHandle, (int)ObjectInformationClass.ObjectBasicInformation, ipBasic, Marshal.SizeOf(objBasic), ref nLength); 
       objBasic = (OBJECT_BASIC_INFORMATION)Marshal.PtrToStructure(ipBasic, objBasic.GetType()); 
      } 
      finally 
      { 
       Marshal.FreeHGlobal(ipBasic); 
      } 


      IntPtr ipObjectType = Marshal.AllocHGlobal(objBasic.TypeInformationLength); 
      try 
      { 
       nLength = objBasic.TypeInformationLength; 
       while (NtQueryObject(ipHandle, (int)ObjectInformationClass.ObjectTypeInformation, ipObjectType, nLength, ref nLength) == STATUS_INFO_LENGTH_MISMATCH) 
       { 
        Marshal.FreeHGlobal(ipObjectType); 
        ipObjectType = IntPtr.Zero; //zero the pointer before new alloc for case the alloc fails 
        ipObjectType = Marshal.AllocHGlobal(nLength); 
       } 

       objObjectType = (OBJECT_TYPE_INFORMATION)Marshal.PtrToStructure(ipObjectType, objObjectType.GetType()); 
       //IntPtr ipTemp = Is64Bits() ? new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32) : objObjectType.Name.Buffer; 

       //string strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1); 
       string strObjectTypeName = Marshal.PtrToStringUni(objObjectType.Name.Buffer, objObjectType.Name.Length >> 1); 


       if (strObjectTypeName != "Process") 
        return null; 
      } 
      finally 
      { 
       Marshal.FreeHGlobal(ipObjectType); 
      } 


      return (int)GetProcessId(ipHandle); 
     } 
     finally 
     { 
      CloseHandle(ipHandle); 
     } 

    } //private static int? GetFileDetails(IntPtr processHandle, SYSTEM_HANDLE_INFORMATION systemHandleInformation, IntPtr currentProcess) 

    const int CNST_SYSTEM_HANDLE_INFORMATION = 16; 
    const int CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION = 64;  //from ProcessHacker ntexapi.h 

    //http://hintdesk.com/c-get-all-handles-of-a-given-process-in-64-bits/ 
    private static List<SYSTEM_HANDLE_INFORMATION_EX> GetHandles(int pid) 
    { 
     List<SYSTEM_HANDLE_INFORMATION_EX> lstHandles = new List<SYSTEM_HANDLE_INFORMATION_EX>(); 


     int nHandleInfoSize = 0x10000; 
     IntPtr ipHandlePointer = Marshal.AllocHGlobal(nHandleInfoSize); 
     int nLength = 0; 
     IntPtr ipHandle; 


     if (IsWinXP) //from ProcessHacker. This works under Win XP+ 
     { 
      try 
      { 
       //the structure array may get larger any number of times during our query 
       while (
        (
         NtQuerySystemInformation(CNST_SYSTEM_EXTENDED_HANDLE_INFORMATION, ipHandlePointer, 
                 nHandleInfoSize, ref nLength) 
        ) 
        == STATUS_INFO_LENGTH_MISMATCH 
       ) 
       { 
        //TODO: stop loop if buffer size gets large 

        nHandleInfoSize = nLength; 
        Marshal.FreeHGlobal(ipHandlePointer); 
        ipHandlePointer = IntPtr.Zero; //zero the pointer before new alloc for case the alloc fails 
        ipHandlePointer = Marshal.AllocHGlobal(nLength); 
       } 

       long lHandleCount; 
       if (Is64Bits())  
       { 
        lHandleCount = Marshal.ReadInt64(ipHandlePointer); 
        ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 16); 
       } 
       else 
       { 
        lHandleCount = Marshal.ReadInt32(ipHandlePointer); 
        ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 8); //changed to 8, tested OK 
       } 


       SYSTEM_HANDLE_INFORMATION_EX shHandle_ex; 

       for (long lIndex = 0; lIndex < lHandleCount; lIndex++) 
       { 
        shHandle_ex = new SYSTEM_HANDLE_INFORMATION_EX(); 
        if (Is64Bits()) 
        { 
         shHandle_ex = (SYSTEM_HANDLE_INFORMATION_EX)Marshal.PtrToStructure(ipHandle, shHandle_ex.GetType()); 
         ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle_ex));  
        } 
        else 
        { 
         shHandle_ex = (SYSTEM_HANDLE_INFORMATION_EX)Marshal.PtrToStructure(ipHandle, shHandle_ex.GetType());  
         ipHandle = new IntPtr(ipHandle.ToInt32() + Marshal.SizeOf(shHandle_ex));  
        } 

        //failsafety 
        if (shHandle_ex.UniqueProcessId.ToUInt64() > (ulong)int.MaxValue)  //TODO: start using ulong pids? 
         continue; 

        if ((int)shHandle_ex.UniqueProcessId.ToUInt32() != pid) 
         continue; 


        lstHandles.Add(shHandle_ex); 
       } 

      } 
      finally 
      { 
       Marshal.FreeHGlobal(ipHandlePointer); 
      } 


      return lstHandles; 

     } 
     else //if (IsWinXP) 
     { 
      try 
      { 

       //the structure array may get larger any number of times during our query 
       while (
        (
         NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ipHandlePointer, 
                 nHandleInfoSize, ref nLength) 
        ) 
        == STATUS_INFO_LENGTH_MISMATCH 
       ) 
       { 
        //TODO: stop loop if buffer size gets large 

        nHandleInfoSize = nLength; 
        Marshal.FreeHGlobal(ipHandlePointer); 
        ipHandlePointer = IntPtr.Zero; //zero the pointer before new alloc for case the alloc fails 
        ipHandlePointer = Marshal.AllocHGlobal(nLength); 
       } 

       long lHandleCount; 
       if (Is64Bits()) 
       { 
        lHandleCount = Marshal.ReadInt64(ipHandlePointer); 
        ipHandle = new IntPtr(ipHandlePointer.ToInt64() + 8); 
       } 
       else 
       { 
        lHandleCount = Marshal.ReadInt32(ipHandlePointer); 
        ipHandle = new IntPtr(ipHandlePointer.ToInt32() + 4); 
       } 


       SYSTEM_HANDLE_INFORMATION shHandle; 

       for (long lIndex = 0; lIndex < lHandleCount; lIndex++) 
       { 
        shHandle = new SYSTEM_HANDLE_INFORMATION(); 
        if (Is64Bits()) 
        { 
         shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType()); 
         ipHandle = new IntPtr(ipHandle.ToInt64() + Marshal.SizeOf(shHandle) + 4);  
        } 
        else 
        { 
         shHandle = (SYSTEM_HANDLE_INFORMATION)Marshal.PtrToStructure(ipHandle, shHandle.GetType());  
         ipHandle = new IntPtr(ipHandle.ToInt32() + Marshal.SizeOf(shHandle));  
        } 

        if (shHandle.UniqueProcessId != pid) 
         continue; 



        SYSTEM_HANDLE_INFORMATION_EX shHandle_ex = new SYSTEM_HANDLE_INFORMATION_EX(); 

        shHandle_ex.Object = shHandle.Object; 
        shHandle_ex.UniqueProcessId = new UIntPtr(shHandle.UniqueProcessId); 
        shHandle_ex.HandleValue = new UIntPtr(shHandle.HandleValue); 
        shHandle_ex.GrantedAccess = shHandle.GrantedAccess; 
        shHandle_ex.CreatorBackTraceIndex = shHandle.CreatorBackTraceIndex; 
        shHandle_ex.ObjectTypeIndex = shHandle.ObjectTypeIndex; 
        shHandle_ex.HandleAttributes = shHandle.HandleAttributes; 


        lstHandles.Add(shHandle_ex); 
       } 

      } 
      finally 
      { 
       Marshal.FreeHGlobal(ipHandlePointer); 
      } 


      return lstHandles; 

     } //if (IsWinXP) 

    } //private static List<SYSTEM_HANDLE_INFORMATION> GetHandles(int pid) 

    private static bool Is64Bits() 
    { 
     return Marshal.SizeOf(typeof(IntPtr)) == 8 ? true : false; 
    } 

    public static bool IsWinXP 
    { 
     get 
     { 
      return (
       false 
       || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) //WinXP 
       || Environment.OSVersion.Version.Major >= 6 //Vista or 7 
      ); 
     } 
    } 

} 


अद्यतन:

मैं 2014/06/27 पर 64-बिट कोड के लिए महत्वपूर्ण bugfixes जोड़ा।
UNICODE_STRING संरचना का पैकिंग गलत था और कोड ने कुछ मुश्किल तरीके से इसकी क्षतिपूर्ति करने की कोशिश की। हालांकि यह Win7 में प्रकट नहीं हुआ था, यह Win8 के तहत अच्छी तरह से दुर्घटनाग्रस्त हो गया।
पैक = 1 के साथ अन्य structs 'पैकिंग भी गलत था, लेकिन गलती से उनके गणना लेआउट को नहीं बदला।
महत्वपूर्ण बदल भागों थे: मुक्केबाज़ी क्या im के बारे में कहने के लिए, लेकिन मैं क्या पढ़ सकता है conhost वास्तव में खिड़कियों सात में कमांड प्रॉम्प्ट होस्ट कर रहा है से की शुद्धता

[StructLayout(LayoutKind.Sequential)] //, Pack = 1)] //NB! no packing! 
public struct UNICODE_STRING 

//IntPtr ipTemp = Is64Bits() ? new IntPtr(Convert.ToInt64(objObjectType.Name.Buffer.ToString(), 10) >> 32) : objObjectType.Name.Buffer; 
//string strObjectTypeName = Marshal.PtrToStringUni(ipTemp, objObjectType.Name.Length >> 1); 
string strObjectTypeName = Marshal.PtrToStringUni(objObjectType.Name.Buffer, objObjectType.Name.Length >> 1); 
संबंधित मुद्दे