using System; using System.Linq; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; using Vanara.InteropServices; using static Vanara.PInvoke.Kernel32; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace Vanara.PInvoke { /// Pdh Performance Counter functions and structures. public static partial class Pdh { #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member public const uint PDH_CVERSION_WIN40 = 0x0400; public const uint PDH_CVERSION_WIN50 = 0x0500; public const int PDH_MAX_COUNTER_PATH = 2048; // v1.1 revision of PDH -- basic log functions v1.2 of the PDH -- adds variable instance counters v1.3 of the PDH -- adds log service // control & stubs for NT5/PDH v2 fn's v2.0 of the PDH -- is the NT v 5.0 B2 version public const uint PDH_VERSION = PDH_CVERSION_WIN50 + 0x0003; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member /// /// Applications implement the CounterPathCallBack function to process the counter path strings returned by the Browse /// dialog box. /// /// /// /// Return ERROR_SUCCESS if the function succeeds. /// If the function fails due to a transient error, you can return PDH_RETRY and PDH will call your callback immediately. /// Otherwise, return an appropriate error code. The error code is passed back to the caller of PdhBrowseCounters. /// /// The following members of the PDH_BROWSE_DLG_CONFIG structure are used to communicate with the callback function: // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nc-pdh-counterpathcallback CounterPathCallBack Counterpathcallback; // PDH_STATUS Counterpathcallback( DWORD_PTR Arg1 ) {...} [UnmanagedFunctionPointer(CallingConvention.Winapi)] [PInvokeData("pdh.h", MSDNShortId = "b7a2112e-9f50-4a36-b022-f9609b2827bc")] public delegate Win32Error CounterPathCallBack(IntPtr Arg1); /// Flags used by PDH_BROWSE_DLG_CONFIG. [PInvokeData("pdh.h", MSDNShortId = "8e045e0b-c157-4527-902c-6096c7922642")] [Flags] public enum BrowseFlag { /// /// If this flag is TRUE, the dialog box includes an index number for duplicate instance names. For example, if there are /// two cmd instances, the instance list will contain cmd and cmd#1. If this flag is FALSE, duplicate instance names will /// not contain an index number. /// bIncludeInstanceIndex = 1 << 0, /// /// If this flag is TRUE, the dialog returns only one counter. If this flag is FALSE, the dialog can return /// multiple selections, and wildcard selections are permitted. Selected counters are returned as a MULTI_SZ string. /// bSingleCounterPerAdd = 1 << 1, /// /// If this flag is TRUE, the dialog box uses an OK and Cancel button. The dialog returns when the user clicks either /// button. If this flag is FALSE, the dialog box uses an Add and Close button. The dialog box closes when the user clicks /// the Close button. The Add button can be clicked multiple times. The Add button overwrites the previously selected items with /// the currently selected items. /// bSingleCounterPerDialog = 1 << 2, /// /// If this flag is TRUE, the dialog box lets the user select counters only from the local computer (the path will not /// contain a computer name). If this flag is FALSE, the user can specify a computer from which to select counters. The /// computer name will prefix the counter path unless the user selects Use local computer counters. /// bLocalCountersOnly = 1 << 3, /// /// /// If this flag is TRUE and the user selects All instances, the counter path will include the wildcard character /// for the instance field. /// /// /// If this flag is FALSE, and the user selects All instances, all the instances currently found for that object /// will be returned in a MULTI_SZ string. /// /// bWildCardInstances = 1 << 4, /// /// /// If this flag is TRUE, this removes Detail level from the dialog box so the user cannot change the detail level /// of the counters displayed in the dialog box. The detail level will be fixed to the value of the dwDefaultDetailLevel member. /// /// /// If this flag is FALSE, this displays Detail level in the dialog box, allowing the user to change the detail /// level of the counters displayed. /// /// /// Note that the counters displayed will be those whose detail level is less than or equal to the current detail level /// selection. Selecting a detail level of Wizard will display all counters and objects. /// /// bHideDetailBox = 1 << 5, /// /// /// If this flag is TRUE, the dialog highlights the counter and object specified in szReturnPathBuffer when the /// dialog box is first displayed, instead of using the default counter and object specified by the computer. /// /// /// If this flag is FALSE, this selects the initial counter and object using the default counter and object information /// returned by the computer. /// /// bInitializePath = 1 << 6, /// /// If this flag is TRUE, the user cannot select a computer from Select counters from computer. /// /// If this flag is FALSE, the user can select a computer from Select counters from computer. This is the default /// value. The list contains the local computer only unless you call the PdhConnectMachine to connect to other computers first. /// /// bDisableMachineSelection = 1 << 7, /// /// /// If this flag is TRUE, the counters list will also contain costly data—that is, data that requires a relatively large /// amount of processor time or memory overhead to collect. /// /// If this flag is FALSE, the list will not contain costly counters. This is the default value. /// bIncludeCostlyObjects = 1 << 8, /// /// If this flag is TRUE, the dialog lists only performance objects. When the user selects an object, the dialog returns a /// counter path that includes the object and wildcard characters for the instance name and counter if the object is a multiple /// instance object. For example, if the "Process" object is selected, the dialog returns the string "\Process(*)*". If the /// object is a single instance object, the path contains a wildcard character for counter only. For example, "\System*". You can /// then pass the path to PdhExpandWildCardPath to retrieve a list of actual paths for the object. /// bShowObjectBrowser = 1 << 9, } /// Performance counter type. [Flags] public enum CounterType : uint { /// A number (not a counter) PERF_TYPE_NUMBER = 0x00000000, /// 32 bit field PERF_SIZE_DWORD = 0x00000000, /// 64 bit field PERF_SIZE_LARGE = 0x00000100, /// for Zero Length fields PERF_SIZE_ZERO = 0x00000200, /// length is in CounterLength field PERF_SIZE_VARIABLE_LEN = 0x00000300, /// An increasing numeric value PERF_TYPE_COUNTER = 0x00000400, /// A text field PERF_TYPE_TEXT = 0x00000800, /// Displays a zero PERF_TYPE_ZERO = 0x00000C00, /// Display as HEX value PERF_NUMBER_HEX = 0x00000000, /// Display as a decimal integer PERF_NUMBER_DECIMAL = 0x00010000, /// Display as a decimal/1000 PERF_NUMBER_DEC_1000 = 0x00020000, /// Display counter value PERF_COUNTER_VALUE = 0x00000000, /// Divide ctr / delta time PERF_COUNTER_RATE = 0x00010000, /// Divide ctr / base PERF_COUNTER_FRACTION = 0x00020000, /// Base value used in fractions PERF_COUNTER_BASE = 0x00030000, /// Subtract counter from current time PERF_COUNTER_ELAPSED = 0x00040000, /// Use Queuelen processing func. PERF_COUNTER_QUEUELEN = 0x00050000, /// Counter begins or ends a histogram PERF_COUNTER_HISTOGRAM = 0x00060000, /// Divide ctr / private clock PERF_COUNTER_PRECISION = 0x00070000, /// Type of text in text field PERF_TEXT_UNICODE = 0x00000000, /// ASCII using the CodePage field PERF_TEXT_ASCII = 0x00010000, /// Use system perf. freq for base PERF_TIMER_TICK = 0x00000000, /// Use 100 NS timer time base units PERF_TIMER_100NS = 0x00100000, /// Use the object timer freq PERF_OBJECT_TIMER = 0x00200000, /// Compute difference first PERF_DELTA_COUNTER = 0x00400000, /// Compute base diff as well PERF_DELTA_BASE = 0x00800000, /// Show as 1.00-value (assumes: PERF_INVERSE_COUNTER = 0x01000000, /// Sum of multiple instances PERF_MULTI_COUNTER = 0x02000000, /// No suffix PERF_DISPLAY_NO_SUFFIX = 0x00000000, /// "/sec" PERF_DISPLAY_PER_SEC = 0x10000000, /// "%" PERF_DISPLAY_PERCENT = 0x20000000, /// "secs" PERF_DISPLAY_SECONDS = 0x30000000, /// Value is not displayed PERF_DISPLAY_NOSHOW = 0x40000000, /// 32-bit Counter. Divide delta by delta time. Display suffix: "/sec" PERF_COUNTER_COUNTER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC, /// 64-bit Timer. Divide delta by delta time. Display suffix: "%" PERF_COUNTER_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, /// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. PERF_COUNTER_QUEUELEN_TYPE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// Queue Length Space-Time Product. Divide delta by delta time. No Display Suffix. PERF_COUNTER_LARGE_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// Queue Length Space-Time Product using 100 Ns timebase. Divide delta by delta time. No Display Suffix. PERF_COUNTER_100NS_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// Queue Length Space-Time Product using Object specific timebase. Divide delta by delta time. No Display Suffix. PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_QUEUELEN | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// 64-bit Counter. Divide delta by delta time. Display Suffix: "/sec" PERF_COUNTER_BULK_COUNT = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC, /// Indicates the counter is not a counter but rather Unicode text Display as text. PERF_COUNTER_TEXT = PERF_SIZE_VARIABLE_LEN | PERF_TYPE_TEXT | PERF_TEXT_UNICODE | PERF_DISPLAY_NO_SUFFIX, /// /// Indicates the data is a counter which should not be time averaged on display (such as an error counter on a serial line) /// Display as is. No Display Suffix. /// PERF_COUNTER_RAWCOUNT = PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, /// Same as PERF_COUNTER_RAWCOUNT except its size is a large integer PERF_COUNTER_LARGE_RAWCOUNT = PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX, /// /// Special case for RAWCOUNT that want to be displayed in hex Indicates the data is a counter which should not be time averaged /// on display (such as an error counter on a serial line) Display as is. No Display Suffix. /// PERF_COUNTER_RAWCOUNT_HEX = PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX, /// Same as PERF_COUNTER_RAWCOUNT_HEX except its size is a large integer PERF_COUNTER_LARGE_RAWCOUNT_HEX = PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_HEX | PERF_DISPLAY_NO_SUFFIX, /// /// A count which is either 1 or 0 on each sampling interrupt (% busy) Divide delta by delta base. Display Suffix: "%" /// PERF_SAMPLE_FRACTION = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DELTA_COUNTER | PERF_DELTA_BASE | PERF_DISPLAY_PERCENT, /// A count which is sampled on each sampling interrupt (queue length) Divide delta by delta time. No Display Suffix. PERF_SAMPLE_COUNTER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// A label: no data is associated with this counter (it has 0 length) Do not display. PERF_COUNTER_NODATA = PERF_SIZE_ZERO | PERF_DISPLAY_NOSHOW, /// /// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 - delta divided by delta time. Display suffix: "%" /// PERF_COUNTER_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT, /// /// The divisor for a sample, used with the previous counter to form a sampled %. You must check for >0 before dividing by /// this! This counter will directly follow the numerator counter. It should not be displayed to the user. /// PERF_SAMPLE_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000001, /// /// A timer which, when divided by an average base, produces a time in seconds which is the average time of some operation. This /// timer times total operations, and the base is the number of operations. Display Suffix: "sec" /// PERF_AVERAGE_TIMER = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_SECONDS, /// /// Used as the denominator in the computation of time or count averages. Must directly follow the numerator counter. Not /// displayed to the user. /// PERF_AVERAGE_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000002, /// /// A bulk count which, when divided (typically) by the number of operations, gives (typically) the number of bytes per /// operation. No Display Suffix. /// PERF_AVERAGE_BULK = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_NOSHOW, /// /// 64-bit Timer in object specific units. Display delta divided by delta time as returned in the object type header structure. /// Display suffix: "%" /// PERF_OBJ_TIME_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, /// 64-bit Timer in 100 nsec units. Display delta divided by delta time. Display suffix: "%" PERF_100NSEC_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, /// /// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 - delta divided by delta time. Display suffix: "%" /// PERF_100NSEC_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT, /// /// 64-bit Timer. Divide delta by delta time. Display suffix: "%" Timer for multiple instances, so result can exceed 100%. /// PERF_COUNTER_MULTI_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_TIMER_TICK | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT, /// /// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 * _MULTI_BASE - delta divided by delta time. /// Display suffix: "%" Timer for multiple instances, so result can exceed 100%. Followed by a counter of type _MULTI_BASE. /// PERF_COUNTER_MULTI_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_MULTI_COUNTER | PERF_TIMER_TICK | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT, /// Number of instances to which the preceding _MULTI_..._INV counter applies. Used as a factor to get the percentage. PERF_COUNTER_MULTI_BASE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_MULTI_COUNTER | PERF_DISPLAY_NOSHOW, /// /// 64-bit Timer in 100 nsec units. Display delta divided by delta time. Display suffix: "%" Timer for multiple instances, so /// result can exceed 100%. /// PERF_100NSEC_MULTI_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_DISPLAY_PERCENT, /// /// 64-bit Timer inverse (e.g., idle is measured, but display busy %) Display 100 * _MULTI_BASE - delta divided by delta time. /// Display suffix: "%" Timer for multiple instances, so result can exceed 100%. Followed by a counter of type _MULTI_BASE. /// PERF_100NSEC_MULTI_TIMER_INV = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_DELTA_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_MULTI_COUNTER | PERF_INVERSE_COUNTER | PERF_DISPLAY_PERCENT, /// /// Indicates the data is a fraction of the following counter which should not be time averaged on display (such as free space /// over total space.) Display as is. Display the quotient as "%". /// PERF_RAW_FRACTION = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT, /// /// Indicates the data is a fraction of the following counter which should not be time averaged on display (such as free space /// over total space.) Display as is. Display the quotient as "%". /// PERF_LARGE_RAW_FRACTION = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_FRACTION | PERF_DISPLAY_PERCENT, /// /// Indicates the data is a base for the preceding counter which should not be time averaged on display (such as free space over /// total space.) /// PERF_RAW_BASE = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW | 0x00000003, // for compatibility with pre-beta version, /// /// Indicates the data is a base for the preceding counter which should not be time averaged on display (such as free space over /// total space.) /// PERF_LARGE_RAW_BASE = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW, /// /// The data collected in this counter is actually the start time of the item being measured. For display, this data is /// subtracted from the sample time to yield the elapsed time as the difference between the two. In the definition below, the /// PerfTime field of the Object contains the sample time as indicated by the PERF_OBJECT_TIMER bit and the difference is scaled /// by the PerfFreq of the Object to convert the time units into seconds. /// PERF_ELAPSED_TIME = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_ELAPSED | PERF_OBJECT_TIMER | PERF_DISPLAY_SECONDS, /// /// The following counter type can be used with the preceding types to define a range of values to be displayed in a histogram. /// PERF_COUNTER_HISTOGRAM_TYPE = 0x8000000, /// /// This counter is used to display the difference from one sample to the next. The counter value is a constantly increasing /// number and the value displayed is the difference between the current value and the previous value. Negative numbers are not /// allowed which shouldn't be a problem as long as the counter value is increasing or unchanged. /// PERF_COUNTER_DELTA = PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// /// This counter is used to display the difference from one sample to the next. The counter value is a constantly increasing /// number and the value displayed is the difference between the current value and the previous value. Negative numbers are not /// allowed which shouldn't be a problem as long as the counter value is increasing or unchanged. /// PERF_COUNTER_LARGE_DELTA = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_VALUE | PERF_DELTA_COUNTER | PERF_DISPLAY_NO_SUFFIX, /// The timer used has the same frequency as the System Performance Timer PERF_PRECISION_SYSTEM_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_TICK | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, /// The timer used has the same frequency as the 100 NanoSecond Timer PERF_PRECISION_100NS_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, /// The timer used is of the frequency specified in the Object header's PerfFreq field (PerfTime is ignored) PERF_PRECISION_OBJECT_TIMER = PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_PRECISION | PERF_OBJECT_TIMER | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT, } /// Determines the data type of the calculated value. [PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")] public enum PDH_FMT { /// PDH_FMT_RAW = 0x00000010, /// Return the calculated value as an ANSI string. PDH_FMT_ANSI = 0x00000020, /// Return the calculated value as a Unicode string. PDH_FMT_UNICODE = 0x00000040, /// Return the calculated value as a long integer. PDH_FMT_LONG = 0x00000100, /// Return the calculated value as a double-precision floating point real. PDH_FMT_DOUBLE = 0x00000200, /// Return the calculated value as a 64-bit integer. PDH_FMT_LARGE = 0x00000400, /// Do not apply the counter's scaling factor in the calculation. PDH_FMT_NOSCALE = 0x00001000, /// Multiply the final value by 1,000. PDH_FMT_1000 = 0x00002000, /// PDH_FMT_NODATA = 0x00004000, /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will /// not be reset to 100. The default behavior is that counter values are capped at a value of 100. /// PDH_FMT_NOCAP100 = 0x00008000, } /// Type of record for PDH_RAW_LOG_RECORD. [PInvokeData("pdh.h", MSDNShortId = "ae96515f-ea3f-4578-a249-fb8f41cdfa69")] public enum PDH_LOG_TYPE { /// Undefined record format. PDH_LOG_TYPE_UNDEFINED = 0, /// A comma-separated-value format record PDH_LOG_TYPE_CSV = 1, /// A tab-separated-value format record PDH_LOG_TYPE_TSV = 2, /// PDH_LOG_TYPE_TRACE_KERNEL = 4, /// PDH_LOG_TYPE_TRACE_GENERIC = 5, /// A Perfmon format record PDH_LOG_TYPE_PERFMON = 6, /// A SQL format record PDH_LOG_TYPE_SQL = 7, /// A binary trace format record PDH_LOG_TYPE_BINARY = 8, } /// Format of the input and output counter values. [PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")] public enum PDH_PATH { /// Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter. PDH_PATH_DEFAULT = 0x00000000, /// Converts a PDH path to the WMI class and property name format. PDH_PATH_WBEM_RESULT = 0x00000001, /// Converts the WMI class and property name to a PDH path. PDH_PATH_WBEM_INPUT = 0x00000002 } /// Flags that indicate which wildcard characters not to expand. [PInvokeData("pdh.h", MSDNShortId = "415da310-de56-4d58-8959-231426867526")] [Flags] public enum PdhExpandFlags { /// Do not expand the counter name if the path contains a wildcard character for counter name. PDH_NOEXPANDCOUNTERS = 1, /// /// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index. /// PDH_NOEXPANDINSTANCES = 2, /// PDH_REFRESHCOUNTERS = 4 } /// Type of access to use to open the log file. [PInvokeData("pdh.h", MSDNShortId = "a8457959-af3a-497f-91ca-0876cbb552cc")] [Flags] public enum PdhLogAccess : uint { /// Open the log file for reading. PDH_LOG_READ_ACCESS = 0x00010000, /// Open a new log file for writing. PDH_LOG_WRITE_ACCESS = 0x00020000, /// Open an existing log file for writing. PDH_LOG_UPDATE_ACCESS = 0x00040000, /// Creates a new log file with the specified name. PDH_LOG_CREATE_NEW = 0x00000001, /// /// Creates a new log file with the specified name. If the log file already exists, the function removes the existing log file /// before creating the new file. /// PDH_LOG_CREATE_ALWAYS = 0x00000002, /// /// Opens an existing log file with the specified name or creates a new log file with the specified name.Opens an existing log /// file with the specified name or creates a new log file with the specified name. /// PDH_LOG_OPEN_ALWAYS = 0x00000003, /// /// Opens an existing log file with the specified name. If a log file with the specified name does not exist, this is equal to PDH_LOG_CREATE_NEW. /// PDH_LOG_OPEN_EXISTING = 0x00000004, /// /// Used with PDH_LOG_TYPE_TSV to write the user caption or log file description indicated by the szUserString parameter of /// PdhUpdateLog or PdhOpenLog. The user caption or log file description is written as the last column in the first line of the /// text log. /// PDH_LOG_OPT_USER_STRING = 0x01000000, /// /// Creates a circular log file with the specified name. When the file reaches the value of the dwMaxSize parameter, data wraps /// to the beginning of the log file. You can specify this flag only if the lpdwLogType parameter is PDH_LOG_TYPE_BINARY. /// PDH_LOG_OPT_CIRCULAR = 0x02000000, /// PDH_LOG_OPT_MAX_IS_BYTES = 0x04000000, /// PDH_LOG_OPT_APPEND = 0x08000000, } /// Dialog boxes that will be displayed to prompt for the data source. [PInvokeData("pdh.h", MSDNShortId = "211d4504-e1f9-48a0-8ddd-613f2f183c59")] public enum PdhSelectDataSourceFlags { /// /// Display the data source selection dialog box. The dialog box lets the user select performance data from either a log file or /// a real-time source. If the user specified that data is to be collected from a log file, a file browser is displayed for the /// user to specify the name and location of the log file. /// Default, /// /// Display the file browser only. Set this flag when you want to prompt for the name and location of a log file only. /// PDH_FLAGS_FILE_BROWSER_ONLY } /// /// Default detail level to show in the Detail level list if bHideDetailBox is FALSE. If bHideDetailBox is TRUE, the dialog uses this /// value to filter the displayed performance counters and objects. /// [PInvokeData("winperf.h")] public enum PERF_DETAIL { /// A novice user can understand the counter data. PERF_DETAIL_NOVICE = 100, /// The counter data is provided for advanced users. PERF_DETAIL_ADVANCED = 200, /// The counter data is provided for expert users. PERF_DETAIL_EXPERT = 300, /// The counter data is provided for system designers. PERF_DETAIL_WIZARD = 400 } /// Adds the specified counter to the query. /// /// Handle to the query to which you want to add the counter. This handle is returned by the PdhOpenQuery function. /// /// /// Null-terminated string that contains the counter path. For details on the format of a counter path, see Specifying a Counter /// Path. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// /// User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo /// function and access the dwUserData member of the PDH_COUNTER_INFO structure. /// /// /// Handle to the counter that was added to the query. You may need to reference this handle in subsequent calls. /// /// /// Return ERROR_SUCCESS if the function succeeds. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_CSTATUS_BAD_COUNTERNAME /// The counter path could not be parsed or interpreted. /// /// /// PDH_CSTATUS_NO_COUNTER /// Unable to find the specified counter on the computer or in the log file. /// /// /// PDH_CSTATUS_NO_COUNTERNAME /// The counter path is empty. /// /// /// PDH_CSTATUS_NO_MACHINE /// The path did not contain a computer name, and the function was unable to retrieve the local computer name. /// /// /// PDH_CSTATUS_NO_OBJECT /// Unable to find the specified object on the computer or in the log file. /// /// /// PDH_FUNCTION_NOT_FOUND /// Unable to determine the calculation function to use for this counter. /// /// /// PDH_INVALID_ARGUMENT /// One or more arguments are not valid. /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory required to complete the function. /// /// /// /// /// /// If the counter path contains a wildcard character, all counter names matching the wildcard character are added to the query. /// /// /// If a counter instance is specified that does not yet exist, PdhAddCounter does not report an error condition. Instead, it /// returns ERROR_SUCCESS. The reason for this behavior is that it is not known whether a nonexistent counter instance has been /// specified or whether one will exist but has not yet been created. /// /// To remove the counter from the query, use the PdhRemoveCounter function. /// Examples /// For an example, see Browsing Performance Counters or Reading Performance Data from a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhaddcountera PDH_FUNCTION PdhAddCounterA( PDH_HQUERY hQuery, // LPCSTR szFullCounterPath, DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "b8b9a332-ce28-46d4-92e2-91f9f6c24da5")] public static extern Win32Error PdhAddCounter(PDH_HQUERY hQuery, string szFullCounterPath, IntPtr dwUserData, out SafePDH_HCOUNTER phCounter); /// Adds the specified language-neutral counter to the query. /// /// Handle to the query to which you want to add the counter. This handle is returned by the PdhOpenQuery function. /// /// /// Null-terminated string that contains the counter path. For details on the format of a counter path, see Specifying a Counter /// Path. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// /// User-defined value. This value becomes part of the counter information. To retrieve this value later, call the PdhGetCounterInfo /// function and access the dwQueryUserData member of the PDH_COUNTER_INFO structure. /// /// /// Handle to the counter that was added to the query. You may need to reference this handle in subsequent calls. /// /// /// Return ERROR_SUCCESS if the function succeeds. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_CSTATUS_BAD_COUNTERNAME /// The counter path could not be parsed or interpreted. /// /// /// PDH_CSTATUS_NO_COUNTER /// Unable to find the specified counter on the computer or in the log file. /// /// /// PDH_CSTATUS_NO_COUNTERNAME /// The counter path is empty. /// /// /// PDH_CSTATUS_NO_MACHINE /// The path did not contain a computer name and the function was unable to retrieve the local computer name. /// /// /// PDH_CSTATUS_NO_OBJECT /// Unable to find the specified object on the computer or in the log file. /// /// /// PDH_FUNCTION_NOT_FOUND /// Unable to determine the calculation function to use for this counter. /// /// /// PDH_INVALID_ARGUMENT /// One or more arguments are not valid. /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory required to complete the function. /// /// /// /// /// /// This function provides a language-neutral way to add performance counters to the query. In contrast, the counter path that you /// specify in the PdhAddCounter function must be localized. /// /// /// If a counter instance is specified that does not yet exist, PdhAddEnglishCounter does not report an error condition. /// Instead, it returns ERROR_SUCCESS. The reason for this behavior is that it is not known whether a nonexistent counter instance /// has been specified or whether one will exist but has not yet been created. /// /// To remove the counter from the query, use the PdhRemoveCounter function. /// /// Note If the counter path contains a wildcard character, the non-wildcard portions of the path will be localized, but /// wildcards will not be expanded before adding the localized counter path to the query. In this case, you will need use the /// following procedure to add all matching counter names to the query. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhaddenglishcountera PDH_FUNCTION PdhAddEnglishCounterA( PDH_HQUERY // hQuery, LPCSTR szFullCounterPath, DWORD_PTR dwUserData, PDH_HCOUNTER *phCounter ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "6a94b40d-0105-4358-93e1-dae603a35cc4")] public static extern Win32Error PdhAddEnglishCounter(PDH_HQUERY hQuery, string szFullCounterPath, IntPtr dwUserData, out SafePDH_HCOUNTER phCounter); /// Binds one or more binary log files together for reading log data. /// Handle to the bound data sources. /// /// /// One or more binary log files to bind together. The log file names can contain absolute or relative paths. You cannot specify more /// than 32 log files. /// /// If NULL, the source is a real-time data source. /// /// /// Returns ERROR_SUCCESS if the function succeeds. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// /// This function is used with the PDH functions that require a handle to a data source. For a list of these functions, see See Also. /// /// /// You cannot specify more than one comma-delimited (CSV) or tab-delimited (TSV) file. The list can contain only one type of /// file—you cannot combine multiple file types. /// /// To close the bound log files, call the PdhCloseLog function using the log handle. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbindinputdatasourcea PDH_FUNCTION PdhBindInputDataSourceA( // PDH_HLOG *phDataSource, LPCSTR LogFileNameList ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "eaed9b28-eb09-4123-9317-5d3d50e2d77a")] public static extern Win32Error PdhBindInputDataSource(out SafePDH_HLOG phDataSource, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] LogFileNameList); /// Binds one or more binary log files together for reading log data. /// /// /// One or more binary log files to bind together. The log file names can contain absolute or relative paths. You cannot specify more /// than 32 log files. /// /// If NULL, the source is a real-time data source. /// /// Handle to the bound data sources. /// /// /// This function is used with the PDH functions that require a handle to a data source. For a list of these functions, see See Also. /// /// /// You cannot specify more than one comma-delimited (CSV) or tab-delimited (TSV) file. The list can contain only one type of /// file—you cannot combine multiple file types. /// /// [PInvokeData("pdh.h", MSDNShortId = "eaed9b28-eb09-4123-9317-5d3d50e2d77a")] public static SafePDH_HLOG PdhBindInputDataSource(params string[] LogFileNameList) { var err = PdhBindInputDataSource(out var hLog, LogFileNameList is null || LogFileNameList.Length == 0 ? null : LogFileNameList); return err.Succeeded ? hLog : throw err.GetException(); } /// /// /// Displays a Browse Counters dialog box that the user can use to select one or more counters that they want to add to the query. /// /// To use handles to data sources, use the PdhBrowseCountersH function. /// /// A PDH_BROWSE_DLG_CONFIG structure that specifies the behavior of the dialog box. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// /// Note that the dialog box can return PDH_DIALOG_CANCELLED if bSingleCounterPerDialog is FALSE and the user clicks /// the Close button, so your error handling would have to account for this. /// /// For information on using this function, see Browsing Counters. /// Examples /// For an example, see Browsing Performance Counters. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbrowsecountersa PDH_FUNCTION PdhBrowseCountersA( // PPDH_BROWSE_DLG_CONFIG_A pBrowseDlgData ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "4e9e4b20-a573-4f6d-97e8-63bcc675032b")] public static extern Win32Error PdhBrowseCounters(ref PDH_BROWSE_DLG_CONFIG pBrowseDlgData); /// /// /// Displays a Browse Counters dialog box that the user can use to select one or more counters that they want to add to the query. /// /// This function is identical to the PdhBrowseCounters function, except that it supports the use of handles to data sources. /// /// A PDH_BROWSE_DLG_CONFIG_H structure that specifies the behavior of the dialog box. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// Note that the dialog box can return PDH_DIALOG_CANCELLED if bSingleCounterPerDialog is FALSE and the user clicks /// the Close button, so your error handling would have to account for this. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhbrowsecountersha PDH_FUNCTION PdhBrowseCountersHA( // PPDH_BROWSE_DLG_CONFIG_HA pBrowseDlgData ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "ab835bf8-1adc-463f-99c3-654a328af98a")] public static extern Win32Error PdhBrowseCountersH(in PDH_BROWSE_DLG_CONFIG_H pBrowseDlgData); /// Calculates the displayable value of two raw counter values. /// /// Handle to the counter to calculate. The function uses information from the counter to determine how to calculate the value. This /// handle is returned by the PdhAddCounter function. /// /// /// Determines the data type of the calculated value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return the calculated value as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return the calculated value as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return the calculated value as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's scaling factor in the calculation. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the final value by 1,000. /// /// /// /// /// Raw counter value used to compute the displayable counter value. For details, see the PDH_RAW_COUNTER structure. /// /// /// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters (for example, /// rate counters) require two raw values to calculate a displayable value. If the counter type does not require a second value, set /// this parameter to NULL. This value must be the older of the two raw values. /// /// A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// An argument is not correct or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// To retrieve the current raw counter value from the query, call the PdhGetRawCounterValue function. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcalculatecounterfromrawvalue PDH_FUNCTION // PdhCalculateCounterFromRawValue( PDH_HCOUNTER hCounter, DWORD dwFormat, PPDH_RAW_COUNTER rawValue1, PPDH_RAW_COUNTER rawValue2, // PPDH_FMT_COUNTERVALUE fmtValue ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")] public static extern Win32Error PdhCalculateCounterFromRawValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, in PDH_RAW_COUNTER rawValue1, in PDH_RAW_COUNTER rawValue2, out PDH_FMT_COUNTERVALUE fmtValue); /// Calculates the displayable value of two raw counter values. /// /// Handle to the counter to calculate. The function uses information from the counter to determine how to calculate the value. This /// handle is returned by the PdhAddCounter function. /// /// /// Determines the data type of the calculated value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return the calculated value as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return the calculated value as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return the calculated value as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's scaling factor in the calculation. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the final value by 1,000. /// /// /// /// /// Raw counter value used to compute the displayable counter value. For details, see the PDH_RAW_COUNTER structure. /// /// /// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters (for example, /// rate counters) require two raw values to calculate a displayable value. If the counter type does not require a second value, set /// this parameter to NULL. This value must be the older of the two raw values. /// /// A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// An argument is not correct or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// To retrieve the current raw counter value from the query, call the PdhGetRawCounterValue function. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcalculatecounterfromrawvalue PDH_FUNCTION // PdhCalculateCounterFromRawValue( PDH_HCOUNTER hCounter, DWORD dwFormat, PPDH_RAW_COUNTER rawValue1, PPDH_RAW_COUNTER rawValue2, // PPDH_FMT_COUNTERVALUE fmtValue ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "fd50b1fd-29b7-49a8-bbcc-4d7f0cbd7079")] public static extern Win32Error PdhCalculateCounterFromRawValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, in PDH_RAW_COUNTER rawValue1, [Optional] IntPtr rawValue2, out PDH_FMT_COUNTERVALUE fmtValue); /// Closes the specified log file. /// Handle to the log file to be closed. This handle is returned by the PdhOpenLog function. /// /// You can specify the following flag. /// /// /// Value /// Meaning /// /// /// PDH_FLAGS_CLOSE_QUERY /// Closes the query associated with the specified log file handle. See the hQuery parameter of PdhOpenLog. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS and closes and deletes the query. /// If the function fails, the return value is a system error code or a PDH error code. The following is a possible value. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The log file handle is not valid. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcloselog PDH_FUNCTION PdhCloseLog( PDH_HLOG hLog, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "74039bdf-d1b5-41ba-aa4e-4779ce0dd02a")] public static extern Win32Error PdhCloseLog(PDH_HLOG hLog, uint dwFlags); /// /// Closes all counters contained in the specified query, closes all handles related to the query, and frees all memory associated /// with the query. /// /// Handle to the query to close. This handle is returned by the PdhOpenQuery function. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code. /// /// The following is a possible value. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// /// /// Do not use the counter handles associated with this query after calling this function. /// The following shows the syntax if calling this function from Visual Basic. /// Examples /// For an example, see Browsing Performance Counters or Reading Performance Data from a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhclosequery PDH_FUNCTION PdhCloseQuery( PDH_HQUERY hQuery ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "af0fb9f4-3999-48fa-88d7-aa59b5caed75")] public static extern Win32Error PdhCloseQuery(PDH_HQUERY hQuery); /// /// Collects the current raw data value for all counters in the specified query and updates the status code of each counter. /// /// Handle of the query for which you want to collect data. The PdhOpenQuery function returns this handle. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code. /// /// The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_NO_DATA /// /// The query does not currently contain any counters. The query may not contain data because the user is not running with an /// elevated token (see Limited User Access Support). /// /// /// /// /// /// /// Call this function when you want to collect counter data for the counters in the query. PDH stores the raw counter values for the /// current and previous collection. /// /// /// If you want to retrieve the current raw counter value, call the PdhGetRawCounterValue function. If you want to compute a /// displayable value for the counter value, call the PdhGetFormattedCounterValue function. If the counter path contains a wildcard /// for the instance name, instead call the PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively. /// /// /// When PdhCollectQueryData is called for data from one counter instance only and the counter instance does not exist, the /// function returns PDH_NO_DATA. However, if data from more than one counter is queried, PdhCollectQueryData may return /// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter /// instance does not exist, or if it will exist but has not yet been created. In this case, call PdhGetRawCounterValue or /// PdhGetFormattedCounterValue for each of the counter instances of interest to determine whether they exist. /// /// The following shows the syntax if calling this function from Visual Basic. /// Examples /// For an example, see Browsing Performance Counters or Reading Performance Data from a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydata PDH_FUNCTION PdhCollectQueryData( PDH_HQUERY // hQuery ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "1d83325b-8deb-4731-9df4-6201da292cdc")] public static extern Win32Error PdhCollectQueryData(PDH_HQUERY hQuery); /// /// Uses a separate thread to collect the current raw data value for all counters in the specified query. The function then signals /// the application-defined event and waits the specified time interval before returning. /// /// /// Handle of the query. The query identifies the counters that you want to collect. The PdhOpenQuery function returns this handle. /// /// Time interval to wait, in seconds. /// /// Handle to the event that you want PDH to signal after the time interval expires. To create an event object, call the CreateEvent function. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_NO_DATA /// The query does not currently have any counters. /// /// /// /// /// /// PDH terminates the thread when you call the PdhCloseQuery function. If you call PdhCollectQueryDataEx more than once, each /// subsequent call terminates the thread from the previous call and then starts a new thread. /// /// /// When PdhCollectQueryDataEx is called for data from one counter instance only and the counter instance does not exist, the /// function returns PDH_NO_DATA. However, if data from more than one counter is queried, PdhCollectQueryDataEx may return /// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter /// instance does not exist, or if it will exist but has not yet been created. In this case, call PdhGetRawCounterValue or /// PdhGetFormattedCounterValue for each of the counter instances of interest to determine whether they exist. /// /// /// PDH stores the raw counter values for the current and previous collection. If you want to retrieve the current raw counter value, /// call the PdhGetRawCounterValue function. If you want to compute a displayable value for the counter value, call the /// PdhGetFormattedCounterValue. If the counter path contains a wildcard for the instance name, instead call the /// PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively. /// /// Examples /// The following example shows how to use this function. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydataex PDH_FUNCTION PdhCollectQueryDataEx( PDH_HQUERY // hQuery, DWORD dwIntervalTime, HANDLE hNewDataEvent ); [DllImport(Lib.Pdh, SetLastError = true, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "3fa1d193-03d0-44d8-a32b-b7754594d0ca")] public static extern Win32Error PdhCollectQueryDataEx(PDH_HQUERY hQuery, uint dwIntervalTime, SafeEventHandle hNewDataEvent); /// /// Collects the current raw data value for all counters in the specified query and updates the status code of each counter. /// /// Handle of the query for which you want to collect data. The PdhOpenQuery function returns this handle. /// Time stamp when the first counter value in the query was retrieved. The time is specified as FILETIME. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. Otherwise, the function returns a system error code or a PDH error code. /// /// The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_NO_DATA /// The query does not currently have any counters. /// /// /// /// /// /// Call this function when you want to collect counter data for the counters in the query. PDH stores the raw counter values for the /// current and previous collection. /// /// /// If you want to retrieve the current raw counter value, call the PdhGetRawCounterValue function. If you want to compute a /// displayable value for the counter value, call the PdhGetFormattedCounterValue. If the counter path contains a wildcard for the /// instance name, instead call the PdhGetRawCounterArray and PdhGetFormattedCounterArray functions, respectively. /// /// /// When PdhCollectQueryDataEx is called for data from one counter instance only, and the counter instance does not exist, the /// function returns PDH_NO_DATA. However, if data from more than one counter is queried, PdhCollectQueryDataEx may return /// ERROR_SUCCESS even if one of the counter instances does not yet exist. This is because it is not known if the specified counter /// instance does not exist, or if it will exist but has not yet been created. In this case, call the PdhGetRawCounterValue or /// PdhGetFormattedCounterValue function for each of the counter instances of interest to determine whether they exist. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcollectquerydatawithtime PDH_FUNCTION // PdhCollectQueryDataWithTime( PDH_HQUERY hQuery, LONGLONG *pllTimeStamp ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "2c47c690-0748-4ed4-a138-894d45c72581")] public static extern Win32Error PdhCollectQueryDataWithTime(PDH_HQUERY hQuery, out FILETIME pllTimeStamp); /// Computes statistics for a counter from an array of raw values. /// /// Handle of the counter for which you want to compute statistics. The PdhAddCounter function returns this handle. /// /// /// Determines the data type of the formatted value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return the calculated value as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return the calculated value as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return the calculated value as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's scaling factors in the calculation. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the final value by 1,000. /// /// /// /// /// Zero-based index of the first raw counter value to use to begin the calculations. The index value must point to the oldest entry /// in the buffer. The function starts at this entry and scans through the buffer, wrapping at the last entry back to the beginning /// of the buffer and up to the dwFirstEntry-1 entry, which is assumed to be the newest or most recent data. /// /// Number of raw counter values in the lpRawValueArray buffer. /// Array of PDH_RAW_COUNTER structures that contain dwNumEntries entries. /// A PDH_STATISTICS structure that receives the counter statistics. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// An argument is not correct or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhcomputecounterstatistics PDH_FUNCTION // PdhComputeCounterStatistics( PDH_HCOUNTER hCounter, DWORD dwFormat, DWORD dwFirstEntry, DWORD dwNumEntries, PPDH_RAW_COUNTER // lpRawValueArray, PPDH_STATISTICS data ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "a986ae6c-88ee-4a03-9077-3d286157b9d1")] public static extern Win32Error PdhComputeCounterStatistics(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, uint dwFirstEntry, uint dwNumEntries, [In] PDH_RAW_COUNTER[] lpRawValueArray, out PDH_STATISTICS data); /// Connects to the specified computer. /// /// Null-terminated string that specifies the name of the computer to connect to. If NULL, PDH connects to the local computer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_CSTATUS_NO_MACHINE /// /// Unable to connect to the specified computer. Could be caused by the computer not being on, not supporting PDH, not being /// connected to the network, or having the permissions set on the registry that prevent remote connections or remote performance /// monitoring by the user. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// /// Unable to allocate a dynamic memory block. Occurs when there is a serious memory shortage in the system due to too many /// applications running on the system or an insufficient memory paging file. /// /// /// /// /// /// /// Typically, applications do not call this function and instead the connection is made when the application adds the counter to the query. /// /// /// However, you can use this function if you want to include more than the local computer in the Select counters from /// computer list on the Browse Counters dialog box. For details, see the PDH_BROWSE_DLG_CONFIG structure. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhconnectmachinea PDH_FUNCTION PdhConnectMachineA( LPCSTR // szMachineName ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "8f8b4651-b550-4b34-bb2f-d2497c56b572")] public static extern Win32Error PdhConnectMachine([Optional] string szMachineName); /// Enumerates the names of the log sets within the DSN. /// Null-terminated string that specifies the DSN. /// /// Caller-allocated buffer that receives the list of null-terminated log set names. The list is terminated with a /// null-terminator character. Set to NULL if the pcchBufferLength parameter is zero. /// /// /// Size of the mszLogSetNameList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The size of the mszLogSetNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength /// is zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszLogSetNameList to NULL and /// pcchBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumlogsetnamesa PDH_FUNCTION PdhEnumLogSetNamesA( LPCSTR // szDataSource, PZZSTR mszDataSetNameList, LPDWORD pcchBufferLength ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "c74cc8a6-915b-40ed-a88b-bc2147215d52")] public static extern Win32Error PdhEnumLogSetNames(string szDataSource, IntPtr mszDataSetNameList, ref uint pcchBufferLength); /// /// /// Returns a list of the computer names associated with counters in a log file. The computer names were either specified when adding /// counters to the query or when calling the PdhConnectMachine function. The computers listed include those that are currently /// connected and online, in addition to those that are offline or not returning performance data. /// /// To use handles to data sources, use the PdhEnumMachinesH function. /// /// /// Null-terminated string that specifies the name of a log file. The function enumerates the names of the computers whose /// counter data is in the log file. If NULL, the function enumerates the list of computers that were specified when adding /// counters to a real time query or when calling the PdhConnectMachine function. /// /// /// Caller-allocated buffer to receive the list of null-terminated strings that contain the computer names. The list is /// terminated with two null-terminator characters. Set to NULL if pcchBufferLength is zero. /// /// /// Size of the mszMachineNameList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszMachineNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszMachineNameList to NULL and /// pcchBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenummachinesa PDH_FUNCTION PdhEnumMachinesA( LPCSTR szDataSource, // PZZSTR mszMachineList, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "77584d3b-3ba5-4288-b730-be2458f4fc1c")] public static extern Win32Error PdhEnumMachines([Optional] string szDataSource, IntPtr mszMachineList, ref uint pcchBufferSize); /// /// /// Returns a list of the computer names associated with counters in a log file. The computer names were either specified when adding /// counters to the query or when calling the PdhConnectMachine function. The computers listed include those that are currently /// connected and online, in addition to those that are offline or not returning performance data. /// /// This function is identical to the PdhEnumMachines function, except that it supports the use of handles to data sources. /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// Caller-allocated buffer to receive the list of null-terminated strings that contain the computer names. The list is /// terminated with two null-terminator characters. Set to NULL if pcchBufferLength is zero. /// /// /// Size of the mszMachineNameList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszMachineNameList buffer is too small to contain all the data. This return value is expected if pcchBufferLength is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszMachineNameList to NULL and /// pcchBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenummachinesha PDH_FUNCTION PdhEnumMachinesHA( PDH_HLOG // hDataSource, PZZSTR mszMachineList, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "7e8dc113-76a7-4a7a-bbad-1a4387831501")] public static extern Win32Error PdhEnumMachinesH([Optional] PDH_HLOG hDataSource, IntPtr mszMachineList, ref uint pcchBufferSize); /// /// /// Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file. /// /// To use handles to data sources, use the PdhEnumObjectItemsH function. /// /// /// /// Null-terminated string that specifies the name of the log file used to enumerate the counter and instance names. If /// NULL, the function uses the computer specified in /// /// the szMachineName parameter to enumerate the names. /// /// /// /// Null-terminated string that specifies the name of the computer that contains the counter and instance names that you want /// to enumerate. /// /// Include the leading slashes in the computer name, for example, \computername. /// If the szDataSource parameter is NULL, you can set szMachineName to NULL to specify the local computer. /// /// /// Null-terminated string that specifies the name of the object whose counter and instance names you want to enumerate. /// /// /// Caller-allocated buffer that receives a list of null-terminated counter names provided by the specified object. The list /// contains unique counter names. The list is terminated by two NULL characters. Set to NULL if the /// pcchCounterListLengthparameter is zero. /// /// /// Size of the mszCounterList buffer, in TCHARs. If zero on input and the object exists, the function returns PDH_MORE_DATA /// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this /// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the /// required size, you should not rely on the returned size to reallocate the buffer. /// /// /// Caller-allocated buffer that receives a list of null-terminated instance names provided by the specified object. The list /// contains unique instance names. The list is terminated by two NULL characters. Set to NULL if /// pcchInstanceListLength is zero. /// /// /// /// Size of the mszInstanceList buffer, in TCHARs. If zero on input and the object exists, the function returns PDH_MORE_DATA /// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this /// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the /// required size, you should not rely on the returned size to reallocate the buffer. /// /// /// If the specified object does not support variable instances, then the returned value will be zero. If the specified object does /// support variable instances, but does not currently have any instances, then the value returned is 2, which is the size of an /// empty MULTI_SZ list string. /// /// /// /// /// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the /// levels are listed in increasing order). This parameter can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// PERF_DETAIL_NOVICE /// Novice user level of detail. /// /// /// PERF_DETAIL_ADVANCED /// Advanced user level of detail. /// /// /// PERF_DETAIL_EXPERT /// Expert user level of detail. /// /// /// PERF_DETAIL_WIZARD /// System designer level of detail. /// /// /// /// This parameter must be zero. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// One of the buffers is too small to contain the list of names. This return value is expected if pcchCounterListLength or /// pcchInstanceListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory to support this function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found on the specified computer or in the specified log file. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set the buffers to NULL and the sizes /// to 0), and the second time to get the data. /// /// /// Consecutive calls to this function will return identical lists of counters and instances, because PdhEnumObjectItems will /// always query the list of performance objects defined by the last call to PdhEnumObjects or PdhEnumObjectItems. To refresh /// the list of performance objects, call PdhEnumObjects with a bRefresh flag value of TRUE before calling /// PdhEnumObjectItems again. /// /// The order of the instance and counter names is undetermined. /// Examples /// For an example, see Enumerating Process Objects. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectitemsa PDH_FUNCTION PdhEnumObjectItemsA( LPCSTR // szDataSource, LPCSTR szMachineName, LPCSTR szObjectName, PZZSTR mszCounterList, LPDWORD pcchCounterListLength, PZZSTR // mszInstanceList, LPDWORD pcchInstanceListLength, DWORD dwDetailLevel, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "b3efdd31-44e6-47ff-bd0e-d31451c32818")] public static extern Win32Error PdhEnumObjectItems([Optional] string szDataSource, [Optional] string szMachineName, string szObjectName, [Optional] IntPtr mszCounterList, ref uint pcchCounterListLength, [Optional] IntPtr mszInstanceList, ref uint pcchInstanceListLength, PERF_DETAIL dwDetailLevel, uint dwFlags = 0); /// /// /// Returns the specified object's counter and instance names that exist on the specified computer or in the specified log file. /// /// This function is identical to the PdhEnumObjectItems function, except that it supports the use of handles to data sources. /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// /// Null-terminated string that specifies the name of the computer that contains the counter and instance names that you want /// to enumerate. /// /// Include the leading slashes in the computer name, for example, \computername. /// If the szDataSource parameter is NULL, you can set szMachineName to NULL to specify the local computer. /// /// /// Null-terminated string that specifies the name of the object whose counter and instance names you want to enumerate. /// /// /// Caller-allocated buffer that receives a list of null-terminated counter names provided by the specified object. The list /// contains unique counter names. The list is terminated by two NULL characters. Set to NULL if the /// pcchCounterListLength parameter is zero. /// /// /// Size of the mszCounterList buffer, in TCHARs. If zero on input and the object exists, the function returns PDH_MORE_DATA /// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this /// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the /// required size, you should not rely on the returned size to reallocate the buffer. /// /// /// Caller-allocated buffer that receives a list of null-terminated instance names provided by the specified object. The list /// contains unique instance names. The list is terminated by two NULL characters. Set to NULL if the /// pcchInstanceListLength parameter is zero. /// /// /// /// Size of the mszInstanceList buffer, in TCHARs. If zero on input and the object exists, the function returns PDH_MORE_DATA /// and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function sets this /// parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less than the /// required size, you should not rely on the returned size to reallocate the buffer. /// /// /// If the specified object does not support variable instances, then the returned value will be zero. If the specified object does /// support variable instances, but does not currently have any instances, then the value returned is 2, which is the size of an /// empty MULTI_SZ list string. /// /// /// /// /// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the /// levels are listed in increasing order). This parameter can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// PERF_DETAIL_NOVICE /// Novice user level of detail. /// /// /// PERF_DETAIL_ADVANCED /// Advanced user level of detail. /// /// /// PERF_DETAIL_EXPERT /// Expert user level of detail. /// /// /// PERF_DETAIL_WIZARD /// System designer level of detail. /// /// /// /// This parameter must be zero. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// One of the buffers is too small to contain the list of names. This return value is expected if pcchCounterListLength or /// pcchInstanceListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory to support this function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found on the specified computer or in the specified log file. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set the buffers to NULL and the sizes /// to 0), and the second time to get the data. /// /// /// Consecutive calls to this function will return identical lists of counters and instances, because PdhEnumObjectItemsH will /// always query the list of performance objects defined by the last call to PdhEnumObjectsH or PdhEnumObjectItemsH. To /// refresh the list of performance objects, call PdhEnumObjectsH with a bRefresh flag value of TRUE before calling /// PdhEnumObjectItemsH again. /// /// The order of the instance and counter names is undetermined. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectitemsha PDH_FUNCTION PdhEnumObjectItemsHA( PDH_HLOG // hDataSource, LPCSTR szMachineName, LPCSTR szObjectName, PZZSTR mszCounterList, LPDWORD pcchCounterListLength, PZZSTR // mszInstanceList, LPDWORD pcchInstanceListLength, DWORD dwDetailLevel, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "2cea7d0a-cea2-4fee-a087-37663de254e9")] public static extern Win32Error PdhEnumObjectItemsH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, string szObjectName, [Optional] IntPtr mszCounterList, ref uint pcchCounterListLength, [Optional] IntPtr mszInstanceList, ref uint pcchInstanceListLength, PERF_DETAIL dwDetailLevel, uint dwFlags = 0); /// /// Returns a list of objects available on the specified computer or in the specified log file. /// To use handles to data sources, use the PdhEnumObjectsH function. /// /// /// /// Null-terminated string that specifies the name of the log file used to enumerate the performance objects. If NULL, /// the function uses the computer specified in /// /// the szMachineName parameter to enumerate the names. /// /// /// Null-terminated string that specifies the name of the computer used to enumerate the performance objects. /// Include the leading slashes in the computer name, for example, \computername. /// If the szDataSource parameter is NULL, you can set szMachineName to NULL to specify the local computer. /// /// /// Caller-allocated buffer that receives the list of object names. Each object name in this list is terminated by a null /// character. The list is terminated with two null-terminator characters. Set to NULL if the pcchBufferLength /// parameter is zero. /// /// /// /// Size of the mszObjectList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// Windows XP: Add one to the required buffer size. /// /// /// /// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the /// levels are listed in increasing order). This parameter can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// PERF_DETAIL_NOVICE /// Novice user level of detail. /// /// /// PERF_DETAIL_ADVANCED /// Advanced user level of detail. /// /// /// PERF_DETAIL_EXPERT /// Expert user level of detail. /// /// /// PERF_DETAIL_WIZARD /// System designer level of detail. /// /// /// /// /// Indicates if the cached object list should be automatically refreshed. Specify one of the following values. /// /// If you call this function twice, once to get the size of the list and a second time to get the actual list, set this parameter to /// TRUE on the first call and FALSE on the second call. If both calls are TRUE, the second call may also return /// PDH_MORE_DATA because the object data may have changed between calls. /// /// /// /// Value /// Meaning /// /// /// TRUE /// The object cache is automatically refreshed before the objects are returned. /// /// /// FALSE /// Do not automatically refresh the cache. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszObjectList buffer is too small to hold the list of objects. This return value is expected if pcchBufferLength is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found. /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszObjectList to NULL and /// pcchBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectsa PDH_FUNCTION PdhEnumObjectsA( LPCSTR szDataSource, // LPCSTR szMachineName, PZZSTR mszObjectList, LPDWORD pcchBufferSize, DWORD dwDetailLevel, BOOL bRefresh ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "dfa4b10f-5134-4620-a6b0-0fa2c13a33ec")] public static extern Win32Error PdhEnumObjects([Optional] string szDataSource, [Optional] string szMachineName, [Optional] IntPtr mszObjectList, ref uint pcchBufferSize, PERF_DETAIL dwDetailLevel, [MarshalAs(UnmanagedType.Bool)] bool bRefresh); /// /// Returns a list of objects available on the specified computer or in the specified log file. /// This function is identical to PdhEnumObjects, except that it supports the use of handles to data sources. /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// Null-terminated string that specifies the name of the computer used to enumerate the performance objects. /// Include the leading slashes in the computer name, for example, \computername. /// If szDataSource is NULL, you can set szMachineName to NULL to specify the local computer. /// /// /// Caller-allocated buffer that receives the list of object names. Each object name in this list is terminated by a null /// character. The list is terminated with two null-terminator characters. Set to NULL if pcchBufferLength is zero. /// /// /// /// Size of the mszObjectList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// Windows XP: Add one to the required buffer size. /// /// /// /// Detail level of the performance items to return. All items that are of the specified detail level or less will be returned (the /// levels are listed in increasing order). This parameter can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// PERF_DETAIL_NOVICE /// Novice user level of detail. /// /// /// PERF_DETAIL_ADVANCED /// Advanced user level of detail. /// /// /// PERF_DETAIL_EXPERT /// Expert user level of detail. /// /// /// PERF_DETAIL_WIZARD /// System designer level of detail. /// /// /// /// /// Indicates if the cached object list should be automatically refreshed. Specify one of the following values. /// /// If you call this function twice, once to get the size of the list and a second time to get the actual list, set this parameter to /// TRUE on the first call and FALSE on the second call. If both calls are TRUE, the second call may also return /// PDH_MORE_DATA because the object data may have changed between calls. /// /// /// /// Value /// Meaning /// /// /// TRUE /// The object cache is automatically refreshed before the objects are returned. /// /// /// FALSE /// Do not automatically refresh the cache. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszObjectList buffer is too small to hold the list of objects. This return value is expected if pcchBufferLength is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found. /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszObjectList to NULL and /// pcchBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhenumobjectsha PDH_FUNCTION PdhEnumObjectsHA( PDH_HLOG // hDataSource, LPCSTR szMachineName, PZZSTR mszObjectList, LPDWORD pcchBufferSize, DWORD dwDetailLevel, BOOL bRefresh ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "8f68a7a8-cc56-4f7f-a86f-4b439738808d")] public static extern Win32Error PdhEnumObjectsH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, [Optional] IntPtr mszObjectList, ref uint pcchBufferSize, PERF_DETAIL dwDetailLevel, [MarshalAs(UnmanagedType.Bool)] bool bRefresh); /// /// /// Examines the specified computer (or local computer if none is specified) for counters and instances of counters that match the /// wildcard strings in the counter path. /// /// Note This function is superseded by the PdhExpandWildCardPath function. /// /// /// Null-terminated string that contains the counter path to expand. The function searches the computer specified in the path /// for matches. If the path does not specify a computer, the function searches the local computer. The maximum length of a counter /// path is PDH_MAX_COUNTER_PATH. /// /// /// Caller-allocated buffer that receives the list of expanded counter paths that match the wildcard specification in szWildCardPath. /// Each counter path in this list is terminated by a null character. The list is terminated with two NULL characters. /// Set to NULL if pcchPathListLength is zero. /// /// /// /// Size of the mszExpandedPathList buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// Note You must add one to the required size on Windows XP. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszExpandedPathList buffer is too small to contain the list of paths. This return value is expected if pcchPathListLength is /// zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory to support this function. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to NULL and /// pcchPathListLength to 0), and the second time to get the data. /// /// The general counter path format is as follows: /// \computer\object(parent/instance#index)\counter /// /// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character. /// The computer, parent, instance, and index components are not necessary for all counters. /// /// /// The counter paths that you must use is determined by the counter itself. For example, the LogicalDisk object has an instance /// index, so you must provide the #index, or a wildcard. Therefore, you could use the following format: /// /// \LogicalDisk(/#*)* /// In comparison, the Process object does not require an instance index. Therefore, you could use the following format: /// \Process(*)\ID Process /// The following is a list of the possible formats: /// /// /// \\computer\object(parent/instance#index)\counter /// /// /// \\computer\object(parent/instance)\counter /// /// /// \\computer\object(instance#index)\counter /// /// /// \\computer\object(instance)\counter /// /// /// \\computer\object\counter /// /// /// \object(parent/instance#index)\counter /// /// /// \object(parent/instance)\counter /// /// /// \object(instance#index)\counter /// /// /// \object(instance)\counter /// /// /// \object\counter /// /// /// /// If a wildcard character is specified in the parent name, all instances of the specified object that match the specified instance /// and counter fields will be returned. /// /// /// If a wildcard character is specified in the instance name, all instances of the specified object and parent object will be /// returned if all instance names corresponding to the specified index match the wildcard character. /// /// If a wildcard character is specified in the counter name, all counters of the specified object are returned. /// Partial counter path string matches (for example, "pro*") are not supported. /// Examples /// The following example demonstrates how to this function. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandcounterpatha PDH_FUNCTION PdhExpandCounterPathA( LPCSTR // szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "d90954ab-ec2f-42fd-90b7-66f59f3d1115")] public static extern Win32Error PdhExpandCounterPath(string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength); /// /// /// Examines the specified computer or log file and returns those counter paths that match the given counter path which contains /// wildcard characters. /// /// To use handles to data sources, use the PdhExpandWildCardPathH function. /// /// /// /// Null-terminated string that contains the name of a log file. The function uses the performance objects and counters /// defined in the log file to expand the path specified in the szWildCardPath parameter. /// /// If NULL, the function searches the computer specified in szWildCardPath. /// /// /// Null-terminated string that specifies the counter path to expand. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// If the szDataSource parameter is NULL, the function searches the computer specified in the path for matches. If the path /// does not specify a computer, the function searches the local computer. /// /// /// /// Caller-allocated buffer that receives a list of null-terminated counter paths that match the wildcard specification in the /// szWildCardPath. The list is terminated by two NULL characters. Set to NULL if pcchPathListLength is zero. /// /// /// /// Size of the mszExpandedPathList buffer, in TCHARs. If zero on input and the object exists, the function returns /// PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function /// sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less /// than the required size, you should not rely on the returned size to reallocate the buffer. /// /// Note You must add one to the required size on Windows XP. /// /// /// Flags that indicate which wildcard characters not to expand. You can specify one or more flags. /// /// /// Value /// Meaning /// /// /// PDH_NOEXPANDCOUNTERS /// Do not expand the counter name if the path contains a wildcard character for counter name. /// /// /// PDH_NOEXPANDINSTANCES /// /// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index. /// /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszExpandedPathList buffer is not large enough to contain the list of paths. This return value is expected if /// pcchPathListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_INVALID_PATH /// The specified object does not contain an instance. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory to support this function. /// /// /// PDH_CSTATUS_NO_OBJECT /// Unable to find the specified object on the computer or in the log file. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to NULL and /// pcchPathListLength to 0), and the second time to get the data. /// /// PdhExpandWildCardPath differs from PdhExpandCounterPath in the following ways: /// /// /// Lets you control which wildcard characters are expanded. /// /// /// The contents of a log file can be used as the source of counter names. /// /// /// The general counter path format is as follows: /// \computer\object(parent/instance#index)\counter /// /// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character. /// The computer, parent, instance, and index components are not necessary for all counters. /// /// The following is a list of the possible formats: /// /// /// \\computer\object(parent/instance#index)\counter /// /// /// \\computer\object(parent/instance)\counter /// /// /// \\computer\object(instance#index)\counter /// /// /// \\computer\object(instance)\counter /// /// /// \\computer\object\counter /// /// /// \object(parent/instance#index)\counter /// /// /// \object(parent/instance)\counter /// /// /// \object(instance#index)\counter /// /// /// \object(instance)\counter /// /// /// \object\counter /// /// /// Use an asterisk (*) as the wildcard character, for example, \object(*)\counter. /// /// If a wildcard character is specified in the parent name, all instances of the specified object that match the specified instance /// and counter fields will be returned. For example, \object(*/instance)\counter. /// /// /// If a wildcard character is specified in the instance name, all instances of the specified object and parent object will be /// returned if all instance names corresponding to the specified index match the wildcard character. For example, /// \object(parent/*)\counter. If the object does not contain an instance, an error occurs. /// /// If a wildcard character is specified in the counter name, all counters of the specified object are returned. /// Partial counter path string matches (for example, "pro*") are supported. /// Prior to Windows Vista: Partial wildcard matches are not supprted. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandwildcardpatha PDH_FUNCTION PdhExpandWildCardPathA( LPCSTR // szDataSource, LPCSTR szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "415da310-de56-4d58-8959-231426867526")] public static extern Win32Error PdhExpandWildCardPath([Optional] string szDataSource, string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength, PdhExpandFlags dwFlags); /// /// /// Examines the specified computer or log file and returns those counter paths that match the given counter path which contains /// wildcard characters. /// /// This function is identical to the PdhExpandWildCardPath function, except that it supports the use of handles to data sources. /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// Null-terminated string that specifies the counter path to expand. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// If hDataSource is a real time data source, the function searches the computer specified in the path for matches. If the path does /// not specify a computer, the function searches the local computer. /// /// /// /// Caller-allocated buffer that receives a list of null-terminated counter paths that match the wildcard specification in the /// szWildCardPath. The list is terminated by two NULL characters. Set to NULL if pcchPathListLength is zero. /// /// /// /// Size of the mszExpandedPathList buffer, in TCHARs. If zero on input and the object exists, the function returns /// PDH_MORE_DATA and sets this parameter to the required buffer size. If the buffer is larger than the required size, the function /// sets this parameter to the actual size of the buffer that was used. If the specified size on input is greater than zero but less /// than the required size, you should not rely on the returned size to reallocate the buffer. /// /// Note You must add one to the required size on Windows XP. /// /// /// Flags that indicate which wildcard characters not to expand. You can specify one or more flags. /// /// /// Value /// Meaning /// /// /// PDH_NOEXPANDCOUNTERS /// Do not expand the counter name if the path contains a wildcard character for counter name. /// /// /// PDH_NOEXPANDINSTANCES /// /// Do not expand the instance name if the path contains a wildcard character for parent instance, instance name, or instance index. /// /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The mszExpandedPathList buffer is not large enough to contain the list of paths. This return value is expected if /// pcchPathListLength is zero on input. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory to support this function. /// /// /// PDH_CSTATUS_NO_OBJECT /// Unable to find the specified object on the computer or in the log file. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set mszExpandedPathList to NULL and /// pcchPathListLength to 0), and the second time to get the data. /// /// PdhExpandWildCardPathH differs from PdhExpandCounterPath in the following ways: /// /// /// Lets you control which wildcard characters are expanded. /// /// /// The contents of a log file can be used as the source of counter names. /// /// /// The general counter path format is as follows: /// \computer\object(parent/instance#index)\counter /// /// The parent, instance, index, and counter components of the counter path may contain either a valid name or a wildcard character. /// The computer, parent, instance, and index components are not necessary for all counters. /// /// The following is a list of the possible formats: /// /// /// \\computer\object(parent/instance#index)\counter /// /// /// \\computer\object(parent/instance)\counter /// /// /// \\computer\object(instance#index)\counter /// /// /// \\computer\object(instance)\counter /// /// /// \\computer\object\counter /// /// /// \object(parent/instance#index)\counter /// /// /// \object(parent/instance)\counter /// /// /// \object(instance#index)\counter /// /// /// \object(instance)\counter /// /// /// \object\counter /// /// /// Use an asterisk (*) as the wildcard character, for example, \object(*)\counter. /// /// If a wildcard character is specified in the parent name, all instances of the specified object that match the specified instance /// and counter fields will be returned. For example, \object(*/instance)\counter. /// /// /// If a wildcard character is specified in the instance name, all instances of the specified object and parent object will be /// returned if all instance names corresponding to the specified index match the wildcard character. For example, \object(parent/*)\counter. /// /// If a wildcard character is specified in the counter name, all counters of the specified object are returned. /// Partial counter path string matches (for example, "pro*") are supported. /// Prior to Windows Vista: Partial wildcard matches are not supprted. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhexpandwildcardpathha PDH_FUNCTION PdhExpandWildCardPathHA( // PDH_HLOG hDataSource, LPCSTR szWildCardPath, PZZSTR mszExpandedPathList, LPDWORD pcchPathListLength, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "d7d13beb-02ab-4204-808e-d395197f09e1")] public static extern Win32Error PdhExpandWildCardPathH([Optional] PDH_HLOG hDataSource, string szWildCardPath, [Optional] IntPtr mszExpandedPathList, ref uint pcchPathListLength, PdhExpandFlags dwFlags); /// Computes a displayable value for the given raw counter values. /// /// /// Type of counter. Typically, you call PdhGetCounterInfo to retrieve the counter type at the time you call PdhGetRawCounterValue to /// retrieve the raw counter value. /// /// /// For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. (The constant values are /// defined in Winperf.h.) /// /// Note that you cannot specify base types, for example, PERF_LARGE_RAW_BASE. /// /// /// Determines the data type of the calculated value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return the calculated value as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return the calculated value as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return the calculated value as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's scaling factor in the calculation. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the final value by 1,000. /// /// /// /// /// Pointer to the time base, if necessary for the format conversion. If time base information is not necessary for the format /// conversion, the value of this parameter is ignored. To retrieve the time base of the counter, call PdhGetCounterTimeBase. /// /// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. /// /// Raw counter value used to compute the displayable counter value. For details, see PDH_RAW_COUNTER. Some counters, for example, /// rate counters, require two raw values to calculate a displayable value. If the counter type does not require a second value, set /// this parameter to NULL. This value must be the older of the two raw values. /// /// A PDH_FMT_COUNTERVALUE structure that receives the calculated counter value. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhformatfromrawvalue PDH_FUNCTION PdhFormatFromRawValue( DWORD // dwCounterType, DWORD dwFormat, LONGLONG *pTimeBase, PPDH_RAW_COUNTER pRawValue1, PPDH_RAW_COUNTER pRawValue2, // PPDH_FMT_COUNTERVALUE pFmtValue ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "13027af4-2e76-4c2f-88e8-a2554a16fae3")] public static extern Win32Error PdhFormatFromRawValue(CounterType dwCounterType, PDH_FMT dwFormat, in FILETIME pTimeBase, in PDH_RAW_COUNTER pRawValue1, in PDH_RAW_COUNTER pRawValue2, out PDH_FMT_COUNTERVALUE pFmtValue); /// Retrieves information about a counter, such as data size, counter type, path, and user-supplied data values. /// /// Handle of the counter from which you want to retrieve information. The PdhAddCounter function returns this handle. /// /// /// Determines whether explain text is retrieved. If you set this parameter to TRUE, the explain text for the counter is /// retrieved. If you set this parameter to FALSE, the field in the returned buffer is NULL. /// /// /// Size of the lpBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the /// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the /// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on /// the returned size to reallocate the buffer. /// /// /// Caller-allocated buffer that receives a structure. The structure is variable-length, because the /// string data is appended to the end of the fixed-format portion of the structure. This is done so that all data is returned in a /// single buffer allocated by the caller. Set to NULL if pdwBufferSize is zero. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// PDH_MORE_DATA /// /// The lpBuffer buffer is too small to hold the counter information. This return value is expected if pdwBufferSize is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set lpBuffer to NULL and /// pdwBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetcounterinfoa PDH_FUNCTION PdhGetCounterInfoA( PDH_HCOUNTER // hCounter, BOOLEAN bRetrieveExplainText, LPDWORD pdwBufferSize, PPDH_COUNTER_INFO_A lpBuffer ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "12e1a194-5418-4c2a-9853-ef2d2c666893")] public static extern Win32Error PdhGetCounterInfo(PDH_HCOUNTER hCounter, [MarshalAs(UnmanagedType.U1)] bool bRetrieveExplainText, ref uint pdwBufferSize, IntPtr lpBuffer); /// Returns the time base of the specified counter. /// Handle to the counter. The PdhAddCounter function returns this handle. /// Time base that specifies the number of performance values a counter samples per second. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// The specified counter does not use a time base. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// /// If you use the PdhFormatFromRawValue function to calculate a displayable value instead of calling the /// PdhCalculateCounterFromRawValue function, you must call the PdhGetCounterTimeBase function to retrieve the time base. /// /// /// Each counter that returns time-based performance data has a time base defined for it. The time base of a counter is the number of /// times a counter samples data per second. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetcountertimebase PDH_FUNCTION PdhGetCounterTimeBase( // PDH_HCOUNTER hCounter, LONGLONG *pTimeBase ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "b034c00e-50f1-46af-aebc-0cb968c0b737")] public static extern Win32Error PdhGetCounterTimeBase(PDH_HCOUNTER hCounter, out FILETIME pTimeBase); /// /// /// Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the /// specified input source. /// /// To use handles to data sources, use the PdhGetDataSourceTimeRangeH function. /// /// /// Null-terminated string that specifies the name of a log file from which the time range information is retrieved. /// /// /// Number of structures in the pInfo buffer. This function collects information for only one time range, so the value is typically /// 1, or zero if an error occurred. /// /// A PDH_TIME_INFO structure that receives the time range. /// Size of the PDH_TIME_INFO structure, in bytes. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// PDH_DATA_SOURCE_IS_REAL_TIME /// The current data source is a real-time data source. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdatasourcetimerangea PDH_FUNCTION PdhGetDataSourceTimeRangeA( // LPCSTR szDataSource, LPDWORD pdwNumEntries, PPDH_TIME_INFO pInfo, LPDWORD pdwBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "142ee829-7f1c-4b97-859c-670f7058dfa1")] public static extern Win32Error PdhGetDataSourceTimeRange(string szDataSource, out uint pdwNumEntries, out PDH_TIME_INFO pInfo, ref uint pdwBufferSize); /// /// /// Determines the time range, number of entries and, if applicable, the size of the buffer containing the performance data from the /// specified input source. /// /// /// This function is identical to the PdhGetDataSourceTimeRange function, except that it supports the use of handles to data sources. /// /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// Number of structures in the pInfo buffer. This function collects information for only one time range, so the value is typically /// 1, or zero if an error occurred. /// /// A PDH_TIME_INFO structure that receives the time range. The information spans all bound log files. /// Size of the PDH_TIME_INFO structure, in bytes. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// PDH_DATA_SOURCE_IS_REAL_TIME /// The current data source is a real-time data source. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdatasourcetimerangeh PDH_FUNCTION PdhGetDataSourceTimeRangeH( // PDH_HLOG hDataSource, LPDWORD pdwNumEntries, PPDH_TIME_INFO pInfo, LPDWORD pdwBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "55cfef46-999d-43fa-9b09-9d8916fbf755")] public static extern Win32Error PdhGetDataSourceTimeRangeH(PDH_HLOG hDataSource, out uint pdwNumEntries, out PDH_TIME_INFO pInfo, ref uint pdwBufferSize); /// /// /// Retrieves the name of the default counter for the specified object. This name can be used to set the initial counter selection in /// the Browse Counter dialog box. /// /// To use handles to data sources, use the PdhGetDefaultPerfCounterH function. /// /// Should be NULL. /// /// Null-terminated string that specifies the name of the computer used to verify the object name. If NULL, the local /// computer is used to verify the object name. /// /// /// Null-terminated string that specifies the name of the object whose default counter name you want to retrieve. /// /// /// Caller-allocated buffer that receives the null-terminated default counter name. Set to NULL if pcchBufferSize is zero. /// /// /// Size of the szDefaultCounterName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szDefaultCounterName buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero /// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is /// greater than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_COUNTERNAME /// The default counter name cannot be read or found. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found. /// /// /// PDH_CSTATUS_NO_COUNTER /// The object did not specify a default counter. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szDefaultCounterName to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfcountera PDH_FUNCTION PdhGetDefaultPerfCounterA( // LPCSTR szDataSource, LPCSTR szMachineName, LPCSTR szObjectName, LPSTR szDefaultCounterName, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "0eb78071-3496-40e9-91b0-3c06547c88d5")] public static extern Win32Error PdhGetDefaultPerfCounter([Optional] string szDataSource, [Optional] string szMachineName, string szObjectName, [Optional] StringBuilder szDefaultCounterName, ref uint pcchBufferSize); /// /// /// Retrieves the name of the default counter for the specified object. This name can be used to set the initial counter selection in /// the Browse Counter dialog box. /// /// This function is identical to PdhGetDefaultPerfCounter, except that it supports the use of handles to data sources. /// /// Should be NULL. /// /// Null-terminated string that specifies the name of the computer used to verify the object name. If NULL, the local /// computer is used to verify the name. /// /// /// Null-terminated string that specifies the name of the object whose default counter name you want to retrieve. /// /// /// Caller-allocated buffer that receives the null-terminated default counter name. Set to NULL if pcchBufferSize is zero. /// /// /// Size of the szDefaultCounterName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szDefaultCounterName buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero /// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is /// greater than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_COUNTERNAME /// The default counter name cannot be read or found. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified object could not be found. /// /// /// PDH_CSTATUS_NO_COUNTER /// The object did not specify a default counter. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szDefaultCounterName to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfcounterha PDH_FUNCTION PdhGetDefaultPerfCounterHA( // PDH_HLOG hDataSource, LPCSTR szMachineName, LPCSTR szObjectName, LPSTR szDefaultCounterName, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "d1b3de9a-99ab-4339-8e9f-906f5a5d291d")] public static extern Win32Error PdhGetDefaultPerfCounterH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, string szObjectName, [Optional] StringBuilder szDefaultCounterName, ref uint pcchBufferSize); /// /// /// Retrieves the name of the default object. This name can be used to set the initial object selection in the Browse Counter dialog box. /// /// To use handles to data sources, use the PdhGetDefaultPerfObjectH function. /// /// Should be NULL. /// /// Null-terminated string that specifies the name of the computer used to verify the object name. If NULL, the local /// computer is used to verify the name. /// /// /// /// Caller-allocated buffer that receives the null-terminated default object name. Set to NULL if the pcchBufferSize /// parameter is zero. /// /// Note that PDH always returns Processor for the default object name. /// /// /// Size of the szDefaultObjectName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szDefaultObjectName buffer is too small to contain the object name. This return value is expected if pcchBufferSize is zero /// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is /// greater than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szDefaultObjectName to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfobjecta PDH_FUNCTION PdhGetDefaultPerfObjectA( // LPCSTR szDataSource, LPCSTR szMachineName, LPSTR szDefaultObjectName, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "7c6d4d82-8b60-4422-8108-8ac10f254278")] public static extern Win32Error PdhGetDefaultPerfObject([Optional] string szDataSource, [Optional] string szMachineName, [Optional] StringBuilder szDefaultObjectName, ref uint pcchBufferSize); /// /// /// Retrieves the name of the default object. This name can be used to set the initial object selection in the Browse Counter dialog box. /// /// /// This function is identical to the PdhGetDefaultPerfObject function, except that it supports the use of handles to data sources. /// /// /// Should be NULL. /// /// Null-terminated string that specifies the name of the computer used to verify the object name. If NULL, the local /// computer is used to verify the name. /// /// /// /// Caller-allocated buffer that receives the null-terminated default object name. Set to NULL if pcchBufferSize is zero. /// /// Note that PDH always returns Processor for the default object name. /// /// /// Size of the szDefaultObjectName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szDefaultObjectName buffer is too small to contain the object name. This return value is expected if pcchBufferSize is zero /// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A required parameter is not valid. For example, on some releases you could receive this error if the specified size on input is /// greater than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer is offline or unavailable. /// /// /// PDH_CSTATUS_NO_COUNTERNAME /// The default object name cannot be read or found. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szDefaultObjectName to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdefaultperfobjectha PDH_FUNCTION PdhGetDefaultPerfObjectHA( // PDH_HLOG hDataSource, LPCSTR szMachineName, LPSTR szDefaultObjectName, LPDWORD pcchBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "4950d5b7-3a6f-410d-830f-7868aa84f6d5")] public static extern Win32Error PdhGetDefaultPerfObjectH([Optional] PDH_HLOG hDataSource, [Optional] string szMachineName, [Optional] StringBuilder szDefaultObjectName, ref uint pcchBufferSize); /// /// Returns the version of the currently installed Pdh.dll file. /// Note This function is obsolete and no longer supported. /// /// /// Pointer to a variable that receives the version of Pdh.dll. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_CVERSION_WIN50 /// The file version is a legacy operating system. /// /// /// PDH_VERSION /// The file version is Windows XP. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// This function is used to help in determining the functionality that the currently installed version of Pdh.dll supports. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetdllversion PDH_FUNCTION PdhGetDllVersion( LPDWORD lpdwVersion ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "09c9ecf6-43e0-480c-b607-537632b56576")] public static extern Win32Error PdhGetDllVersion(out uint lpdwVersion); /// /// Returns an array of formatted counter values. Use this function when you want to format the counter values of a counter that /// contains a wildcard character for the instance name. /// /// /// Handle to the counter whose current value you want to format. The PdhAddCounter function returns this handle. /// /// /// Determines the data type of the formatted value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return data as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return data as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return data as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's default scaling factor. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the actual value by 1,000. /// /// /// /// /// Size of the ItemBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the /// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the /// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on /// the returned size to reallocate the buffer. /// /// Number of counter values in the ItemBuffer buffer. /// /// Caller-allocated buffer that receives an array of PDH_FMT_COUNTERVALUE_ITEM structures; the structures contain the counter /// values. Set to NULL if lpdwBufferSize is zero. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The ItemBuffer buffer is not large enough to contain the object name. This return value is expected if lpdwBufferSize is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set ItemBuffer to NULL and /// lpdwBufferSize to 0), and the second time to get the data. /// /// /// The data for the counter is locked for the duration of the call to PdhGetFormattedCounterArray to prevent any changes /// during the processing of the call. /// /// Examples /// The following example shows how to use this function. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetformattedcounterarraya PDH_FUNCTION // PdhGetFormattedCounterArrayA( PDH_HCOUNTER hCounter, DWORD dwFormat, LPDWORD lpdwBufferSize, LPDWORD lpdwItemCount, // PPDH_FMT_COUNTERVALUE_ITEM_A ItemBuffer ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "0f388c7e-d0c8-461d-908c-48af92166996")] public static extern Win32Error PdhGetFormattedCounterArray(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, ref uint lpdwBufferSize, out uint lpdwItemCount, [Optional] IntPtr ItemBuffer); /// Computes a displayable value for the specified counter. /// /// Handle of the counter for which you want to compute a displayable value. The PdhAddCounter function returns this handle. /// /// /// Determines the data type of the formatted value. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FMT_DOUBLE /// Return data as a double-precision floating point real. /// /// /// PDH_FMT_LARGE /// Return data as a 64-bit integer. /// /// /// PDH_FMT_LONG /// Return data as a long integer. /// /// /// You can use the bitwise inclusive OR operator (|) to combine the data type with one of the following scaling factors. /// /// /// Value /// Meaning /// /// /// PDH_FMT_NOSCALE /// Do not apply the counter's default scaling factor. /// /// /// PDH_FMT_NOCAP100 /// /// Counter values greater than 100 (for example, counter values measuring the processor load on multiprocessor computers) will not /// be reset to 100. The default behavior is that counter values are capped at a value of 100. /// /// /// /// PDH_FMT_1000 /// Multiply the actual value by 1,000. /// /// /// /// /// Receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. /// This parameter is optional. /// /// A PDH_FMT_COUNTERVALUE structure that receives the counter value. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid or is incorrectly formatted. /// /// /// PDH_INVALID_DATA /// The specified counter does not contain valid data or a successful status code. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// /// The data for the counter is locked (protected) for the duration of the call to PdhGetFormattedCounterValue to prevent any /// changes during the processing of the call. Reading the data (calling this function successfully) clears the data-changed flag for /// the counter. /// /// /// Some counters, such as rate counters, require two counter values in order to compute a displayable value. In this case you must /// call PdhCollectQueryData twice before calling PdhGetFormattedCounterValue. For more information, see Collecting /// Performance Data. /// /// /// If the specified counter instance does not exist, the method will return PDH_INVALID_DATA and set the CStatus member of /// the PDH_FMT_COUNTERVALUE structure to PDH_CSTATUS_NO_INSTANCE. /// /// /// Prior to Windows Server 2003: The format call may fail for counters that require only a single value when the instance is /// not found. Try calling the query and format calls again. If the format call fails the second time, the instance is not found. As /// an alternative, you can call the PdhEnumObjects function with the refresh option set to TRUE to refresh the counter /// instances before querying and formatting the counter data. /// /// Examples /// For an example, see Browsing Performance Counters or Reading Performance Data from a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetformattedcountervalue PDH_FUNCTION // PdhGetFormattedCounterValue( PDH_HCOUNTER hCounter, DWORD dwFormat, LPDWORD lpdwType, PPDH_FMT_COUNTERVALUE pValue ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "cd104b26-1498-4f95-a411-97d868b43836")] public static extern Win32Error PdhGetFormattedCounterValue(PDH_HCOUNTER hCounter, PDH_FMT dwFormat, out CounterType lpdwType, out PDH_FMT_COUNTERVALUE pValue); /// Returns the size of the specified log file. /// Handle to the log file. The PdhOpenLog or PdhBindInputDataSource function returns this handle. /// Size of the log file, in bytes. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_LOG_FILE_OPEN_ERROR /// An error occurred when trying to open the log file. /// /// /// PDH_INVALID_HANDLE /// The handle is not valid. /// /// /// /// /// If the log file handle points to multiple bound log files, the size is the sum of all the log files. If the log file is a SQL log /// file, the llSize parameter is the number of records in the log file. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetlogfilesize PDH_FUNCTION PdhGetLogFileSize( PDH_HLOG hLog, // LONGLONG *llSize ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "2bb94019-c664-4144-98b6-a0a545f7e4c1")] public static extern Win32Error PdhGetLogFileSize(PDH_HLOG hLog, out long llSize); /// /// Returns an array of raw values from the specified counter. Use this function when you want to retrieve the raw counter values of /// a counter that contains a wildcard character for the instance name. /// /// /// Handle of the counter for whose current raw instance values you want to retrieve. The PdhAddCounter function returns this handle. /// /// /// Size of the ItemBuffer buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter to the /// required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size of the /// buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not rely on /// the returned size to reallocate the buffer. /// /// Number of raw counter values in the ItemBuffer buffer. /// /// Caller-allocated buffer that receives the array of structures; the structures contain the raw /// instance counter values. Set to NULL if lpdwBufferSize is zero. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The ItemBuffer buffer is not large enough to contain the object name. This return value is expected if lpdwBufferSize is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set ItemBuffer to NULL and /// lpdwBufferSize to 0), and the second time to get the data. /// /// /// The data for the counter is locked for the duration of the call to PdhGetRawCounterArray to prevent any changes during /// processing of the call. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetrawcounterarraya PDH_FUNCTION PdhGetRawCounterArrayA( // PDH_HCOUNTER hCounter, LPDWORD lpdwBufferSize, LPDWORD lpdwItemCount, PPDH_RAW_COUNTER_ITEM_A ItemBuffer ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "03b30d08-6901-45cd-bd6d-d2672eb0f914")] public static extern Win32Error PdhGetRawCounterArray(PDH_HCOUNTER hCounter, ref uint lpdwBufferSize, out uint lpdwItemCount, IntPtr ItemBuffer); /// Returns the current raw value of the counter. /// /// Handle of the counter from which to retrieve the current raw value. The PdhAddCounter function returns this handle. /// /// /// Receives the counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. /// This parameter is optional. /// /// A PDH_RAW_COUNTER structure that receives the counter value. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid or is incorrectly formatted. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// /// The data for the counter is locked (protected) for the duration of the call to PdhGetRawCounterValue to prevent any /// changes during processing of the call. /// /// /// If the specified counter instance does not exist, this function will return ERROR_SUCCESS and the CStatus member of the /// PDH_RAW_COUNTER structure will contain PDH_CSTATUS_NO_INSTANCE. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhgetrawcountervalue PDH_FUNCTION PdhGetRawCounterValue( // PDH_HCOUNTER hCounter, LPDWORD lpdwType, PPDH_RAW_COUNTER pValue ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "bb246c82-8748-4e2f-9f44-a206199aff90")] public static extern Win32Error PdhGetRawCounterValue(PDH_HCOUNTER hCounter, out CounterType lpdwType, out PDH_RAW_COUNTER pValue); /// Determines if the specified query is a real-time query. /// Handle to the query. The PdhOpenQuery function returns this handle. /// /// If the query is a real-time query, the return value is TRUE. /// If the query is not a real-time query, the return value is FALSE. /// /// /// The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. /// Instead, it describes the collection of performance data from a source providing current information (for example, the registry /// or a WMI provider) rather than from a log file. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhisrealtimequery BOOL PdhIsRealTimeQuery( PDH_HQUERY hQuery ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "4f6b2d8d-3a0f-4346-8b8e-a7aea11fbc40")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PdhIsRealTimeQuery(PDH_HQUERY hQuery); /// Returns the counter index corresponding to the specified counter name. /// /// Null-terminated string that specifies the name of the computer where the specified counter is located. The computer name /// can be specified by the DNS name or the IP address. If NULL, the function uses the local computer. /// /// Null-terminated string that contains the counter name. /// Index of the counter. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following is a possible value. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid or is incorrectly formatted. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhlookupperfindexbynamea PDH_FUNCTION PdhLookupPerfIndexByNameA( // LPCSTR szMachineName, LPCSTR szNameBuffer, LPDWORD pdwIndex ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "b8530bf3-0a9b-49c2-9494-4dca14cd57ef")] public static extern Win32Error PdhLookupPerfIndexByName([Optional] string szMachineName, string szNameBuffer, out uint pdwIndex); /// Returns the performance object name or counter name corresponding to the specified index. /// /// Null-terminated string that specifies the name of the computer where the specified performance object or counter is /// located. The computer name can be specified by the DNS name or the IP address. If NULL, the function uses the local computer. /// /// Index of the performance object or counter. /// /// Caller-allocated buffer that receives the null-terminated name of the performance object or counter. Set to NULL if /// pcchNameBufferSize is zero. /// /// /// Size of the szNameBuffer buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szNameBuffer buffer is not large enough to contain the counter name. This return value is expected if pcchNameBufferSize is /// zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szNameBuffer to NULL and /// pcchNameBufferSize to 0), and the second time to get the data. /// /// /// Windows XP: You must specify a buffer and buffer size. The function sets pcchNameBufferSize to either the required size or /// the size of the buffer that was used. If the buffer is too small, the function returns PDH_INSUFFICIENT_BUFFER instead of /// PDH_MORE_DATA. The maximum string size in bytes is PDH_MAX_COUNTER_NAME * sizeof(TCHAR). /// /// /// The index value that you specify must match one of the index values associated with the objects or counters that were loaded on /// the computer. The index/name value pairs are stored in the Counters registry value in the following registry location. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhlookupperfnamebyindexa PDH_FUNCTION PdhLookupPerfNameByIndexA( // LPCSTR szMachineName, DWORD dwNameIndex, LPSTR szNameBuffer, LPDWORD pcchNameBufferSize ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "6d5e1465-296b-4d8c-b0cb-aefdffb8539e")] public static extern Win32Error PdhLookupPerfNameByIndex([Optional] string szMachineName, uint dwNameIndex, [Optional] StringBuilder szNameBuffer, ref uint pcchNameBufferSize); /// Creates a full counter path using the members specified in the PDH_COUNTER_PATH_ELEMENTS structure. /// /// /// A PDH_COUNTER_PATH_ELEMENTS structure that contains the members used to make up the path. Only the szObjectName and /// szCounterName members are required, the others are optional. /// /// /// If the instance name member is NULL, the path will not contain an instance reference and the szParentInstance and /// dwInstanceIndex members will be ignored. /// /// /// /// Caller-allocated buffer that receives a null-terminated counter path. The maximum length of a counter path is /// PDH_MAX_COUNTER_PATH. Set to NULL if pcchBufferSize is zero. /// /// /// Size of the szFullPathBuffer buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// Format of the input and output counter values. You can specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_PATH_WBEM_RESULT /// Converts a PDH path to the WMI class and property name format. /// /// /// PDH_PATH_WBEM_INPUT /// Converts the WMI class and property name to a PDH path. /// /// /// 0 /// Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szFullPathBuffer buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szFullPathBuffer to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhmakecounterpatha PDH_FUNCTION PdhMakeCounterPathA( // PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPSTR szFullPathBuffer, LPDWORD pcchBufferSize, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")] public static extern Win32Error PdhMakeCounterPath(in PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, [Optional] StringBuilder szFullPathBuffer, ref uint pcchBufferSize, [Optional] PDH_PATH dwFlags); /// Creates a full counter path using the members specified in the PDH_COUNTER_PATH_ELEMENTS structure. /// /// /// A PDH_COUNTER_PATH_ELEMENTS structure that contains the members used to make up the path. Only the szObjectName and /// szCounterName members are required, the others are optional. /// /// /// If the instance name member is NULL, the path will not contain an instance reference and the szParentInstance and /// dwInstanceIndex members will be ignored. /// /// /// /// Caller-allocated buffer that receives a null-terminated counter path. The maximum length of a counter path is /// PDH_MAX_COUNTER_PATH. Set to NULL if pcchBufferSize is zero. /// /// /// Size of the szFullPathBuffer buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this /// parameter to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the /// actual size of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you /// should not rely on the returned size to reallocate the buffer. /// /// /// Format of the input and output counter values. You can specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_PATH_WBEM_RESULT /// Converts a PDH path to the WMI class and property name format. /// /// /// PDH_PATH_WBEM_INPUT /// Converts the WMI class and property name to a PDH path. /// /// /// 0 /// Returns the path in the PDH format, for example, \\computer\object(parent/instance#index)\counter. /// /// /// /// The language identifier to be used in creating the path. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_MORE_DATA /// /// The szFullPathBuffer buffer is too small to contain the counter name. This return value is expected if pcchBufferSize is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid or is incorrectly formatted. For example, on some releases you could receive this error if the specified /// size on input is greater than zero but less than the required size. /// /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set szFullPathBuffer to NULL and /// pcchBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhmakecounterpatha PDH_FUNCTION PdhMakeCounterPathA( // PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPSTR szFullPathBuffer, LPDWORD pcchBufferSize, DWORD dwFlags ); [PInvokeData("pdh.h", MSDNShortId = "f2dc5f77-9f9e-4290-95fa-ce2f1e81fc69")] public static Win32Error PdhMakeCounterPath(in PDH_COUNTER_PATH_ELEMENTS pCounterPathElements, [Optional] StringBuilder szFullPathBuffer, ref uint pcchBufferSize, PDH_PATH dwFlags, ushort langId) => PdhMakeCounterPath(pCounterPathElements, szFullPathBuffer, ref pcchBufferSize, PDH_PATH_LANG_FLAGS(langId, dwFlags)); /// Opens the specified log file for reading or writing. /// /// /// Null-terminated string that specifies the name of the log file to open. The name can contain an absolute or relative path. /// /// /// If the lpdwLogType parameter is PDH_LOG_TYPE_SQL, specify the name of the log file in the form, SQL: DataSourceName /// ! LogFileName. /// /// /// /// Type of access to use to open the log file. Specify one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_LOG_READ_ACCESS /// Open the log file for reading. /// /// /// PDH_LOG_WRITE_ACCESS /// Open a new log file for writing. /// /// /// PDH_LOG_UPDATE_ACCESS /// Open an existing log file for writing. /// /// /// /// You can use the bitwise inclusive OR operator (|) to combine the access type with one or more of the following creation flags. /// /// /// /// Value /// Meaning /// /// /// PDH_LOG_CREATE_NEW /// Creates a new log file with the specified name. /// /// /// PDH_LOG_CREATE_ALWAYS /// /// Creates a new log file with the specified name. If the log file already exists, the function removes the existing log file before /// creating the new file. /// /// /// /// PDH_LOG_OPEN_EXISTING /// /// Opens an existing log file with the specified name. If a log file with the specified name does not exist, this is equal to PDH_LOG_CREATE_NEW. /// /// /// /// PDH_LOG_OPEN_ALWAYS /// Opens an existing log file with the specified name or creates a new log file with the specified name. /// /// /// PDH_LOG_OPT_CIRCULAR /// /// Creates a circular log file with the specified name. When the file reaches the value of the dwMaxSize parameter, data wraps to /// the beginning of the log file. You can specify this flag only if the lpdwLogType parameter is PDH_LOG_TYPE_BINARY. /// /// /// /// PDH_LOG_USER_STRING /// /// Used with PDH_LOG_TYPE_TSV to write the user caption or log file description indicated by the szUserString parameter of /// PdhUpdateLog or PdhOpenLog. The user caption or log file description is written as the last column in the first line of the text log. /// /// /// /// /// /// Type of log file to open. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_LOG_TYPE_UNDEFINED /// /// Undefined log file format. If specified, PDH determines the log file type. You cannot specify this value if the dwAccessFlags /// parameter is PDH_LOG_WRITE_ACCESS. /// /// /// /// PDH_LOG_TYPE_CSV /// /// Text file containing column headers in the first line, and individual data records in each subsequent line. The fields of each /// data record are comma-delimited. The first line also contains information about the format of the file, the PDH version used to /// create the log file, and the names and paths of each of the counters. /// /// /// /// PDH_LOG_TYPE_SQL /// The data source of the log file is an SQL database. /// /// /// PDH_LOG_TYPE_TSV /// /// Text file containing column headers in the first line, and individual data records in each subsequent line. The fields of each /// data record are tab-delimited. The first line also contains information about the format of the file, the PDH version used to /// create the log file, and the names and paths of each of the counters. /// /// /// /// PDH_LOG_TYPE_BINARY /// Binary log file format. /// /// /// /// /// Specify a query handle if you are writing query data to a log file. The PdhOpenQuery function returns this handle. /// This parameter is ignored and should be NULL if you are reading from the log file. /// /// /// /// Maximum size of the log file, in bytes. Specify the maximum size if you want to limit the file size or if dwAccessFlags specifies /// PDH_LOG_OPT_CIRCULAR; otherwise, set to 0. /// /// /// For circular log files, you must specify a value large enough to hold at least one sample. Sample size depends on data being /// collected. However, specifying a value of at least one megabyte will cover most samples. /// /// /// /// Null-terminated string that specifies the user-defined caption of the log file. A log file caption generally describes the /// contents of the log file. When an existing log file is opened, the value of this parameter is ignored. /// /// Handle to the opened log file. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// /// /// /// To use this function to write performance data to a log file, you must open a query using PdhOpenQuery and add the desired /// counters to it, before calling this function. /// /// /// Newer operating systems can read log files that were generated on older operating systems; however, log files that were created /// on Windows Vista and later operating systems cannot be read on earlier operating systems. /// /// The following rules apply to log files /// /// /// /// /// /// /// /// /// /// /// /// Examples /// For an example, see Writing Performance Data to a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenloga PDH_FUNCTION PdhOpenLogA( LPCSTR szLogFileName, DWORD // dwAccessFlags, LPDWORD lpdwLogType, PDH_HQUERY hQuery, DWORD dwMaxSize, LPCSTR szUserCaption, PDH_HLOG *phLog ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "a8457959-af3a-497f-91ca-0876cbb552cc")] public static extern Win32Error PdhOpenLog(string szLogFileName, PdhLogAccess dwAccessFlags, ref PDH_LOG_TYPE lpdwLogType, [Optional] PDH_HQUERY hQuery, [Optional] uint dwMaxSize, [Optional] string szUserCaption, out SafePDH_HLOG phLog); /// /// Creates a new query that is used to manage the collection of performance data. /// To use handles to data sources, use the PdhOpenQueryH function. /// /// /// Null-terminated string that specifies the name of the log file from which to retrieve performance data. If NULL, /// performance data is collected from a real-time data source. /// /// /// User-defined value to associate with this query. To retrieve the user data later, call PdhGetCounterInfo and access the /// dwQueryUserData member of PDH_COUNTER_INFO. /// /// Handle to the query. You use this handle in subsequent calls. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenquerya PDH_FUNCTION PdhOpenQueryA( LPCSTR szDataSource, // DWORD_PTR dwUserData, PDH_HQUERY *phQuery ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "ec4e5353-c7f5-4957-b7f4-39df508846a0")] public static extern Win32Error PdhOpenQuery([Optional] string szDataSource, [Optional] IntPtr dwUserData, out SafePDH_HQUERY phQuery); /// /// Creates a new query that is used to manage the collection of performance data. /// This function is identical to the PdhOpenQuery function, except that it supports the use of handles to data sources. /// /// Handle to a data source returned by the PdhBindInputDataSource function. /// /// User-defined value to associate with this query. To retrieve the user data later, call the PdhGetCounterInfo function and access /// the dwQueryUserData member of PDH_COUNTER_INFO. /// /// Handle to the query. You use this handle in subsequent calls. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhopenqueryh PDH_FUNCTION PdhOpenQueryH( PDH_HLOG hDataSource, // DWORD_PTR dwUserData, PDH_HQUERY *phQuery ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "068c55da-d7e0-4111-91c8-a2bbd676f99d")] public static extern Win32Error PdhOpenQueryH([Optional] PDH_HLOG hDataSource, [Optional] IntPtr dwUserData, out SafePDH_HQUERY phQuery); /// Parses the elements of the counter path and stores the results in the PDH_COUNTER_PATH_ELEMENTS structure. /// /// Null-terminated string that contains the counter path to parse. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// /// Caller-allocated buffer that receives a PDH_COUNTER_PATH_ELEMENTS structure. The structure contains pointers to the individual /// string elements of the path referenced by the szFullPathBuffer parameter. The function appends the strings to the end of the /// PDH_COUNTER_PATH_ELEMENTS structure. The allocated buffer should be large enough for the structure and the strings. Set to /// NULL if pdwBufferSize is zero. /// /// /// Size of the pCounterPathElements buffer, in bytes. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// Reserved. Must be zero. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// A parameter is not valid. /// /// /// PDH_MORE_DATA /// /// The pCounterPathElements buffer is too small to contain the path elements. This return value is expected if pdwBufferSize is zero /// on input. If the specified size on input is greater than zero but less than the required size, you should not rely on the /// returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_PATH /// /// The path is not formatted correctly and cannot be parsed. For example, on some releases you could receive this error if the /// specified size on input is greater than zero but less than the required size. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set pCounterPathElements to NULL and /// pdwBufferSize to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhparsecounterpatha PDH_FUNCTION PdhParseCounterPathA( LPCSTR // szFullPathBuffer, PPDH_COUNTER_PATH_ELEMENTS_A pCounterPathElements, LPDWORD pdwBufferSize, DWORD dwFlags ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "760b94e9-88df-4f7d-92e9-333d682779f6")] public static extern Win32Error PdhParseCounterPath(string szFullPathBuffer, [Optional] IntPtr pCounterPathElements, ref uint pdwBufferSize, uint dwFlags = 0); /// Parses the elements of an instance string. /// /// /// Null-terminated string that specifies the instance string to parse into individual components. This string can contain the /// following formats, and is less than MAX_PATH characters in length: /// /// /// /// instance /// /// /// instance#index /// /// /// parent/instance /// /// /// parent/instance#index /// /// /// /// /// Caller-allocated buffer that receives the null-terminated instance name. Set to NULL if pcchInstanceNameLength is zero. /// /// /// Size of the szInstanceName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// /// Caller-allocated buffer that receives the null-terminated name of the parent instance, if one is specified. Set to /// NULL if pcchParentNameLength is zero. /// /// /// Size of the szParentName buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// /// Index value of the instance. If an index entry is not present in the string, then this value is zero. This parameter can be NULL. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MORE_DATA /// /// One or both of the string buffers are too small to contain the data. This return value is expected if the corresponding size /// buffer is zero on input. If the specified size on input is greater than zero but less than the required size, you should not rely /// on the returned size to reallocate the buffer. /// /// /// /// PDH_INVALID_INSTANCE /// The instance string is incorrectly formatted, exceeds MAX_PATH characters in length, or cannot be parsed. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set the buffers to NULL and buffer /// sizes to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhparseinstancenamea PDH_FUNCTION PdhParseInstanceNameA( LPCSTR // szInstanceString, LPSTR szInstanceName, LPDWORD pcchInstanceNameLength, LPSTR szParentName, LPDWORD pcchParentNameLength, LPDWORD // lpIndex ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "8304ecee-5141-450a-be11-838b9f52413b")] public static extern Win32Error PdhParseInstanceName(string szInstanceString, [Optional] StringBuilder szInstanceName, ref uint pcchInstanceNameLength, [Optional] StringBuilder szParentName, ref uint pcchParentNameLength, out uint lpIndex); /// Reads the information in the specified binary trace log file. /// Handle to the log file. The PdhOpenLog or PdhBindInputDataSource function returns this handle. /// /// Time stamp of the record to be read. If the time stamp does not match a record in the log file, the function returns the record /// that has a time stamp closest to (but not greater than) the given time stamp. /// /// /// Caller-allocated buffer that receives a structure; the structure contains the log file record /// information. Set to NULL if pdwBufferLength is zero. /// /// /// Size of the pRawLogRecord buffer, in TCHARs. If zero on input, the function returns PDH_MORE_DATA and sets this parameter /// to the required buffer size. If the buffer is larger than the required size, the function sets this parameter to the actual size /// of the buffer that was used. If the specified size on input is greater than zero but less than the required size, you should not /// rely on the returned size to reallocate the buffer. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// /// A parameter is not valid. For example, on some releases you could receive this error if the specified size on input is greater /// than zero but less than the required size. /// /// /// /// PDH_MORE_DATA /// /// The pRawLogRecord buffer is too small to contain the path elements. This return value is expected if pdwBufferLength is zero on /// input. If the specified size on input is greater than zero but less than the required size, you should not rely on the returned /// size to reallocate the buffer. /// /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// Unable to allocate memory in order to complete the function. /// /// /// /// /// You should call this function twice, the first time to get the required buffer size (set pRawLogRecord to NULL and /// pdwBufferLength to 0), and the second time to get the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhreadrawlogrecord PDH_FUNCTION PdhReadRawLogRecord( PDH_HLOG hLog, // FILETIME ftRecord, PPDH_RAW_LOG_RECORD pRawLogRecord, LPDWORD pdwBufferLength ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "fb93b6ea-ca31-4ff1-a553-b02388be8b72")] public static extern Win32Error PdhReadRawLogRecord(PDH_HLOG hLog, FILETIME ftRecord, [Optional] IntPtr pRawLogRecord, ref uint pdwBufferLength); /// Removes a counter from a query. /// Handle of the counter to remove from its query. The PdhAddCounter function returns this handle. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. /// The following is a possible value. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// /// /// Do not use the counter handle after removing the counter from the query. /// The following shows the syntax if calling this function from Visual Basic. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhremovecounter PDH_FUNCTION PdhRemoveCounter( PDH_HCOUNTER // hCounter ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "adf9c7bd-47d6-489a-88fc-954fdf127ce8")] public static extern Win32Error PdhRemoveCounter(PDH_HCOUNTER hCounter); /// Displays a dialog window that prompts the user to specify the source of the performance data. /// Owner of the dialog window. This can be NULL if there is no owner (the desktop becomes the owner). /// /// Dialog boxes that will be displayed to prompt for the data source. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_FLAGS_FILE_BROWSER_ONLY /// Display the file browser only. Set this flag when you want to prompt for the name and location of a log file only. /// /// /// 0 /// /// Display the data source selection dialog box. The dialog box lets the user select performance data from either a log file or a /// real-time source. If the user specified that data is to be collected from a log file, a file browser is displayed for the user to /// specify the name and location of the log file. /// /// /// /// /// /// /// Caller-allocated buffer that receives a null-terminated string that contains the name of a log file that the user /// selected. The log file name is truncated to the size of the buffer if the buffer is too small. /// /// If the user selected a real time source, the buffer is empty. /// /// Maximum size of the szDataSource buffer, in TCHARs. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// The length of the buffer passed in the pcchBufferLength is not equal to the actual length of the szDataSource buffer. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// A zero-length buffer was passed in the szDataSource parameter. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhselectdatasourcea PDH_FUNCTION PdhSelectDataSourceA( HWND // hWndOwner, DWORD dwFlags, LPSTR szDataSource, LPDWORD pcchBufferLength ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "211d4504-e1f9-48a0-8ddd-613f2f183c59")] public static extern Win32Error PdhSelectDataSource([Optional] HWND hWndOwner, PdhSelectDataSourceFlags dwFlags, StringBuilder szDataSource, ref uint pcchBufferLength); /// /// Sets the scale factor that is applied to the calculated value of the specified counter when you request the formatted counter /// value. If the PDH_FMT_NOSCALE flag is set, then this scale factor is ignored. /// /// Handle of the counter to apply the scale factor to. The PdhAddCounter function returns this handle. /// /// Power of ten by which to multiply the calculated value before returning it. The minimum value of this parameter is PDH_MIN_SCALE /// (–7), where the returned value is the actual value multiplied by 10⁷. The maximum value of this parameter is PDH_MAX_SCALE (+7), /// where the returned value is the actual value multiplied by 10⁺⁷. A value of zero will set the scale to one, so that the actual /// value is returned. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// The scale value is out of range. /// /// /// PDH_INVALID_HANDLE /// The counter handle is not valid. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetcounterscalefactor PDH_FUNCTION PdhSetCounterScaleFactor( // PDH_HCOUNTER hCounter, LONG lFactor ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "6db99e03-0b03-4c1c-b82a-2982b52746db")] public static extern Win32Error PdhSetCounterScaleFactor(PDH_HCOUNTER hCounter, int lFactor); /// Specifies the source of the real-time data. /// /// Source of the performance data. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// DATA_SOURCE_REGISTRY /// The data source is the registry interface. This is the default. /// /// /// DATA_SOURCE_WBEM /// The data source is a WMI provider. /// /// /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following is a possible value. /// /// /// Return code /// Description /// /// /// PDH_INVALID_ARGUMENT /// The parameter is not valid. /// /// /// /// /// /// The term real-time as used in the description of this function does not imply the standard meaning of the term real-time. /// Instead, it describes the collection of performance data from a source providing current information (for example, the registry /// or a WMI provider) rather than from a log file. /// /// /// If you want to query real-time data from WMI, you must call PdhSetDefaultRealTimeDataSource to set the default real-time /// data source. You must call this function before calling any other PDH API function. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetdefaultrealtimedatasource PDH_FUNCTION // PdhSetDefaultRealTimeDataSource( DWORD dwDataSourceId ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "5a46ac26-c1a1-40c1-a328-688e0b394e18")] public static extern Win32Error PdhSetDefaultRealTimeDataSource(uint dwDataSourceId); /// Limits the samples that you can read from a log file to those within the specified time range, inclusively. /// Handle to the query. The PdhOpenQuery function returns this handle. /// /// A PDH_TIME_INFO structure that specifies the time range. Specify the time as local file time. The end time must be greater than /// the start time. You can specify 0 for the start time and the maximum 64-bit value for the end time if you want to read all records. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The query handle is not valid. /// /// /// PDH_INVALID_ARGUMENT /// The ending time range value must be greater than the starting time range value. /// /// /// /// /// When the end of the specified time range or the end of the log file is reached, the PdhCollectQueryData function will return PDH_NO_MORE_DATA. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhsetquerytimerange PDH_FUNCTION PdhSetQueryTimeRange( PDH_HQUERY // hQuery, PPDH_TIME_INFO pInfo ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "ed0e100e-9f82-48c0-b4bb-72820c5eeaa8")] public static extern Win32Error PdhSetQueryTimeRange(PDH_HQUERY hQuery, in PDH_TIME_INFO pInfo); /// Collects counter data for the current query and writes the data to the log file. /// Handle of a single log file to update. The PdhOpenLog function returns this handle. /// /// Null-terminated string that contains a user-defined comment to add to the data record. The string can not be empty. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_INVALID_HANDLE /// The log file handle is not valid. /// /// /// PDH_INVALID_ARGUMENT /// An empty string was passed in the szUserString parameter. /// /// /// /// /// If you are updating a log file from another log file, the comments from the other log file do not migrate. /// Examples /// For an example, see Writing Performance Data to a Log File. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhupdateloga PDH_FUNCTION PdhUpdateLogA( PDH_HLOG hLog, LPCSTR // szUserString ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "b2052275-6944-41f4-92ac-38967ed270f3")] public static extern Win32Error PdhUpdateLog(PDH_HLOG hLog, string szUserString); /// /// Synchronizes the information in the log file catalog with the performance data in the log file. /// Note This function is obsolete. /// /// Handle to the log file containing the file catalog to update. The PdhOpenLog function. /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_NOT_IMPLEMENTED /// A handle to a CSV or TSV log file was specified. These log file types do not have catalogs. /// /// /// PDH_UNKNOWN_LOG_FORMAT /// A handle to a log file with an unknown format was specified. /// /// /// PDH_INVALID_HANDLE /// The handle is not valid. /// /// /// /// /// /// The log file catalog serves as an index to the performance data records in the log file, providing for faster searches for /// individual records in the file. /// /// /// Catalogs should be updated when the data collection process is complete and the log file has been closed. The catalog can be /// updated during data collection, but doing this may disrupt the process of logging the performance data because updating the /// catalogs can be time consuming. /// /// /// Perfmon, CSV, and TSV log files do not have catalogs. Specifying a handle to these log file types will result in a return value /// of PDH_NOT_IMPLEMENTED. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhupdatelogfilecatalog PDH_FUNCTION PdhUpdateLogFileCatalog( // PDH_HLOG hLog ); [DllImport(Lib.Pdh, SetLastError = false, ExactSpelling = true)] [PInvokeData("pdh.h", MSDNShortId = "e8aa8462-48f1-4ccd-8c41-a7358975e056")] public static extern Win32Error PdhUpdateLogFileCatalog(PDH_HLOG hLog); /// Validates that the counter is present on the computer specified in the counter path. /// /// Null-terminated string that contains the counter path to validate. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_CSTATUS_NO_INSTANCE /// The specified instance of the performance object was not found. /// /// /// PDH_CSTATUS_NO_COUNTER /// The specified counter was not found in the performance object. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified performance object was not found on the computer. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer could not be found or connected to. /// /// /// PDH_CSTATUS_BAD_COUNTERNAME /// The counter path string could not be parsed. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// The function is unable to allocate a required temporary buffer. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhvalidatepatha PDH_FUNCTION PdhValidatePathA( LPCSTR // szFullPathBuffer ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "9248e63c-2672-466f-85f5-46f26e31dc75")] public static extern Win32Error PdhValidatePath(string szFullPathBuffer); /// Validates that the specified counter is present on the computer or in the log file. /// /// Handle to the data source. The PdhOpenLog and PdhBindInputDataSource functions return this handle. /// To validate that the counter is present on the local computer, specify NULL (this is the same as calling PdhValidatePath). /// /// /// Null-terminated string that specifies the counter path to validate. The maximum length of a counter path is PDH_MAX_COUNTER_PATH. /// /// /// If the function succeeds, it returns ERROR_SUCCESS. /// If the function fails, the return value is a system error code or a PDH error code. The following are possible values. /// /// /// Return code /// Description /// /// /// PDH_CSTATUS_NO_INSTANCE /// The specified instance of the performance object was not found. /// /// /// PDH_CSTATUS_NO_COUNTER /// The specified counter was not found in the performance object. /// /// /// PDH_CSTATUS_NO_OBJECT /// The specified performance object was not found on the computer or in the log file. /// /// /// PDH_CSTATUS_NO_MACHINE /// The specified computer could not be found or connected to. /// /// /// PDH_CSTATUS_BAD_COUNTERNAME /// The counter path string could not be parsed. /// /// /// PDH_MEMORY_ALLOCATION_FAILURE /// The function is unable to allocate a required temporary buffer. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/nf-pdh-pdhvalidatepathexw PDH_FUNCTION PdhValidatePathExW( PDH_HLOG // hDataSource, LPCWSTR szFullPathBuffer ); [DllImport(Lib.Pdh, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("pdh.h", MSDNShortId = "e6b52af7-7276-4565-aa61-73899796a13c")] public static extern Win32Error PdhValidatePathExW(PDH_HLOG hDataSource, string szFullPathBuffer); private static PDH_PATH PDH_PATH_LANG_FLAGS(ushort LangId, PDH_PATH Flags) => (PDH_PATH)(((LangId & 0x0000FFFF) << 16) | ((int)Flags & 0x0000FFFF)); /// /// The PDH_BROWSE_DLG_CONFIG structure is used by the PdhBrowseCounters function to configure the Browse Performance /// Counters dialog box. /// /// /// Each time the Add button is clicked, the szReturnPathBuffer buffer contains the selected counter and the pCallBack /// callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_browse_dlg_config_a typedef struct _BrowseDlgConfig_A { DWORD // bIncludeInstanceIndex : 1; DWORD bSingleCounterPerAdd : 1; DWORD bSingleCounterPerDialog : 1; DWORD bLocalCountersOnly : 1; DWORD // bWildCardInstances : 1; DWORD bHideDetailBox : 1; DWORD bInitializePath : 1; DWORD bDisableMachineSelection : 1; DWORD // bIncludeCostlyObjects : 1; DWORD bShowObjectBrowser : 1; DWORD bReserved : 22; HWND hWndOwner; LPSTR szDataSource; LPSTR // szReturnPathBuffer; DWORD cchReturnPathLength; CounterPathCallBack pCallBack; DWORD_PTR dwCallBackArg; PDH_STATUS CallBackStatus; // DWORD dwDefaultDetailLevel; LPSTR szDialogBoxCaption; } PDH_BROWSE_DLG_CONFIG_A, *PPDH_BROWSE_DLG_CONFIG_A; [PInvokeData("pdh.h", MSDNShortId = "8e045e0b-c157-4527-902c-6096c7922642")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_BROWSE_DLG_CONFIG { /// public BrowseFlag Flags; /// Handle of the window to own the dialog. If NULL, the owner is the desktop. public HWND hWndOwner; /// /// Pointer to a null-terminated string that specifies the name of the log file from which the list of counters is /// retrieved. If NULL, the list of counters is retrieved from the local computer (or remote computer if specified). /// [MarshalAs(UnmanagedType.LPTStr)] public string szDataSource; /// /// Pointer to a MULTI_SZ that contains the selected counter paths. /// /// If bInitializePath is TRUE, you can use this member to specify a counter path whose components are used to /// highlight entries in computer, object, counter, and instance lists when the dialog is first displayed. /// /// public IntPtr szReturnPathBuffer; /// /// Size of the szReturnPathBuffer buffer, in TCHARs. If the callback function reallocates a new buffer, it must /// also update this value. /// public uint cchReturnPathLength; /// Pointer to the callback function that processes the user's selection. For more information, see CounterPathCallBack. public CounterPathCallBack pCallBack; /// Caller-defined value that is passed to the callback function. public IntPtr dwCallBackArg; /// /// /// On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets /// the status value resulting from processing. /// /// /// If the buffer is too small to load the current selection, the dialog sets this value to PDH_MORE_DATA. If this value is /// ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list. /// /// /// If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the dialog will try to load /// the buffer with the selected paths and call the callback function again. /// /// If some other error occurred, then the callback function should return the appropriate PDH error status value. /// public Win32Error CallBackStatus; /// /// /// Default detail level to show in the Detail level list if bHideDetailBox is FALSE. If /// bHideDetailBox is TRUE, the dialog uses this value to filter the displayed performance counters and objects. /// You can specify one of the following values: /// /// /// /// Detail level /// Meaning /// /// /// PERF_DETAIL_NOVICE /// A novice user can understand the counter data. /// /// /// PERF_DETAIL_ADVANCED /// The counter data is provided for advanced users. /// /// /// PERF_DETAIL_EXPERT /// The counter data is provided for expert users. /// /// /// PERF_DETAIL_WIZARD /// The counter data is provided for system designers. /// /// /// public PERF_DETAIL dwDefaultDetailLevel; /// /// Pointer to a null-terminated string that specifies the optional caption to display in the caption bar of the dialog /// box. If this member is NULL, the caption will be Browse Performance Counters. /// [MarshalAs(UnmanagedType.LPTStr)] public string szDialogBoxCaption; /// On return, gets the selected counter paths. public string[] CounterPaths => szReturnPathBuffer.ToStringEnum(CharSet.Auto, 0, cchReturnPathLength).ToArray(); } /// /// The PDH_BROWSE_DLG_CONFIG_H structure is used by the PdhBrowseCountersH function to configure the Browse Performance /// Counters dialog box. /// /// /// Each time the Add button is clicked, the szReturnPathBuffer buffer contains the selected counter and the pCallBack /// callback function is called. The callback function should call the PdhAddCounter function for each counter in the buffer. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_browse_dlg_config_ha typedef struct _BrowseDlgConfig_HA { DWORD // bIncludeInstanceIndex : 1; DWORD bSingleCounterPerAdd : 1; DWORD bSingleCounterPerDialog : 1; DWORD bLocalCountersOnly : 1; DWORD // bWildCardInstances : 1; DWORD bHideDetailBox : 1; DWORD bInitializePath : 1; DWORD bDisableMachineSelection : 1; DWORD // bIncludeCostlyObjects : 1; DWORD bShowObjectBrowser : 1; DWORD bReserved : 22; HWND hWndOwner; PDH_HLOG hDataSource; LPSTR // szReturnPathBuffer; DWORD cchReturnPathLength; CounterPathCallBack pCallBack; DWORD_PTR dwCallBackArg; PDH_STATUS CallBackStatus; // DWORD dwDefaultDetailLevel; LPSTR szDialogBoxCaption; } PDH_BROWSE_DLG_CONFIG_HA, *PPDH_BROWSE_DLG_CONFIG_HA; [PInvokeData("pdh.h", MSDNShortId = "db30ff94-3238-45a0-a78e-8b3cd00ec79c")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_BROWSE_DLG_CONFIG_H { /// public BrowseFlag Flags; /// Handle of the window to own the dialog. If NULL, the owner is the desktop. public HWND hWndOwner; /// Handle to a data source returned by the PdhBindInputDataSource function. public PDH_HLOG hDataSource; /// /// Pointer to a MULTI_SZ that contains the selected counter paths. /// /// If bInitializePath is TRUE, you can use this member to specify a counter path whose components are used to /// highlight entries in computer, object, counter, and instance lists when the dialog is first displayed. /// /// [MarshalAs(UnmanagedType.LPTStr)] public string szReturnPathBuffer; /// /// Size of the szReturnPathBuffer buffer, in TCHARs. If the callback function reallocates a new buffer, it must /// also update this value. /// public uint cchReturnPathLength; /// Pointer to the callback function that processes the user's selection. For more information, see CounterPathCallBack. public CounterPathCallBack pCallBack; /// Caller-defined value that is passed to the callback function. public IntPtr dwCallBackArg; /// /// /// On entry to the callback function, this member contains the status of the path buffer. On exit, the callback function sets /// the status value resulting from processing. /// /// /// If the buffer is too small to load the current selection, the dialog sets this value to PDH_MORE_DATA. If this value is /// ERROR_SUCCESS, then the szReturnPathBuffer member contains a valid counter path or counter path list. /// /// /// If the callback function reallocates a new buffer, it should set this member to PDH_RETRY so that the dialog will try to load /// the buffer with the selected paths and call the callback function again. /// /// If some other error occurred, then the callback function should return the appropriate PDH error status value. /// public Win32Error CallBackStatus; /// /// /// Default detail level to show in the Detail level list if bHideDetailBox is FALSE. If /// bHideDetailBox is TRUE, the dialog uses this value to filter the displayed performance counters and objects. /// You can specify one of the following values: /// /// /// /// Detail level /// Meaning /// /// /// PERF_DETAIL_NOVICE /// A novice user can understand the counter data. /// /// /// PERF_DETAIL_ADVANCED /// The counter data is provided for advanced users. /// /// /// PERF_DETAIL_EXPERT /// The counter data is provided for expert users. /// /// /// PERF_DETAIL_WIZARD /// The counter data is provided for system designers. /// /// /// public PERF_DETAIL dwDefaultDetailLevel; /// /// Pointer to a null-terminated string that specifies the optional caption to display in the caption bar of the dialog /// box. If this member is NULL, the caption will be Browse Performance Counters. /// [MarshalAs(UnmanagedType.LPTStr)] public string szDialogBoxCaption; } /// /// The PDH_COUNTER_INFO structure contains information describing the properties of a counter. This information also includes /// the counter path. /// /// /// When you allocate memory for this structure, allocate enough memory for the member strings, such as szCounterName, that /// are appended to the end of this structure. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_counter_info_a typedef struct _PDH_COUNTER_INFO_A { DWORD // dwLength; DWORD dwType; DWORD CVersion; DWORD CStatus; LONG lScale; LONG lDefaultScale; DWORD_PTR dwUserData; DWORD_PTR // dwQueryUserData; LPSTR szFullPath; union { PDH_DATA_ITEM_PATH_ELEMENTS_A DataItemPath; PDH_COUNTER_PATH_ELEMENTS_A CounterPath; // struct { LPSTR szMachineName; LPSTR szObjectName; LPSTR szInstanceName; LPSTR szParentInstance; DWORD dwInstanceIndex; LPSTR // szCounterName; }; }; LPSTR szExplainText; DWORD DataBuffer[1]; } PDH_COUNTER_INFO_A, *PPDH_COUNTER_INFO_A; [PInvokeData("pdh.h", MSDNShortId = "c9ede50e-85de-4a68-b539-54285c2599cb")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_COUNTER_INFO { /// Size of the structure, including the appended strings, in bytes. public uint dwLength; /// /// Counter type. For a list of counter types, see the Counter Types section of the Windows Server 2003 Deployment Kit. The /// counter type constants are defined in Winperf.h. /// public CounterType dwType; /// Counter version information. Not used. public uint CVersion; /// /// Counter status that indicates if the counter value is valid. For a list of possible values, see Checking PDH Interface Return Values. /// public uint CStatus; /// /// Scale factor to use when computing the displayable value of the counter. The scale factor is a power of ten. The valid range /// of this parameter is PDH_MIN_SCALE (–7) (the returned value is the actual value times 10⁷) to PDH_MAX_SCALE (+7) (the /// returned value is the actual value times 10⁺⁷). A value of zero will set the scale to one, so that the actual value is returned /// public long lScale; /// Default scale factor as suggested by the counter's provider. public long lDefaultScale; /// The value passed in the dwUserData parameter when calling PdhAddCounter. public IntPtr dwUserData; /// The value passed in the dwUserData parameter when calling PdhOpenQuery. public IntPtr dwQueryUserData; /// Null-terminated string that specifies the full counter path. The string follows this structure in memory. public StrPtrAuto szFullPath; /// /// Null-terminated string that contains the name of the computer specified in the counter path. Is NULL, if the /// path does not specify a computer. The string follows this structure in memory. /// public StrPtrAuto szMachineName; /// /// Null-terminated string that contains the name of the performance object specified in the counter path. The string /// follows this structure in memory. /// public StrPtrAuto szObjectName; /// /// Null-terminated string that contains the name of the object instance specified in the counter path. Is NULL, if /// the path does not specify an instance. The string follows this structure in memory. /// public StrPtrAuto szInstanceName; /// /// Null-terminated string that contains the name of the parent instance specified in the counter path. Is NULL, if /// the path does not specify a parent instance. The string follows this structure in memory. /// public StrPtrAuto szParentInstance; /// Instance index specified in the counter path. Is 0, if the path does not specify an instance index. public uint dwInstanceIndex; /// Null-terminated string that contains the counter name. The string follows this structure in memory. public StrPtrAuto szCounterName; /// Help text that describes the counter. Is NULL if the source is a log file. public StrPtrAuto szExplainText; /// Start of the string data that is appended to the structure. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public uint[] DataBuffer; } /// The PDH_COUNTER_PATH_ELEMENTS structure contains the components of a counter path. /// /// This structure is used by PdhMakeCounterPath to create a counter path and by PdhParseCounterPath to parse a counter path. /// /// When you allocate memory for this structure, allocate enough memory for the member strings, such as szCounterName, that /// are appended to the end of this structure. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_counter_path_elements_a typedef struct // _PDH_COUNTER_PATH_ELEMENTS_A { LPSTR szMachineName; LPSTR szObjectName; LPSTR szInstanceName; LPSTR szParentInstance; DWORD // dwInstanceIndex; LPSTR szCounterName; } PDH_COUNTER_PATH_ELEMENTS_A, *PPDH_COUNTER_PATH_ELEMENTS_A; [PInvokeData("pdh.h", MSDNShortId = "ffa2a076-7267-406b-8eed-4a49504a7ad6")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_COUNTER_PATH_ELEMENTS { /// Pointer to a null-terminated string that specifies the computer name. [MarshalAs(UnmanagedType.LPTStr)] public string szMachineName; /// Pointer to a null-terminated string that specifies the object name. [MarshalAs(UnmanagedType.LPTStr)] public string szObjectName; /// Pointer to a null-terminated string that specifies the instance name. Can contain a wildcard character. [MarshalAs(UnmanagedType.LPTStr)] public string szInstanceName; /// Pointer to a null-terminated string that specifies the parent instance name. Can contain a wildcard character. [MarshalAs(UnmanagedType.LPTStr)] public string szParentInstance; /// Index used to uniquely identify duplicate instance names. public uint dwInstanceIndex; /// Pointer to a null-terminated string that specifies the counter name. [MarshalAs(UnmanagedType.LPTStr)] public string szCounterName; } /// The PDH_DATA_ITEM_PATH_ELEMENTS structure contains the path elements of a specific data item. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_data_item_path_elements_a typedef struct // _PDH_DATA_ITEM_PATH_ELEMENTS_A { LPSTR szMachineName; GUID ObjectGUID; DWORD dwItemId; LPSTR szInstanceName; } // PDH_DATA_ITEM_PATH_ELEMENTS_A, *PPDH_DATA_ITEM_PATH_ELEMENTS_A; [PInvokeData("pdh.h", MSDNShortId = "7d80d9ac-0123-4743-93a2-fa9d609d81b2")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_DATA_ITEM_PATH_ELEMENTS { /// Pointer to a null-terminated string that specifies the name of the computer where the data item resides. [MarshalAs(UnmanagedType.LPTStr)] public string szMachineName; /// GUID of the object where the data item resides. public Guid ObjectGUID; /// Identifier of the data item. public uint dwItemId; /// Pointer to a null-terminated string that specifies the name of the data item instance. [MarshalAs(UnmanagedType.LPTStr)] public string szInstanceName; } /// The PDH_FMT_COUNTERVALUE structure contains the computed value of the counter and its status. /// /// You specify the data type of the computed counter value when you call PdhGetFormattedCounterValue or /// PdhCalculateCounterFromRawValue to compute the counter's value. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_fmt_countervalue typedef struct _PDH_FMT_COUNTERVALUE { DWORD // CStatus; union { LONG longValue; double doubleValue; LONGLONG largeValue; LPCSTR AnsiStringValue; LPCWSTR WideStringValue; }; } // PDH_FMT_COUNTERVALUE, *PPDH_FMT_COUNTERVALUE; [PInvokeData("pdh.h", MSDNShortId = "68ccd722-94d2-4610-ba64-f51318f5436e")] [StructLayout(LayoutKind.Explicit, Size = 16)] public struct PDH_FMT_COUNTERVALUE { /// /// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or /// displaying its value. For a list of possible values, see Checking PDH Interface Return Values. /// [FieldOffset(0)] public Win32Error CStatus; /// The computed counter value as a LONG. [FieldOffset(8)] public int longValue; /// The computed counter value as a DOUBLE. [FieldOffset(8)] public double doubleValue; /// The computed counter value as a LONGLONG. [FieldOffset(8)] public long largeValue; /// The computed counter value as a LPCSTR. Not supported. [FieldOffset(8)] public StrPtrAnsi AnsiStringValue; /// The computed counter value as a LPCWSTR. Not supported. [FieldOffset(8)] public StrPtrUni WideStringValue; } /// The PDH_FMT_COUNTERVALUE_ITEM structure contains the instance name and formatted value of a counter. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_fmt_countervalue_item_a typedef struct // _PDH_FMT_COUNTERVALUE_ITEM_A { LPSTR szName; PDH_FMT_COUNTERVALUE FmtValue; } PDH_FMT_COUNTERVALUE_ITEM_A, *PPDH_FMT_COUNTERVALUE_ITEM_A; [PInvokeData("pdh.h", MSDNShortId = "d3bc6ad3-0cab-4843-ae1d-5f384948a1ea")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_FMT_COUNTERVALUE_ITEM { /// /// Pointer to a null-terminated string that specifies the instance name of the counter. The string is appended to the end of /// this structure. /// [MarshalAs(UnmanagedType.LPTStr)] public string szName; /// A PDH_FMT_COUNTERVALUE structure that contains the counter value of the instance. public PDH_FMT_COUNTERVALUE FmtValue; } /// Provides a handle to a PDH counter. [PInvokeData("pdh.h")] [StructLayout(LayoutKind.Sequential)] public struct PDH_HCOUNTER : IHandle { private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public PDH_HCOUNTER(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static PDH_HCOUNTER NULL => new PDH_HCOUNTER(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(PDH_HCOUNTER h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator PDH_HCOUNTER(IntPtr h) => new PDH_HCOUNTER(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(PDH_HCOUNTER h1, PDH_HCOUNTER h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(PDH_HCOUNTER h1, PDH_HCOUNTER h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is PDH_HCOUNTER h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Provides a handle to a PDH log. [PInvokeData("pdh.h")] [StructLayout(LayoutKind.Sequential)] public struct PDH_HLOG : IHandle { private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public PDH_HLOG(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static PDH_HLOG NULL => new PDH_HLOG(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(PDH_HLOG h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator PDH_HLOG(IntPtr h) => new PDH_HLOG(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(PDH_HLOG h1, PDH_HLOG h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(PDH_HLOG h1, PDH_HLOG h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is PDH_HLOG h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Provides a handle to a PDH query. [PInvokeData("pdh.h")] [StructLayout(LayoutKind.Sequential)] public struct PDH_HQUERY : IHandle { private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public PDH_HQUERY(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static PDH_HQUERY NULL => new PDH_HQUERY(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(PDH_HQUERY h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator PDH_HQUERY(IntPtr h) => new PDH_HQUERY(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(PDH_HQUERY h1, PDH_HQUERY h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(PDH_HQUERY h1, PDH_HQUERY h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is PDH_HQUERY h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// /// The PDH_RAW_COUNTER structure returns the data as it was collected from the counter provider. No translation, formatting, /// or other interpretation is performed on the data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_counter typedef struct _PDH_RAW_COUNTER { DWORD CStatus; // FILETIME TimeStamp; LONGLONG FirstValue; LONGLONG SecondValue; DWORD MultiCount; } PDH_RAW_COUNTER, *PPDH_RAW_COUNTER; [PInvokeData("pdh.h", MSDNShortId = "237a3c82-0ab4-45cb-bd93-2f308178c573")] [StructLayout(LayoutKind.Sequential)] public struct PDH_RAW_COUNTER { /// /// Counter status that indicates if the counter value is valid. Check this member before using the data in a calculation or /// displaying its value. For a list of possible values, see Checking PDH Interface Return Values. /// public Win32Error CStatus; /// Local time for when the data was collected, in FILETIME format. public FILETIME TimeStamp; /// First raw counter value. public long FirstValue; /// Second raw counter value. Rate counters require two values in order to compute a displayable value. public long SecondValue; /// /// If the counter type contains the PERF_MULTI_COUNTER flag, this member contains the additional counter data used in the /// calculation. For example, the PERF_100NSEC_MULTI_TIMER counter type contains the PERF_MULTI_COUNTER flag. /// public uint MultiCount; } /// The PDH_RAW_COUNTER_ITEM structure contains the instance name and raw value of a counter. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_counter_item_a typedef struct _PDH_RAW_COUNTER_ITEM_A { // LPSTR szName; PDH_RAW_COUNTER RawValue; } PDH_RAW_COUNTER_ITEM_A, *PPDH_RAW_COUNTER_ITEM_A; [PInvokeData("pdh.h", MSDNShortId = "602e0d44-3551-4a26-a5b7-8f7015131f9a")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PDH_RAW_COUNTER_ITEM { /// /// Pointer to a null-terminated string that specifies the instance name of the counter. The string is appended to the end of /// this structure. /// [MarshalAs(UnmanagedType.LPTStr)] public string szName; /// A PDH_RAW_COUNTER structure that contains the raw counter value of the instance. public PDH_RAW_COUNTER RawValue; } /// The PDH_RAW_LOG_RECORD structure contains information about a binary trace log file record. // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_raw_log_record typedef struct _PDH_RAW_LOG_RECORD { DWORD // dwStructureSize; DWORD dwRecordType; DWORD dwItems; UCHAR RawBytes[1]; } PDH_RAW_LOG_RECORD, *PPDH_RAW_LOG_RECORD; [PInvokeData("pdh.h", MSDNShortId = "ae96515f-ea3f-4578-a249-fb8f41cdfa69")] [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwItems))] [StructLayout(LayoutKind.Sequential)] public struct PDH_RAW_LOG_RECORD { /// /// Size of this structure, in bytes. The size includes this structure and the RawBytes appended to the end of this structure. /// public uint dwStructureSize; /// /// Type of record. This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// PDH_LOG_TYPE_BINARY /// A binary trace format record /// /// /// PDH_LOG_TYPE_CSV /// A comma-separated-value format record /// /// /// PDH_LOG_TYPE_PERFMON /// A Perfmon format record /// /// /// PDH_LOG_TYPE_SQL /// A SQL format record /// /// /// PDH_LOG_TYPE_TSV /// A tab-separated-value format record /// /// /// public PDH_LOG_TYPE dwRecordType; /// Size of the RawBytes data. public uint dwItems; /// Binary record. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] RawBytes; } /// /// The PDH_STATISTICS structure contains the minimum, maximum, and mean values for an array of raw counters values. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_statistics typedef struct _PDH_STATISTICS { DWORD dwFormat; // DWORD count; PDH_FMT_COUNTERVALUE min; PDH_FMT_COUNTERVALUE max; PDH_FMT_COUNTERVALUE mean; } PDH_STATISTICS, *PPDH_STATISTICS; [PInvokeData("pdh.h", MSDNShortId = "a1daedfd-55f6-418e-b71f-8334cb628d98")] [StructLayout(LayoutKind.Sequential)] public struct PDH_STATISTICS { /// Format of the data. The format is specified in the dwFormat when calling PdhComputeCounterStatistics. public PDH_FMT dwFormat; /// Number of values in the array. public uint count; /// Minimum of the values. public PDH_FMT_COUNTERVALUE min; /// Maximum of the values. public PDH_FMT_COUNTERVALUE max; /// Mean of the values. public PDH_FMT_COUNTERVALUE mean; } /// /// The PDH_TIME_INFO structure contains information on time intervals as applied to the sampling of performance data. /// // https://docs.microsoft.com/en-us/windows/win32/api/pdh/ns-pdh-pdh_time_info typedef struct _PDH_TIME_INFO { LONGLONG StartTime; // LONGLONG EndTime; DWORD SampleCount; } PDH_TIME_INFO, *PPDH_TIME_INFO; [PInvokeData("pdh.h", MSDNShortId = "a747f288-8d6c-401c-a927-a61ffea3d423")] [StructLayout(LayoutKind.Sequential, Size = 24)] public struct PDH_TIME_INFO { /// Starting time of the sample interval, in local FILETIME format. public FILETIME StartTime; /// Ending time of the sample interval, in local FILETIME format. public FILETIME EndTime; /// Number of samples collected during the interval. public uint SampleCount; } /// Provides a for that is disposed using . public class SafePDH_HCOUNTER : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafePDH_HCOUNTER(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafePDH_HCOUNTER() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator PDH_HCOUNTER(SafePDH_HCOUNTER h) => h.handle; /// protected override bool InternalReleaseHandle() => PdhRemoveCounter(handle).Succeeded; } /// Provides a for that is disposed using . public class SafePDH_HLOG : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafePDH_HLOG(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafePDH_HLOG() : base() { } /// /// Gets or sets a value indicating whether to close the query associated with the specified log file handle on disposal. See the /// hQuery parameter of PdhOpenLog. /// public bool CloseAssocQueries { get; set; } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator PDH_HLOG(SafePDH_HLOG h) => h.handle; /// protected override bool InternalReleaseHandle() => PdhCloseLog(handle, CloseAssocQueries ? 1U : 0).Succeeded; } /// Provides a for that is disposed using . public class SafePDH_HQUERY : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafePDH_HQUERY(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafePDH_HQUERY() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator PDH_HQUERY(SafePDH_HQUERY h) => h.handle; /// protected override bool InternalReleaseHandle() => PdhCloseQuery(handle).Succeeded; } } }