मुझे सिस्टम में सभी हैंडल की गणना करने के लिए एक निश्चित कार्य के लिए आवश्यक है। अब तक का सबसे अच्छा तरीका कक्षा पैरामीटर के लिए SystemHandleInformation
ध्वज के साथ अंडर डॉक्यूमेंटेड NtQuerySystemInformation
का उपयोग कर रहा है।32-बिट बनाम 64-बिट संस्करणों के लिए सशर्त संकलन के लिए पसंदीदा दृष्टिकोण
अभी तक इतना अच्छा है। हालांकि, पर 64 बिट Windows 32 बिट मोड में यह चल रहा है, आवश्यक संरचना इस प्रकार है:
// 32-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public uint ProcessID;
public byte ObjectTypeNumber;
public byte Flags;
public ushort Handle;
public uint Object_Pointer;
public UInt32 GrantedAccess;
}
और के लिए 64 बिट विंडोज (64, मैं इटेनियम है, जो मुझे आशा है कि अलग नहीं है का परीक्षण नहीं किया। ..), संरचना इस प्रकार है के रूप में:
// 64-bit version
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct SYSTEM_HANDLE_INFORMATION
{
public int Reserved; // unknown, no documentation found
public uint ProcessID;
public byte ObjectTypeNumber;
public byte Flags;
public ushort Handle;
public long Object_Pointer;
public UInt32 GrantedAccess;
}
अब, मैं एक IntPtr
को Object_Pointer
बदलना चाहिए। मुझे एक पल की उम्मीद थी कि मैं ProcessId
के साथ ऐसा ही कर सकता था, एक संदर्भ था कि यह वास्तव में HANDLE
था जो वास्तव में 64-बिट मान है। हालांकि, Reserved
हमेशा शून्य होता है, इसलिए मैं इसे IntPtr
में उसी तरह मर्ज नहीं कर सकता।
शायद यह एकमात्र परिदृश्य नहीं है जहां यह होता है। मैं इस तरह के मतभेदों से निपटने का एक सबसे अच्छा अभ्यास रास्ता तलाश कर रहा हूँ:
#if WIN32
की तरह एक निरंतर (IntPtr के संदर्भ स्रोत में आंतरिक रूप से उपयोग) जब तक कि मैं अलग binaries बनाए रखना चाहते हैं यहाँ काम नहीं होगा का उपयोग करना।- मैं दो अलग-अलग फ़ंक्शन और दो अलग-अलग structs लिख सकता हूं, एक रैपर बना सकता हूं और कोड में
if IntPtr.Size ==4
का उपयोग कर सकता हूं। यह बाहरी कार्यों के लिए काम करता है, लेकिन प्रकारों के साथ अच्छी तरह से काम नहीं करता है। - मैं
GetType
अधिभारित कर सकता हूं लेकिन मुझे यकीन नहीं है कि यह कहां जाता है (मार्शलिंग के साथ मदद कर सकता है?)। - और कुछ और? इनमें से
कोई भी आदर्श लगते हैं, लेकिन अब तक, केवल सरल तरीका if IsWin64()
बयान के साथ अपने सिस्टम चरबी को हो रहा है। मुझे मेरी तुलना में बेहतर दृष्टिकोण सुनना अच्छा लगेगा।
कोड इस तरह किशोर प्यार की तरह है, एक गलती और आप अपने जीवन के बाकी के लिए इसे समर्थन करेंगे। SysInternals 'Handle.exe उपयोगिता को चलाने के लिए प्रक्रिया वर्ग का उपयोग करें, कम से कम आप इसका समर्थन करने के लिए किसी और को प्राप्त कर सकते हैं। –
@ हंसपैसेंट: एलओएल! हां, मैंने SysInternal की उपयोगिताओं में से किसी का भी उपयोग करने पर विचार किया है, लेकिन नहीं, मेरे परिदृश्य में फिट नहीं है। यद्यपि सूचक के लिए धन्यवाद। – Abel