Sono richiesto per una determinata attività per enumerare tutti gli handle nel sistema. L'approccio migliore che ho trovato finora è l'uso di documenti non documentati NtQuerySystemInformation
con il flag SystemHandleInformation
per il parametro di classe.Approccio preferito per la compilazione condizionale per versioni di tipi a 32 bit contro 64 bit
Fin qui tutto bene. Tuttavia, l'esecuzione in modalità a 32 bit a 64 bit di Windows, la struttura richiesta è la seguente:
// 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;
}
E per Windows a 64 bit (x64, non ho la prova Itanium, che spero non sia diverso. ..), la struttura è la seguente:
// 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;
}
Ora, dovrei cambiare il Object_Pointer
a un IntPtr
. Speravo per un momento che potessi fare lo stesso con ProcessId
, c'era un riferimento che diceva che in realtà era un HANDLE
che in realtà è un valore a 64 bit. Tuttavia, Reserved
è sempre zero, quindi non posso unirlo in uno IntPtr
allo stesso modo.
Questo probabilmente non è l'unico scenario in cui ciò accade. Sto cercando un modo migliore pratica di trattare con tali differenze:
- Usando una costante come
#if WIN32
(utilizzato internamente nella fonte di riferimento di IntPtr) non avrebbe funzionato qui a meno che voglio mantenere separati i binari. - Posso scrivere due diverse funzioni e due diverse strutture, creare un wrapper e utilizzare
if IntPtr.Size ==4
nel codice. Funziona per funzioni esterne, ma non funziona bene con i tipi. - Posso sovraccaricare
GetType
ma non sono sicuro di dove porta (potrebbe essere d'aiuto con Marshalling?). - C'è altro?
Nessuno di questi sembra l'ideale, ma finora, l'unico modo infallibile sembra essere quella di strutto mio sistema con if IsWin64()
dichiarazioni. Mi piacerebbe sentire approcci migliori dei miei.
Questo tipo di codice è come il sesso adolescenziale, un errore e ti sostenere per il resto della tua vita. Utilizzare la classe Process per eseguire l'utilità Handle.exe di SysInternals, almeno è possibile ottenere qualcun altro per supportarlo. –
@HansPassant: LOL! Sì, ho preso in considerazione l'utilizzo di qualcuno dei programmi di utilità di SysInternal, ma no, non si adatta al mio scenario. Grazie per il puntatore però. – Abel