using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using Vanara.InteropServices; using static Vanara.Extensions.BitHelper; namespace Vanara.PInvoke { public static partial class Kernel32 { private const string Lib_Psapi = "psapi.dll"; /// /// An application-defined callback function used with the EnumPageFiles function. /// /// The PENUM_PAGE_FILE_CALLBACK type defines a pointer to this callback function. EnumPageFilesProc is a placeholder /// for the application-defined function name. /// /// /// The user-defined data passed from EnumPageFiles. /// A pointer to an ENUM_PAGE_FILE_INFORMATION structure. /// The name of the pagefile. /// /// To continue enumeration, the callback function must return TRUE. /// To stop enumeration, the callback function must return FALSE. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nc-psapi-penum_page_file_callbacka PENUM_PAGE_FILE_CALLBACKA // PenumPageFileCallbacka; BOOL PenumPageFileCallbacka( LPVOID pContext, PENUM_PAGE_FILE_INFORMATION pPageFileInfo, LPCSTR // lpFilename ) {...} [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "eb3610fb-2c95-4f7b-973d-8dc41d2829f1")] [return: MarshalAs(UnmanagedType.Bool)] public delegate bool EnumPageFilesProc(IntPtr pContext, in ENUM_PAGE_FILE_INFORMATION pPageFileInfo, string lpFilename); /// Used by . [PInvokeData("psapi.h", MSDNShortId = "0f982f32-31f4-47b6-85d2-d6e17aa4eeb9")] public enum LIST_MODULES { /// Use the default behavior. LIST_MODULES_DEFAULT = 0x0, /// List the 32-bit modules. LIST_MODULES_32BIT = 0x01, /// List the 64-bit modules. LIST_MODULES_64BIT = 0x02, /// List all modules. LIST_MODULES_ALL = 0x03, } /// /// Removes as many pages as possible from the working set of the specified process. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION /// access right and the PROCESS_SET_QUOTA access right. For more information, see Process Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// You can also empty the working set by calling the SetProcessWorkingSetSize or SetProcessWorkingSetSizeEx function with the /// dwMinimumWorkingSetSize and dwMaximumWorkingSetSize parameters set to the value . /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EmptyWorkingSet in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as K32EmptyWorkingSet in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32EmptyWorkingSet. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as K32EmptyWorkingSet. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-emptyworkingset BOOL EmptyWorkingSet( HANDLE hProcess ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "76f2252e-7305-46b0-b1af-40ac084e6696")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EmptyWorkingSet(HPROCESS hProcess); /// /// Retrieves the load address for each device driver in the system. /// /// /// An array that receives the list of load addresses for the device drivers. /// /// /// /// The size of the lpImageBase array, in bytes. If the array is not large enough to store the load addresses, the lpcbNeeded /// parameter receives the required size of the array. /// /// /// /// The number of bytes returned in the lpImageBase array. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// To determine how many device drivers were enumerated by the call to EnumDeviceDrivers, divide the resulting value in the /// lpcbNeeded parameter by . /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EnumDeviceDrivers in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as EnumDeviceDrivers in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32EnumDeviceDrivers. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as EnumDeviceDrivers. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating all Device Drivers in the System. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-enumdevicedrivers BOOL EnumDeviceDrivers( LPVOID // *lpImageBase, DWORD cb, LPDWORD lpcbNeeded ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "55925741-da23-44b1-93e8-0e9468434a61")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumDeviceDrivers([In, Out, MarshalAs(UnmanagedType.LPArray)] IntPtr[] lpImageBase, uint cb, out uint lpcbNeeded); /// Retrieves the load address for each device driver in the system. /// An array that receives the list of load addresses for the device drivers. [PInvokeData("psapi.h", MSDNShortId = "55925741-da23-44b1-93e8-0e9468434a61")] public static IntPtr[] EnumDeviceDrivers() { if (!EnumDeviceDrivers(null, 0, out var sz) && sz == 0) Win32Error.ThrowLastError(); var ret = new IntPtr[sz / IntPtr.Size]; if (!EnumDeviceDrivers(ret, sz, out _)) Win32Error.ThrowLastError(); return ret; } /// /// Calls the callback routine for each installed pagefile in the system. /// /// /// A pointer to the routine called for each pagefile. For more information, see EnumPageFilesProc. /// /// /// The user-defined data passed to the callback routine. /// /// /// /// If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get /// extended error information, call GetLastError. /// /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EnumPageFiles in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as EnumPageFiles in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32EnumPageFiles. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as EnumPageFiles. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-enumpagefilesa BOOL EnumPageFilesA( PENUM_PAGE_FILE_CALLBACKA // pCallBackRoutine, LPVOID pContext ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "9289fe3c-a7d9-4acb-aeb6-a50de65db0a2")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumPageFiles(EnumPageFilesProc pCallBackRoutine, IntPtr pContext); /// Enumerates the pagefiles in the system. /// A list of ENUM_PAGE_FILE_INFORMATION structures with the associated filename. [PInvokeData("psapi.h", MSDNShortId = "9289fe3c-a7d9-4acb-aeb6-a50de65db0a2")] public static IEnumerable<(ENUM_PAGE_FILE_INFORMATION pageInfo, string filename)> EnumPageFiles() { var l = new List<(ENUM_PAGE_FILE_INFORMATION pageInfo, string filename)>(); if (!EnumPageFiles(callback, default)) Win32Error.ThrowLastError(); return l; bool callback(IntPtr _, in ENUM_PAGE_FILE_INFORMATION pPageFileInfo, string lpFilename) { l.Add((pPageFileInfo, lpFilename)); return true; } } /// /// Retrieves the process identifier for each process object in the system. /// /// /// A pointer to an array that receives the list of process identifiers. /// /// /// The size of the pProcessIds array, in bytes. /// /// /// The number of bytes returned in the pProcessIds array. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// It is a good idea to use a large array, because it is hard to predict how many processes there will be at the time you call EnumProcesses. /// /// /// To determine how many processes were enumerated, divide the pBytesReturned value by sizeof(DWORD). There is no indication given /// when the buffer is too small to store all process identifiers. Therefore, if pBytesReturned equals cb, consider retrying the /// call with a larger array. /// /// To obtain process handles for the processes whose identifiers you have just obtained, call the OpenProcess function. /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EnumProcesses in Psapi.h and exported in Kernel32.lib /// and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as EnumProcesses in Psapi.h and exported in Psapi.lib /// and Psapi.dll as a wrapper that calls K32EnumProcesses. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as EnumProcesses. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the program /// with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating All Processes or Enumerating All Modules for a Process. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-enumprocesses BOOL EnumProcesses( DWORD *lpidProcess, DWORD // cb, LPDWORD lpcbNeeded ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "0c0445cb-27d2-4857-a4a5-7a4c180b068b")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumProcesses([In, Out, MarshalAs(UnmanagedType.LPArray)] uint[] lpidProcess, uint cb, out uint lpcbNeeded); /// Retrieves the process identifier for each process object in the system. /// An array that receives the list of process identifiers. [PInvokeData("psapi.h", MSDNShortId = "0c0445cb-27d2-4857-a4a5-7a4c180b068b")] public static uint[] EnumProcesses() { uint rsz = 1024, sz; uint[] ret; do { sz = rsz * 2; ret = new uint[sz / sizeof(uint)]; if (!EnumProcesses(ret, sz, out rsz)) Win32Error.ThrowLastError(); } while (sz == rsz); return ret; } /// /// Retrieves a handle for each module in the specified process. /// /// To control whether a 64-bit application enumerates 32-bit modules, 64-bit modules, or both types of modules, use the /// EnumProcessModulesEx function. /// /// /// /// A handle to the process. /// /// /// An array that receives the list of module handles. /// /// /// The size of the lphModule array, in bytes. /// /// /// The number of bytes required to store all module handles in the lphModule array. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The EnumProcessModules function is primarily designed for use by debuggers and similar applications that must extract /// module information from another process. If the module list in the target process is corrupted or not yet initialized, or if the /// module list changes during the function call as a result of DLLs being loaded or unloaded, EnumProcessModules may fail or /// return incorrect information. /// /// /// It is a good idea to specify a large array of HMODULE values, because it is hard to predict how many modules there will /// be in the process at the time you call EnumProcessModules. To determine if the lphModule array is too small to hold all /// module handles for the process, compare the value returned in lpcbNeeded with the value specified in cb. If lpcbNeeded is /// greater than cb, increase the size of the array and call EnumProcessModules again. /// /// /// To determine how many modules were enumerated by the call to EnumProcessModules, divide the resulting value in the /// lpcbNeeded parameter by . /// /// /// The EnumProcessModules function does not retrieve handles for modules that were loaded with the /// LOAD_LIBRARY_AS_DATAFILE or similar flags. For more information, see LoadLibraryEx. /// /// /// Do not call CloseHandle on any of the handles returned by this function. The information comes from a snapshot, so there are no /// resources to be freed. /// /// /// If this function is called from a 32-bit application running on WOW64, it can only enumerate the modules of a 32-bit process. If /// the process is a 64-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299). /// /// /// To take a snapshot of specified processes and the heaps, modules, and threads used by these processes, use the /// CreateToolhelp32Snapshot function. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EnumProcessModules in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as EnumProcessModules in Psapi.h /// and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32EnumProcessModules. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as EnumProcessModules. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating All Processes or Enumerating All Modules for a Process. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-enumprocessmodules BOOL EnumProcessModules( HANDLE hProcess, // HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "b4088506-2f69-4cf0-9bab-3e6a7185f5b2")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumProcessModules(HPROCESS hProcess, [In, Out, MarshalAs(UnmanagedType.LPArray)] HINSTANCE[] lphModule, uint cb, out uint lpcbNeeded); /// /// Retrieves a handle for each module in the specified process. /// /// To control whether a 64-bit application enumerates 32-bit modules, 64-bit modules, or both types of modules, use the /// EnumProcessModulesEx function. /// /// /// A handle to the process. /// An array that receives the list of module handles. [PInvokeData("psapi.h", MSDNShortId = "b4088506-2f69-4cf0-9bab-3e6a7185f5b2")] public static HINSTANCE[] EnumProcessModules(HPROCESS hProcess) { if (!EnumProcessModules(hProcess, null, 0, out var sz) && sz == 0) Win32Error.ThrowLastError(); var ret = new HINSTANCE[sz / IntPtr.Size]; if (!EnumProcessModules(hProcess, ret, sz, out _)) Win32Error.ThrowLastError(); return ret; } /// Retrieves a handle for each module in the specified process that meets the specified filter criteria. /// A handle to the process. /// An array that receives the list of module handles. /// The size of the lphModule array, in bytes. /// The number of bytes required to store all module handles in the lphModule array. /// /// The filter criteria. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// LIST_MODULES_32BIT 0x01 /// List the 32-bit modules. /// /// /// LIST_MODULES_64BIT 0x02 /// List the 64-bit modules. /// /// /// LIST_MODULES_ALL 0x03 /// List all modules. /// /// /// LIST_MODULES_DEFAULT 0x0 /// Use the default behavior. /// /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The EnumProcessModulesEx function is primarily designed for use by debuggers and similar applications that must extract /// module information from another process. If the module list in the target process is corrupted or not yet initialized, or if the /// module list changes during the function call as a result of DLLs being loaded or unloaded, EnumProcessModulesEx may fail /// or return incorrect information. /// /// /// This function is intended primarily for 64-bit applications. If the function is called by a 32-bit application running under /// WOW64, the dwFilterFlag option is ignored and the function provides the same results as the EnumProcessModules function. /// /// /// It is a good idea to specify a large array of HMODULE values, because it is hard to predict how many modules there will /// be in the process at the time you call EnumProcessModulesEx. To determine if the lphModule array is too small to hold all /// module handles for the process, compare the value returned in lpcbNeeded with the value specified in cb. If lpcbNeeded is /// greater than cb, increase the size of the array and call EnumProcessModulesEx again. /// /// /// To determine how many modules were enumerated by the call to EnumProcessModulesEx, divide the resulting value in the /// lpcbNeeded parameter by . /// /// /// The EnumProcessModulesEx function does not retrieve handles for modules that were loaded with the /// LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. /// /// /// Do not call CloseHandle on any of the handles returned by this function. The information comes from a snapshot, so there are no /// resources to be freed. /// /// /// To take a snapshot of specified processes and the heaps, modules, and threads used by these processes, use the /// CreateToolhelp32Snapshot function. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32EnumProcessModulesEx in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as EnumProcessModulesEx in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32EnumProcessModulesEx. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as EnumProcessModulesEx. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocessmodulesex BOOL EnumProcessModulesEx( HANDLE // hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded, DWORD dwFilterFlag ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "0f982f32-31f4-47b6-85d2-d6e17aa4eeb9")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumProcessModulesEx(HPROCESS hProcess, [In, Out, MarshalAs(UnmanagedType.LPArray)] HINSTANCE[] lphModule, uint cb, out uint lpcbNeeded, LIST_MODULES dwFilterFlag); /// Retrieves a handle for each module in the specified process that meets the specified filter criteria. /// A handle to the process. /// /// The filter criteria. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// LIST_MODULES_32BIT 0x01 /// List the 32-bit modules. /// /// /// LIST_MODULES_64BIT 0x02 /// List the 64-bit modules. /// /// /// LIST_MODULES_ALL 0x03 /// List all modules. /// /// /// LIST_MODULES_DEFAULT 0x0 /// Use the default behavior. /// /// /// /// An array that receives the list of module handles. /// /// /// The EnumProcessModulesEx function is primarily designed for use by debuggers and similar applications that must extract /// module information from another process. If the module list in the target process is corrupted or not yet initialized, or if the /// module list changes during the function call as a result of DLLs being loaded or unloaded, EnumProcessModulesEx may fail /// or return incorrect information. /// /// /// This function is intended primarily for 64-bit applications. If the function is called by a 32-bit application running under /// WOW64, the dwFilterFlag option is ignored and the function provides the same results as the EnumProcessModules function. /// /// /// The EnumProcessModulesEx function does not retrieve handles for modules that were loaded with the /// LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. /// /// /// Do not call CloseHandle on any of the handles returned by this function. The information comes from a snapshot, so there are no /// resources to be freed. /// /// /// To take a snapshot of specified processes and the heaps, modules, and threads used by these processes, use the /// CreateToolhelp32Snapshot function. /// /// [PInvokeData("psapi.h", MSDNShortId = "0f982f32-31f4-47b6-85d2-d6e17aa4eeb9")] public static HINSTANCE[] EnumProcessModulesEx(HPROCESS hProcess, LIST_MODULES dwFilterFlag = LIST_MODULES.LIST_MODULES_ALL) { if (!EnumProcessModulesEx(hProcess, null, 0, out var sz, dwFilterFlag) && sz == 0) Win32Error.ThrowLastError(); var ret = new HINSTANCE[sz / IntPtr.Size]; if (!EnumProcessModulesEx(hProcess, ret, sz, out _, dwFilterFlag)) Win32Error.ThrowLastError(); return ret; } /// /// Retrieves the base name of the specified device driver. /// /// /// The load address of the device driver. This value can be retrieved using the EnumDeviceDrivers function. /// /// /// A pointer to the buffer that receives the base name of the device driver. /// /// /// /// The size of the lpBaseName buffer, in characters. If the buffer is not large enough to store the base name plus the terminating /// null character, the string is truncated. /// /// /// /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer, not including any /// terminating null character. /// /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetDeviceDriverBaseName in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetDeviceDriverBaseName in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetDeviceDriverBaseName. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetDeviceDriverBaseName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating all Device Drivers in the System. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getdevicedriverbasenamea DWORD GetDeviceDriverBaseNameA( // LPVOID ImageBase, LPSTR lpFilename, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "a19a927d-4669-4d4c-951e-43f294a8fb40")] public static extern uint GetDeviceDriverBaseName(IntPtr ImageBase, StringBuilder lpFilename, uint nSize); /// /// Retrieves the path available for the specified device driver. /// /// /// The load address of the device driver. /// /// /// A pointer to the buffer that receives the path to the device driver. /// /// /// /// The size of the lpFilename buffer, in characters. If the buffer is not large enough to store the path plus the terminating null /// character, the string is truncated. /// /// /// /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer, not including any /// terminating null character. /// /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetDeviceDriverFileName in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetDeviceDriverFileName in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetDeviceDriverFileName. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetDeviceDriverFileName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getdevicedriverfilenamea DWORD GetDeviceDriverFileNameA( // LPVOID ImageBase, LPSTR lpFilename, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "6ddbcf7e-e41c-4ea7-b60a-01ed5c98c530")] public static extern uint GetDeviceDriverFileName(IntPtr ImageBase, StringBuilder lpFilename, uint nSize); /// /// /// Checks whether the specified address is within a memory-mapped file in the address space of the specified process. If so, the /// function returns the name of the memory-mapped file. /// /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For /// more information, see Process Security and Access Rights. /// /// /// /// The address to be verified. /// /// /// A pointer to the buffer that receives the name of the memory-mapped file to which the address specified by lpv belongs. /// /// /// The size of the lpFilename buffer, in characters. /// /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer, in characters. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetMappedFileName in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetMappedFileName in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetMappedFileName. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetMappedFileName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// In Windows Server 2012, this function is supported by the following technologies. /// /// /// Technology /// Supported /// /// /// Server Message Block (SMB) 3.0 protocol /// Yes /// /// /// SMB 3.0 Transparent Failover (TFO) /// Yes /// /// /// SMB 3.0 with Scale-out File Shares (SO) /// Yes /// /// /// Cluster Shared Volume File System (CsvFS) /// Yes /// /// /// Resilient File System (ReFS) /// Yes /// /// /// Examples /// For an example, see Obtaining a File Name From a File Handle. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getmappedfilenamea DWORD GetMappedFileNameA( HANDLE hProcess, // LPVOID lpv, LPSTR lpFilename, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "10a2e5ab-f495-486d-8ef7-ef763716afd1")] public static extern uint GetMappedFileName(HPROCESS hProcess, IntPtr lpv, StringBuilder lpFilename, uint nSize); /// /// Retrieves the base name of the specified module. /// /// /// A handle to the process that contains the module. /// /// The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For more information, see /// Process Security and Access Rights. /// /// /// /// /// A handle to the module. If this parameter is NULL, this function returns the name of the file used to create the calling process. /// /// /// /// /// A pointer to the buffer that receives the base name of the module. If the base name is longer than maximum number of characters /// specified by the nSize parameter, the base name is truncated. /// /// /// /// The size of the lpBaseName buffer, in characters. /// /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer, in characters. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The GetModuleBaseName function is primarily designed for use by debuggers and similar applications that must extract /// module information from another process. If the module list in the target process is corrupted or is not yet initialized, or if /// the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleBaseName may fail /// or return incorrect information. /// /// /// To retrieve the base name of a module in the current process, use the GetModuleFileName function to retrieve the full module /// name and then use a function call such as to scan to the beginning of the base name within the module name string. This is more /// efficient and more reliable than calling GetModuleBaseName with a handle to the current process. /// /// /// To retrieve the base name of the main executable module for a remote process, use the GetProcessImageFileName or /// QueryFullProcessImageName function to retrieve the module name and then use the function as described in the previous paragraph. /// This is more efficient and more reliable than calling GetModuleBaseName with a NULL module handle. /// /// /// The GetModuleBaseName function does not retrieve the base name for modules that were loaded with the /// LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetModuleBaseName in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetModuleBaseName in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetModuleBaseName. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetModuleBaseName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating All Processes. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getmodulebasenamea DWORD GetModuleBaseNameA( HANDLE hProcess, // HMODULE hModule, LPSTR lpBaseName, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "31a9eb69-95f0-4dd7-8fd5-296f2cff0b8a")] public static extern uint GetModuleBaseName(HPROCESS hProcess, [Optional] HINSTANCE hModule, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpBaseName, uint nSize); /// Retrieves the fully qualified path for the file containing the specified module. /// /// A handle to the process that contains the module. /// /// The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights. For more /// information, see Process Security and Access Rights. /// /// /// The GetModuleFileNameEx function does not retrieve the path for modules that were loaded using the /// LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. /// /// /// /// A handle to the module. If this parameter is NULL, GetModuleFileNameEx returns the path of the executable file of the /// process specified in hProcess. /// /// /// A pointer to a buffer that receives the fully qualified path to the module. If the size of the file name is larger than the /// value of the nSize parameter, the function succeeds but the file name is truncated and null-terminated. /// /// The size of the lpFilename buffer, in characters. /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The GetModuleFileNameEx function is primarily designed for use by debuggers and similar applications that must extract /// module information from another process. If the module list in the target process is corrupted or is not yet initialized, or if /// the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleFileNameEx may /// fail or return incorrect information. /// /// /// To retrieve the name of a module in the current process, use the GetModuleFileName function. This is more efficient and more /// reliable than calling GetModuleFileNameEx with a handle to the current process. /// /// /// To retrieve the name of the main executable module for a remote process, use the GetProcessImageFileName or /// QueryFullProcessImageName function. This is more efficient and more reliable than calling the GetModuleFileNameEx /// function with a NULL module handle. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetModuleFileNameEx in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetModuleFileNameEx in Psapi.h /// and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetModuleFileNameEx. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetModuleFileNameEx. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Enumerating All Modules for a Process. /// /// Note /// /// The psapi.h header defines GetModuleFileNameEx as an alias which automatically selects the ANSI or Unicode version of this /// function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that /// not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions /// for Function Prototypes. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulefilenameexa DWORD GetModuleFileNameExA( HANDLE // hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "NF:psapi.GetModuleFileNameExA")] public static extern uint GetModuleFileNameEx(HPROCESS hProcess, [Optional] HINSTANCE hModule, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpFilename, uint nSize); /// /// Retrieves information about the specified module in the MODULEINFO structure. /// /// /// A handle to the process that contains the module. /// /// The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For more information, see /// Process Security and Access Rights. /// /// /// /// A handle to the module. /// /// /// A pointer to the MODULEINFO structure that receives information about the module. /// /// /// The size of the MODULEINFO structure, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// To get information for the calling process, pass the handle returned by GetCurrentProcess. /// /// The GetModuleInformation function does not retrieve information for modules that were loaded with the /// LOAD_LIBRARY_AS_DATAFILE flag. For more information, see LoadLibraryEx. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetModuleInformation in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as K32GetModuleInformation in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetModuleInformation. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as K32GetModuleInformation. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getmoduleinformation BOOL GetModuleInformation( HANDLE // hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "afb9f4c8-c8ae-4497-96c1-b559cfa2cedf")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetModuleInformation(HPROCESS hProcess, HINSTANCE hModule, out MODULEINFO lpmodinfo, uint cb); /// /// Retrieves the performance values contained in the PERFORMANCE_INFORMATION structure. /// /// /// A pointer to a PERFORMANCE_INFORMATION structure that receives the performance information. /// /// /// The size of the PERFORMANCE_INFORMATION structure, in bytes. /// /// /// /// If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. To get extended error /// information, call GetLastError. /// /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetPerformanceInfo in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetPerformanceInfo in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetPerformanceInfo. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetPerformanceInfo. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with –DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getperformanceinfo BOOL GetPerformanceInfo( // PPERFORMANCE_INFORMATION pPerformanceInformation, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "21655278-49da-4e63-a4f9-0ee9f6179f4a")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetPerformanceInfo(out PERFORMANCE_INFORMATION pPerformanceInformation, uint cb); /// /// Retrieves the name of the executable file for the specified process. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION /// access right. For more information, see Process Security and Access Rights. /// /// Windows Server 2003 and Windows XP: The handle must have the PROCESS_QUERY_INFORMATION access right. /// /// /// A pointer to a buffer that receives the full path to the executable file. /// /// /// The size of the lpImageFileName buffer, in characters. /// /// /// If the function succeeds, the return value specifies the length of the string copied to the buffer. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The file Psapi.dll is installed in the %windir%\System32 directory. If there is another copy of this DLL on your computer, it /// can lead to the following error when running applications on your system: "The procedure entry point GetProcessImageFileName /// could not be located in the dynamic link library PSAPI.DLL." To work around this problem, locate any versions that are not in /// the %windir%\System32 directory and delete or rename them, then restart. /// /// /// The GetProcessImageFileName function returns the path in device form, rather than drive letters. For example, the file /// name C:\Windows\System32\Ctype.nls would look as follows in device form: /// /// \Device\Harddisk0\Partition1\Windows\System32\Ctype.nls /// /// To retrieve the module name of the current process, use the GetModuleFileName function with a NULL module handle. This is more /// efficient than calling the GetProcessImageFileName function with a handle to the current process. /// /// /// To retrieve the name of the main executable module for a remote process in win32 path format, use the QueryFullProcessImageName function. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetProcessImageFileName in Psapi.h and exported /// in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetProcessImageFileName in /// Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetProcessImageFileName. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetProcessImageFileName. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and /// compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getprocessimagefilenamea DWORD GetProcessImageFileNameA( // HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "819fc2f4-0801-417b-9cbb-d7fd2894634e")] public static extern uint GetProcessImageFileName(HPROCESS hProcess, StringBuilder lpImageFileName, uint nSize); /// /// Retrieves information about the memory usage of the specified process. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION /// access right and the PROCESS_VM_READ access right. For more information, see Process Security and Access Rights. /// /// /// Windows Server 2003 and Windows XP: The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ /// access rights. /// /// /// /// /// A pointer to the PROCESS_MEMORY_COUNTERS or PROCESS_MEMORY_COUNTERS_EX structure that receives information about the memory /// usage of the process. /// /// /// /// The size of the ppsmemCounters structure, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetProcessMemoryInfo in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetProcessMemoryInfo in Psapi.h /// and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetProcessMemoryInfo. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetProcessMemoryInfo. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and /// compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Collecting Memory Usage Information for a Process. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getprocessmemoryinfo BOOL GetProcessMemoryInfo( HANDLE // Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "12990e8d-6097-4502-824e-db6c3f76c715")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetProcessMemoryInfo(HPROCESS Process, out PROCESS_MEMORY_COUNTERS ppsmemCounters, uint cb); /// /// Retrieves information about the memory usage of the specified process. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION /// access right and the PROCESS_VM_READ access right. For more information, see Process Security and Access Rights. /// /// /// Windows Server 2003 and Windows XP: The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ /// access rights. /// /// /// /// /// A pointer to the PROCESS_MEMORY_COUNTERS or PROCESS_MEMORY_COUNTERS_EX structure that receives information about the memory /// usage of the process. /// /// /// /// The size of the ppsmemCounters structure, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetProcessMemoryInfo in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetProcessMemoryInfo in Psapi.h /// and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetProcessMemoryInfo. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetProcessMemoryInfo. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and /// compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Collecting Memory Usage Information for a Process. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getprocessmemoryinfo BOOL GetProcessMemoryInfo( HANDLE // Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "12990e8d-6097-4502-824e-db6c3f76c715")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetProcessMemoryInfo(HPROCESS Process, out PROCESS_MEMORY_COUNTERS_EX ppsmemCounters, uint cb); /// /// /// Retrieves information about the pages that have been added to the working set of the specified process since the last time this /// function or the InitializeProcessForWsWatch function was called. /// /// To retrieve extended information, use the GetWsChangesEx function. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see /// Process Security and Access Rights. /// /// /// /// /// A pointer to a user-allocated buffer that receives an array of PSAPI_WS_WATCH_INFORMATION structures. The array is terminated /// with a structure whose FaultingPc member is NULL. /// /// /// /// The size of the lpWatchInfo buffer, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// GetLastError returns ERROR_INSUFFICIENT_BUFFER if the lpWatchInfo buffer is not large enough to contain all the working /// set change records; the buffer is returned empty. Reallocate a larger block of memory for the buffer and call again. /// /// /// /// /// The operating system uses one buffer per process to maintain working set change records. If more than one application (or /// multiple threads in the same application) calls this function with the same process handle, neither application will have a /// complete accounting of the working set changes because each call empties the buffer. /// /// /// The operating system does not record new change records while it is processing the query (and emptying the buffer). The function /// sets the error code to NO_MORE_ENTRIES if a concurrent query is received while it is processing another query. /// /// /// If the buffer becomes full, no new records are added to the buffer until this function or the InitializeProcessForWsWatch /// function is called. You should call this method with enough frequency to prevent possible data loss. If records are lost, the /// array is terminated with a structure whose FaultingPc member is NULL and whose FaultingVa member is set to the /// number of records that were lost. /// /// /// Windows Server 2003 and Windows XP: If records are lost, the array is terminated with a structure whose FaultingPc /// member is NULL and whose FaultingVa member is 1. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetWsChanges in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetWsChanges in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetWsChanges. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetWsChanges. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getwschanges BOOL GetWsChanges( HANDLE hProcess, // PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "ace5106c-9c7b-4d5f-a69a-c3a8bff0bb2d")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWsChanges(HPROCESS hProcess, IntPtr lpWatchInfo, uint cb); /// /// /// Retrieves information about the pages that have been added to the working set of the specified process since the last time this /// function or the InitializeProcessForWsWatch function was called. /// /// To retrieve extended information, use the GetWsChangesEx function. /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see /// Process Security and Access Rights. /// /// The size at which to initially allocate the buffer. The default is 16KB. /// An array of PSAPI_WS_WATCH_INFORMATION structures. /// /// /// The operating system uses one buffer per process to maintain working set change records. If more than one application (or /// multiple threads in the same application) calls this function with the same process handle, neither application will have a /// complete accounting of the working set changes because each call empties the buffer. /// /// /// The operating system does not record new change records while it is processing the query (and emptying the buffer). The function /// sets the error code to NO_MORE_ENTRIES if a concurrent query is received while it is processing another query. /// /// [PInvokeData("psapi.h", MSDNShortId = "ace5106c-9c7b-4d5f-a69a-c3a8bff0bb2d")] public static PSAPI_WS_WATCH_INFORMATION[] GetWsChanges(HPROCESS hProcess, int sizeHint = 1024 * 16) { using var mem = new SafeHGlobalHandle(sizeHint); while (!GetWsChanges(hProcess, mem, mem.Size)) { var err = Win32Error.GetLastError(); if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) throw err.GetException(); mem.Size *= 2; } var cb = Marshal.SizeOf(typeof(PSAPI_WS_WATCH_INFORMATION)); var c = 0; for (var i = 0; i < mem.Size && Marshal.ReadIntPtr(mem, i) != IntPtr.Zero; c++, i += cb) ; return mem.ToArray(c); } /// /// /// Retrieves extended information about the pages that have been added to the working set of the specified process since the last /// time this function or the InitializeProcessForWsWatch function was called. /// /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see /// Process Security and Access Rights. /// /// /// /// /// A pointer to a user-allocated buffer that receives an array of PSAPI_WS_WATCH_INFORMATION_EX structures. The array is terminated /// with a structure whose FaultingPc member is NULL. /// /// /// /// The size of the lpWatchInfoEx buffer, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call the GetLastError function. /// /// The GetLastError function returns ERROR_INSUFFICIENT_BUFFER if the lpWatchInfoEx buffer is not large enough to contain /// all the working set change records; the buffer is returned empty. Reallocate a larger block of memory for the buffer and call again. /// /// /// /// /// The operating system uses one buffer per process to maintain working set change records. If more than one application (or /// multiple threads in the same application) calls this function with the same process handle, neither application will have a /// complete accounting of the working set changes because each call empties the buffer. /// /// /// The operating system does not record new change records while it is processing the query (and emptying the buffer). This /// function sets the error code to NO_MORE_ENTRIES if a concurrent query is received while it is processing another query. /// /// /// If the buffer becomes full, no new records are added to the buffer until this function or the InitializeProcessForWsWatch /// function is called. You should call GetWsChangesEx with enough frequency to prevent possible data loss. If records are /// lost, the array is terminated with a structure whose FaultingPc member is NULL and whose FaultingVa member is set /// to the number of records that were lost. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32GetWsChangesEx in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as GetWsChangesEx in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32GetWsChangesEx. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as GetWsChangesEx. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-getwschangesex BOOL GetWsChangesEx( HANDLE hProcess, // PPSAPI_WS_WATCH_INFORMATION_EX lpWatchInfoEx, PDWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "8572db5c-2ffc-424f-8cec-b6a6902fed62")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWsChangesEx(HPROCESS hProcess, IntPtr lpWatchInfoEx, ref uint cb); /// /// Retrieves extended information about the pages that have been added to the working set of the specified process since the last /// time this function or the InitializeProcessForWsWatch function was called. /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see /// Process Security and Access Rights. /// /// An array of PSAPI_WS_WATCH_INFORMATION_EX structures. /// /// /// The operating system uses one buffer per process to maintain working set change records. If more than one application (or /// multiple threads in the same application) calls this function with the same process handle, neither application will have a /// complete accounting of the working set changes because each call empties the buffer. /// /// /// The operating system does not record new change records while it is processing the query (and emptying the buffer). This /// function sets the error code to NO_MORE_ENTRIES if a concurrent query is received while it is processing another query. /// /// /// If the buffer becomes full, no new records are added to the buffer until this function or the InitializeProcessForWsWatch /// function is called. You should call GetWsChangesEx with enough frequency to prevent possible data loss. If records are /// lost, the array is terminated with a structure whose FaultingPc member is NULL and whose FaultingVa member is set /// to the number of records that were lost. /// /// [PInvokeData("psapi.h", MSDNShortId = "8572db5c-2ffc-424f-8cec-b6a6902fed62")] public static PSAPI_WS_WATCH_INFORMATION_EX[] GetWsChangesEx(HPROCESS hProcess) { var sz = 0U; if (!GetWsChangesEx(hProcess, IntPtr.Zero, ref sz)) { var err = Win32Error.GetLastError(); if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) throw err.GetException(); } using var mem = new SafeHGlobalHandle((int)sz); if (!GetWsChangesEx(hProcess, mem, ref sz)) { var err = Win32Error.GetLastError(); if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) throw err.GetException(); } var cb = Marshal.SizeOf(typeof(PSAPI_WS_WATCH_INFORMATION_EX)); var c = 0; for (var i = 0; i < mem.Size && Marshal.ReadIntPtr(mem, i) != IntPtr.Zero; c++, i += cb) ; return mem.ToArray(c); } /// /// /// Initiates monitoring of the working set of the specified process. You must call this function before calling the GetWsChanges function. /// /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see Process /// Security and Access Rights. /// /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32InitializeProcessForWsWatch in Psapi.h and /// exported in Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as /// InitializeProcessForWsWatch in Psapi.h and exported in Psapi.lib and Psapi.dll as a wrapper that calls K32InitializeProcessForWsWatch. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as InitializeProcessForWsWatch. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and /// compile the program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-initializeprocessforwswatch BOOL InitializeProcessForWsWatch( // HANDLE hProcess ); [DllImport(Lib_Psapi, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("psapi.h", MSDNShortId = "c928656c-a59d-41b5-9434-911329b0278e")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InitializeProcessForWsWatch(HPROCESS hProcess); /// /// Retrieves information about the pages currently added to the working set of the specified process. /// /// To retrieve working set information for a subset of virtual addresses, or to retrieve information about pages that are not part /// of the working set (such as AWE or large pages), use the QueryWorkingSetEx function. /// /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For /// more information, see Process Security and Access Rights. /// /// /// /// A pointer to the buffer that receives the information. For more information, see PSAPI_WORKING_SET_INFORMATION. /// /// If the buffer pointed to by the pv parameter is not large enough to contain all working set entries for the target process, the /// function fails with ERROR_BAD_LENGTH. In this case, the NumberOfEntries member of the /// PSAPI_WORKING_SET_INFORMATION structure is set to the required number of entries, but the function does not return information /// about the working set entries. /// /// /// /// The size of the pv buffer, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32QueryWorkingSet in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as QueryWorkingSet in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32QueryWorkingSet. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as QueryWorkingSet. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile the /// program with -DPSAPI_VERSION=1. To use run-time dynamic linking, load Psapi.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-queryworkingset BOOL QueryWorkingSet( HANDLE hProcess, PVOID // pv, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "b932153f-2bbd-460e-8ff7-b3e493c397bb")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool QueryWorkingSet(HPROCESS hProcess, IntPtr pv, uint cb); /// /// Retrieves information about the pages currently added to the working set of the specified process. /// /// To retrieve working set information for a subset of virtual addresses, or to retrieve information about pages that are not part /// of the working set (such as AWE or large pages), use the QueryWorkingSetEx function. /// /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For /// more information, see Process Security and Access Rights. /// /// /// A list of entires. [PInvokeData("psapi.h", MSDNShortId = "b932153f-2bbd-460e-8ff7-b3e493c397bb")] public static PSAPI_WORKING_SET_BLOCK[] QueryWorkingSet(HPROCESS hProcess) { using var mem = SafeHGlobalHandle.CreateFromStructure(); var entries = 0; while (!QueryWorkingSet(GetCurrentProcess(), mem, mem.Size)) { entries = (int)mem.ToStructure().ToUInt64(); mem.Size = (entries + 1) * UIntPtr.Size + 1024; } entries = (int)mem.ToStructure().ToUInt64(); return mem.ToArray(entries, UIntPtr.Size); } /// /// Retrieves extended information about the pages at specific virtual addresses in the address space of the specified process. /// /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For /// more information, see Process Security and Access Rights. /// /// /// /// /// A pointer to an array of PSAPI_WORKING_SET_EX_INFORMATION structures. On input, each item in the array specifies a virtual /// address of interest. On output, each item in the array receives information about the corresponding virtual page. /// /// /// /// The size of the pv buffer, in bytes. /// /// /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Unlike the QueryWorkingSet function, which is limited to the working set of the target process, the QueryWorkingSetEx /// function can be used to query addresses that are not in the process working set but are still part of the process, such as AWE /// and large pages. /// /// /// Starting with Windows 7 and Windows Server 2008 R2, Psapi.h establishes version numbers for the PSAPI functions. The PSAPI /// version number affects the name used to call the function and the library that a program must load. /// /// /// If PSAPI_VERSION is 2 or greater, this function is defined as K32QueryWorkingSetEx in Psapi.h and exported in /// Kernel32.lib and Kernel32.dll. If PSAPI_VERSION is 1, this function is defined as QueryWorkingSetEx in Psapi.h and /// exported in Psapi.lib and Psapi.dll as a wrapper that calls K32QueryWorkingSetEx. /// /// /// Programs that must run on earlier versions of Windows as well as Windows 7 and later versions should always call this function /// as QueryWorkingSetEx. To ensure correct resolution of symbols, add Psapi.lib to the TARGETLIBS macro and compile /// the program with "–DPSAPI_VERSION=1". To use run-time dynamic linking, load Psapi.dll. /// /// Examples /// For an example, see Allocating Memory from a NUMA Node. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/nf-psapi-queryworkingsetex BOOL QueryWorkingSetEx( HANDLE hProcess, // PVOID pv, DWORD cb ); [DllImport(Lib_Psapi, SetLastError = true, ExactSpelling = true)] [PInvokeData("psapi.h", MSDNShortId = "59ae76c9-e954-4648-9c9f-787136375b02")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool QueryWorkingSetEx(HPROCESS hProcess, [In, Out] PSAPI_WORKING_SET_EX_INFORMATION[] pv, uint cb); /// /// Retrieves extended information about the pages at specific virtual addresses in the address space of the specified process. /// /// /// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION and PROCESS_VM_READ access rights. For /// more information, see Process Security and Access Rights. /// /// The virtual addresses. /// /// An array of PSAPI_WORKING_SET_EX_INFORMATION structures. On input, each item in the array specifies a virtual address of /// interest. On output, each item in the array receives information about the corresponding virtual page. /// /// /// Unlike the QueryWorkingSet function, which is limited to the working set of the target process, the QueryWorkingSetEx /// function can be used to query addresses that are not in the process working set but are still part of the process, such as AWE /// and large pages. /// [PInvokeData("psapi.h", MSDNShortId = "59ae76c9-e954-4648-9c9f-787136375b02")] public static PSAPI_WORKING_SET_EX_INFORMATION[] QueryWorkingSetEx(HPROCESS hProcess, [Optional] params IntPtr[] virtualAddresses) { PSAPI_WORKING_SET_EX_INFORMATION[] info = virtualAddresses == null || virtualAddresses.Length == 0 ? Array.ConvertAll(QueryWorkingSet(hProcess), b => new PSAPI_WORKING_SET_EX_INFORMATION() { VirtualAddress = b.VirtualPage }) : Array.ConvertAll(virtualAddresses, p => new PSAPI_WORKING_SET_EX_INFORMATION() { VirtualAddress = p }); var cb = (uint)Marshal.SizeOf(typeof(PSAPI_WORKING_SET_EX_INFORMATION)); return QueryWorkingSetEx(hProcess, info, (uint)info.Length * cb) ? info : throw Win32Error.GetLastError().GetException(); } /// Contains information about a pagefile. // https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-_enum_page_file_information typedef struct // _ENUM_PAGE_FILE_INFORMATION { DWORD cb; DWORD Reserved; SIZE_T TotalSize; SIZE_T TotalInUse; SIZE_T PeakUsage; } // ENUM_PAGE_FILE_INFORMATION, *PENUM_PAGE_FILE_INFORMATION; [PInvokeData("psapi.h", MSDNShortId = "020f3be8-f624-4788-8079-0f7679c9bef0")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct ENUM_PAGE_FILE_INFORMATION { /// The size of this structure, in bytes. public uint cb; /// This member is reserved. public uint Reserved; /// The total size of the pagefile, in pages. public SizeT TotalSize; /// The current pagefile usage, in pages. public SizeT TotalInUse; /// The peak pagefile usage, in pages. public SizeT PeakUsage; } /// /// Contains the module load address, size, and entry point. /// /// /// /// The load address of a module is the same as the HMODULE value. The information returned in the SizeOfImage and /// EntryPoint members comes from the module's Portable Executable (PE) header. The module entry point is the location called /// during process startup, thread startup, process shutdown, and thread shutdown. While this is not the address of the DllMain /// function, it should be close enough for most purposes. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_moduleinfo typedef struct _MODULEINFO { LPVOID lpBaseOfDll; // DWORD SizeOfImage; LPVOID EntryPoint; } MODULEINFO, *LPMODULEINFO; [PInvokeData("psapi.h", MSDNShortId = "583caafe-7fa3-4041-b5bc-4e8899b3a08a")] [StructLayout(LayoutKind.Sequential)] public struct MODULEINFO { /// /// The load address of the module. /// public IntPtr lpBaseOfDll; /// /// The size of the linear space that the module occupies, in bytes. /// public uint SizeOfImage; /// /// The entry point of the module. /// public IntPtr EntryPoint; } /// /// Contains performance information. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_performance_information typedef struct // _PERFORMANCE_INFORMATION { DWORD cb; SIZE_T CommitTotal; SIZE_T CommitLimit; SIZE_T CommitPeak; SIZE_T PhysicalTotal; SIZE_T // PhysicalAvailable; SIZE_T SystemCache; SIZE_T KernelTotal; SIZE_T KernelPaged; SIZE_T KernelNonpaged; SIZE_T PageSize; DWORD // HandleCount; DWORD ProcessCount; DWORD ThreadCount; } PERFORMANCE_INFORMATION, *PPERFORMANCE_INFORMATION, PERFORMACE_INFORMATION, *PPERFORMACE_INFORMATION; [PInvokeData("psapi.h", MSDNShortId = "efc47f6e-1a60-4e77-9e5d-c725f9042ab8")] [StructLayout(LayoutKind.Sequential)] public struct PERFORMANCE_INFORMATION { /// /// The size of this structure, in bytes. /// public uint cb; /// /// /// The number of pages currently committed by the system. Note that committing pages (using VirtualAlloc with MEM_COMMIT) /// changes this value immediately; however, the physical memory is not charged until the pages are accessed. /// /// public SizeT CommitTotal; /// /// /// The current maximum number of pages that can be committed by the system without extending the paging file(s). This number /// can change if memory is added or deleted, or if pagefiles have grown, shrunk, or been added. If the paging file can be /// extended, this is a soft limit. /// /// public SizeT CommitLimit; /// /// The maximum number of pages that were simultaneously in the committed state since the last system reboot. /// public SizeT CommitPeak; /// /// The amount of actual physical memory, in pages. /// public SizeT PhysicalTotal; /// /// /// The amount of physical memory currently available, in pages. This is the amount of physical memory that can be immediately /// reused without having to write its contents to disk first. It is the sum of the size of the standby, free, and zero lists. /// /// public SizeT PhysicalAvailable; /// /// The amount of system cache memory, in pages. This is the size of the standby list plus the system working set. /// public SizeT SystemCache; /// /// The sum of the memory currently in the paged and nonpaged kernel pools, in pages. /// public SizeT KernelTotal; /// /// The memory currently in the paged kernel pool, in pages. /// public SizeT KernelPaged; /// /// The memory currently in the nonpaged kernel pool, in pages. /// public SizeT KernelNonpaged; /// /// The size of a page, in bytes. /// public SizeT PageSize; /// /// The current number of open handles. /// public uint HandleCount; /// /// The current number of processes. /// public uint ProcessCount; /// /// The current number of threads. /// public uint ThreadCount; /// A default initialized instance. public static readonly PERFORMANCE_INFORMATION Default = new() { cb = (uint)Marshal.SizeOf(typeof(PERFORMANCE_INFORMATION)) }; } /// /// Contains the memory statistics for a process. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters typedef struct // _PROCESS_MEMORY_COUNTERS { DWORD cb; DWORD PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T // QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T // PagefileUsage; SIZE_T PeakPagefileUsage; } PROCESS_MEMORY_COUNTERS; [PInvokeData("psapi.h", MSDNShortId = "288b5865-28a3-478b-ad32-c710fe4f3a81")] [StructLayout(LayoutKind.Sequential)] public struct PROCESS_MEMORY_COUNTERS { /// /// The size of the structure, in bytes. /// public uint cb; /// /// The number of page faults. /// public uint PageFaultCount; /// /// The peak working set size, in bytes. /// public SizeT PeakWorkingSetSize; /// /// The current working set size, in bytes. /// public SizeT WorkingSetSize; /// /// The peak paged pool usage, in bytes. /// public SizeT QuotaPeakPagedPoolUsage; /// /// The current paged pool usage, in bytes. /// public SizeT QuotaPagedPoolUsage; /// /// The peak nonpaged pool usage, in bytes. /// public SizeT QuotaPeakNonPagedPoolUsage; /// /// The current nonpaged pool usage, in bytes. /// public SizeT QuotaNonPagedPoolUsage; /// /// /// The Commit Charge value in bytes for this process. Commit Charge is the total amount of memory that the memory manager has /// committed for a running process. /// /// public SizeT PagefileUsage; /// /// The peak value in bytes of the Commit Charge during the lifetime of this process. /// public SizeT PeakPagefileUsage; /// A default initialized instance. public static readonly PROCESS_MEMORY_COUNTERS Default = new() { cb = (uint)Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS)) }; } /// Contains extended memory statistics for a process. // https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-process_memory_counters_ex typedef struct // _PROCESS_MEMORY_COUNTERS_EX { DWORD cb; DWORD PageFaultCount; SIZE_T PeakWorkingSetSize; SIZE_T WorkingSetSize; SIZE_T // QuotaPeakPagedPoolUsage; SIZE_T QuotaPagedPoolUsage; SIZE_T QuotaPeakNonPagedPoolUsage; SIZE_T QuotaNonPagedPoolUsage; SIZE_T // PagefileUsage; SIZE_T PeakPagefileUsage; SIZE_T PrivateUsage; } PROCESS_MEMORY_COUNTERS_EX; [PInvokeData("psapi.h", MSDNShortId = "cf06445d-b71a-4320-afc8-4bd88ebfb284")] [StructLayout(LayoutKind.Sequential)] public struct PROCESS_MEMORY_COUNTERS_EX { /// The size of the structure, in bytes. public uint cb; /// The number of page faults. public uint PageFaultCount; /// The peak working set size, in bytes. public SizeT PeakWorkingSetSize; /// The current working set size, in bytes. public SizeT WorkingSetSize; /// The peak paged pool usage, in bytes. public SizeT QuotaPeakPagedPoolUsage; /// The current paged pool usage, in bytes. public SizeT QuotaPagedPoolUsage; /// The peak nonpaged pool usage, in bytes. public SizeT QuotaPeakNonPagedPoolUsage; /// The current nonpaged pool usage, in bytes. public SizeT QuotaNonPagedPoolUsage; /// /// /// The Commit Charge value in bytes for this process. Commit Charge is the total amount of memory that the memory manager has /// committed for a running process. /// /// /// Windows 7 and Windows Server 2008 R2 and earlier:PagefileUsage is always zero. Check PrivateUsage instead. /// /// public SizeT PagefileUsage; /// The peak value in bytes of the Commit Charge during the lifetime of this process. public SizeT PeakPagefileUsage; /// /// Same as PagefileUsage. The Commit Charge value in bytes for this process. Commit Charge is the total amount of memory /// that the memory manager has committed for a running process. /// public SizeT PrivateUsage; /// A default initialized instance. public static readonly PROCESS_MEMORY_COUNTERS_EX Default = new() { cb = (uint)Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS_EX)) }; } /// Contains working set information for a page. // https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-psapi_working_set_block typedef union _PSAPI_WORKING_SET_BLOCK // { ULONG_PTR Flags; struct { ULONG_PTR Protection : 5; ULONG_PTR ShareCount : 3; ULONG_PTR Shared : 1; ULONG_PTR Reserved : 3; #if // ... ULONG_PTR VirtualPage : 52; #elif ULONG_PTR VirtualPage : 52; #elif ULONG_PTR VirtualPage : 20; #else ULONG_PTR VirtualPage : // 20; #endif }; } PSAPI_WORKING_SET_BLOCK, *PPSAPI_WORKING_SET_BLOCK; [PInvokeData("psapi.h", MSDNShortId = "feb64235-1003-4595-a6a9-aca1f94f94b8")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WORKING_SET_BLOCK { /// /// The working set information. See the description of the structure members for information about the layout of this variable. /// public UIntPtr Flags; /// If , the page is sharable; otherwise, the page is not sharable. public bool Shared => GetBit(Flags.ToUInt32(), 9); /// The number of processes that share this page. The maximum value of this member is 7. public uint ShareCount => GetBits(Flags.ToUInt32(), 5, 3); /// /// The protection attributes of the page. This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// The page is not accessed. /// /// /// 1 /// Read-only. /// /// /// 2 /// Executable. /// /// /// 3 /// Executable and read-only. /// /// /// 4 /// Read/write. /// /// /// 5 /// Copy-on-write. /// /// /// 6 /// Executable and read/write. /// /// /// 7 /// Executable and copy-on-write. /// /// /// 8 /// The page is not accessed. /// /// /// 9 /// Non-cacheable and read-only. /// /// /// 10 /// Non-cacheable and executable. /// /// /// 11 /// Non-cacheable, executable, and read-only. /// /// /// 12 /// Non-cacheable and read/write. /// /// /// 13 /// Non-cacheable and copy-on-write. /// /// /// 14 /// Non-cacheable, executable, and read/write. /// /// /// 15 /// Non-cacheable, executable, and copy-on-write. /// /// /// 16 /// The page is not accessed. /// /// /// 17 /// Guard page and read-only. /// /// /// 18 /// Guard page and executable. /// /// /// 19 /// Guard page, executable, and read-only. /// /// /// 20 /// Guard page and read/write. /// /// /// 21 /// Guard page and copy-on-write. /// /// /// 22 /// Guard page, executable, and read/write. /// /// /// 23 /// Guard page, executable, and copy-on-write. /// /// /// 24 /// The page is not accessed. /// /// /// 25 /// Non-cacheable, guard page, and read-only. /// /// /// 26 /// Non-cacheable, guard page, and executable. /// /// /// 27 /// Non-cacheable, guard page, executable, and read-only. /// /// /// 28 /// Non-cacheable, guard page, and read/write. /// /// /// 29 /// Non-cacheable, guard page, and copy-on-write. /// /// /// 30 /// Non-cacheable, guard page, executable, and read/write. /// /// /// 31 /// Non-cacheable, guard page, executable, and copy-on-write. /// /// /// public uint Protection => GetBits(Flags.ToUInt32(), 0, 5); /// public IntPtr VirtualPage => new((long)Flags.ToUInt64() & ~0xFFFL); } /// Contains extended working set information for a page. // https://https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-psapi_working_set_ex_block typedef union // _PSAPI_WORKING_SET_EX_BLOCK { ULONG_PTR Flags; union { struct { ULONG_PTR Valid : 1; ULONG_PTR ShareCount : 3; ULONG_PTR // Win32Protection : 11; ULONG_PTR Shared : 1; ULONG_PTR Node : 6; ULONG_PTR Locked : 1; ULONG_PTR LargePage : 1; ULONG_PTR Reserved // : 7; ULONG_PTR Bad : 1; ULONG_PTR ReservedUlong : 32; }; struct { ULONG_PTR Valid : 1; ULONG_PTR Reserved0 : 14; ULONG_PTR Shared // : 1; ULONG_PTR Reserved1 : 15; ULONG_PTR Bad : 1; ULONG_PTR ReservedUlong : 32; } Invalid; }; } PSAPI_WORKING_SET_EX_BLOCK, *PPSAPI_WORKING_SET_EX_BLOCK; [PInvokeData("psapi.h", MSDNShortId = "4ba17fa0-2aed-4099-9380-fc13f1b826ca")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WORKING_SET_EX_BLOCK { /// /// The working set information. See the description of the structure members for information about the layout of this variable. /// public UIntPtr Flags; /// If , the page is valid; otherwise, the page is not valid. public bool Valid => GetBit(Flags.ToUInt32(), 0); /// Gets a value indicating whether the virtual page is locked in physical memory. public bool Locked => Valid && GetBit(Flags.ToUInt32(), 22); /// Gets a value indicating whether this page is a large page. public bool LargePage => Valid && GetBit(Flags.ToUInt32(), 23); /// Gets a value indicating whether the page is has been reported as bad. public bool Bad => GetBit(Flags.ToUInt32(), 31); /// If , the page is sharable; otherwise, the page is not sharable. public bool Shared => GetBit(Flags.ToUInt32(), 15); /// The number of processes that share this page. The maximum value of this member is 7. public uint ShareCount => Valid ? GetBits(Flags.ToUInt32(), 1, 3) : 0U; /// /// The protection attributes of the page. This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// The page is not accessed. /// /// /// 1 /// Read-only. /// /// /// 2 /// Executable. /// /// /// 3 /// Executable and read-only. /// /// /// 4 /// Read/write. /// /// /// 5 /// Copy-on-write. /// /// /// 6 /// Executable and read/write. /// /// /// 7 /// Executable and copy-on-write. /// /// /// 8 /// The page is not accessed. /// /// /// 9 /// Non-cacheable and read-only. /// /// /// 10 /// Non-cacheable and executable. /// /// /// 11 /// Non-cacheable, executable, and read-only. /// /// /// 12 /// Non-cacheable and read/write. /// /// /// 13 /// Non-cacheable and copy-on-write. /// /// /// 14 /// Non-cacheable, executable, and read/write. /// /// /// 15 /// Non-cacheable, executable, and copy-on-write. /// /// /// 16 /// The page is not accessed. /// /// /// 17 /// Guard page and read-only. /// /// /// 18 /// Guard page and executable. /// /// /// 19 /// Guard page, executable, and read-only. /// /// /// 20 /// Guard page and read/write. /// /// /// 21 /// Guard page and copy-on-write. /// /// /// 22 /// Guard page, executable, and read/write. /// /// /// 23 /// Guard page, executable, and copy-on-write. /// /// /// 24 /// The page is not accessed. /// /// /// 25 /// Non-cacheable, guard page, and read-only. /// /// /// 26 /// Non-cacheable, guard page, and executable. /// /// /// 27 /// Non-cacheable, guard page, executable, and read-only. /// /// /// 28 /// Non-cacheable, guard page, and read/write. /// /// /// 29 /// Non-cacheable, guard page, and copy-on-write. /// /// /// 30 /// Non-cacheable, guard page, executable, and read/write. /// /// /// 31 /// Non-cacheable, guard page, executable, and copy-on-write. /// /// /// public uint Protection => Valid ? GetBits(Flags.ToUInt32(), 4, 11) : 0U; /// Gets the NUMA node. The maximum value of this member is 63. public uint Node => Valid ? GetBits(Flags.ToUInt32(), 16, 6) : 0U; } /// Contains extended working set information for a process. // https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-_psapi_working_set_ex_information typedef struct // _PSAPI_WORKING_SET_EX_INFORMATION { PVOID VirtualAddress; PSAPI_WORKING_SET_EX_BLOCK VirtualAttributes; } // PSAPI_WORKING_SET_EX_INFORMATION, *PPSAPI_WORKING_SET_EX_INFORMATION; [PInvokeData("psapi.h", MSDNShortId = "d3500737-b9af-41a8-bf69-61d0bfbd6ce4")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WORKING_SET_EX_INFORMATION { /// The virtual address. public IntPtr VirtualAddress; /// A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress. public PSAPI_WORKING_SET_EX_BLOCK VirtualAttributes; } /// Contains working set information for a process. // https://docs.microsoft.com/zh-cn/windows/win32/api/psapi/ns-psapi-psapi_working_set_information typedef struct // _PSAPI_WORKING_SET_INFORMATION { ULONG_PTR NumberOfEntries; PSAPI_WORKING_SET_BLOCK WorkingSetInfo[1]; } // PSAPI_WORKING_SET_INFORMATION, *PPSAPI_WORKING_SET_INFORMATION; [PInvokeData("psapi.h", MSDNShortId = "59ca42c0-ca88-4153-b061-980d961a8ca2")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WORKING_SET_INFORMATION { /// The number of entries in the WorkingSetInfo array. public UIntPtr NumberOfEntries; private PSAPI_WORKING_SET_BLOCK padding; /// An array of PSAPI_WORKING_SET_BLOCK elements, one for each page in the process working set. public PSAPI_WORKING_SET_BLOCK[] WorkingSetInfo { get { unsafe { fixed (PSAPI_WORKING_SET_INFORMATION* ptr = &this) { var ret = new PSAPI_WORKING_SET_BLOCK[NumberOfEntries.ToUInt64()]; var pblk = (PSAPI_WORKING_SET_BLOCK*)(ptr + 1); for (ulong i = 0; i < NumberOfEntries.ToUInt64(); i++) ret[i] = pblk[i]; return ret; } } } } } /// /// Contains information about a page added to a process working set. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_psapi_ws_watch_information typedef struct // _PSAPI_WS_WATCH_INFORMATION { LPVOID FaultingPc; LPVOID FaultingVa; } PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION; [PInvokeData("psapi.h", MSDNShortId = "61083366-2a55-431c-807a-3eb85ba0b347")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WS_WATCH_INFORMATION { /// /// A pointer to the instruction that caused the page fault. /// public IntPtr FaultingPc; /// /// A pointer to the page that was added to the working set. /// public IntPtr FaultingVa; } /// /// Contains extended information about a page added to a process working set. /// // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_psapi_ws_watch_information_ex typedef struct // _PSAPI_WS_WATCH_INFORMATION_EX { PSAPI_WS_WATCH_INFORMATION BasicInfo; ULONG_PTR FaultingThreadId; ULONG_PTR Flags; } // PSAPI_WS_WATCH_INFORMATION_EX, *PPSAPI_WS_WATCH_INFORMATION_EX; [PInvokeData("psapi.h", MSDNShortId = "fb0429b1-ec93-401c-aeb1-f7e9d9acfa47")] [StructLayout(LayoutKind.Sequential)] public struct PSAPI_WS_WATCH_INFORMATION_EX { /// /// A PSAPI_WS_WATCH_INFORMATION structure. /// public PSAPI_WS_WATCH_INFORMATION BasicInfo; /// /// The identifier of the thread that caused the page fault. /// public UIntPtr FaultingThreadId; /// /// This member is reserved for future use. /// public UIntPtr Flags; } } }