From 9ccb53a452175e761078316284e954aa8d7b29de Mon Sep 17 00:00:00 2001 From: MichalPavlik Date: Mon, 27 Apr 2026 14:00:12 +0200 Subject: [PATCH 1/2] Removed WMI due to performance --- src/Framework/Utilities/ProcessExtensions.cs | 485 +----------------- .../ProcessExtensions_Tests.cs | 7 +- 2 files changed, 5 insertions(+), 487 deletions(-) diff --git a/src/Framework/Utilities/ProcessExtensions.cs b/src/Framework/Utilities/ProcessExtensions.cs index 15a9e592f91..104666a57f4 100644 --- a/src/Framework/Utilities/ProcessExtensions.cs +++ b/src/Framework/Utilities/ProcessExtensions.cs @@ -63,12 +63,7 @@ public static bool TryGetCommandLine(this Process? process, out string? commandL try { #if NET - if (NativeMethods.IsWindows) - { - commandLine = Windows.GetCommandLine(process.Id); - return true; - } - else if (NativeMethods.IsOSX || NativeMethods.IsBSD) + if (NativeMethods.IsOSX || NativeMethods.IsBSD) { commandLine = BSD.GetCommandLine(process.Id); return true; @@ -164,484 +159,6 @@ private static string ParseNullSeparatedArguments(ReadOnlySpan data, int m } #endif -#if NET - /// - /// Windows-specific command line retrieval via WMI COM interfaces. - /// Queries Win32_Process for the CommandLine property using IWbemLocator/IWbemServices. - /// - [SupportedOSPlatform("windows")] - private static class Windows - { - // WMI COM interface GUIDs - private static readonly Guid CLSID_WbemLocator = new Guid("4590F811-1D3A-11D0-891F-00AA004B2E24"); - private static readonly Guid IID_IWbemLocator = new Guid("DC12A687-737F-11CF-884D-00AA004B2E24"); - - // WBEM status codes - private const int WBEM_S_NO_ERROR = 0; - private const int WBEM_S_FALSE = 1; // No more objects in enumeration - private const int WBEM_FLAG_FORWARD_ONLY = 0x00000020; - private const int WBEM_FLAG_RETURN_IMMEDIATELY = 0x00000010; - private const int WBEM_INFINITE = -1; - - - // RPC authentication/impersonation constants (used by CoInitializeSecurity and CoSetProxyBlanket) - private const int RPC_C_AUTHN_LEVEL_DEFAULT = 0; - private const int RPC_C_AUTHN_LEVEL_CALL = 3; - private const int RPC_C_IMP_LEVEL_IMPERSONATE = 3; - private const int RPC_C_AUTHN_WINNT = 10; - private const int RPC_C_AUTHZ_NONE = 0; - private const int EOAC_NONE = 0; - - // CoCreateInstance: in-process server - private const int CLSCTX_INPROC_SERVER = 1; - - // HRESULTs for conditions that are not fatal failures - private const int RPC_E_TOO_LATE = unchecked((int)0x80010119); // CoInitializeSecurity already called - - [DllImport("ole32.dll")] - private static extern int CoInitializeEx(IntPtr pvReserved, int dwCoInit); - - [DllImport("ole32.dll")] - private static extern int CoInitializeSecurity( - IntPtr pSecDesc, - int cAuthSvc, - IntPtr asAuthSvc, - IntPtr pReserved, - int dwAuthnLevel, - int dwImpLevel, - IntPtr pAuthList, - int dwCapabilities, - IntPtr pReserved3); - - [DllImport("ole32.dll")] - private static extern int CoCreateInstance( - ref Guid rclsid, - IntPtr pUnkOuter, - int dwClsContext, - ref Guid riid, - [MarshalAs(UnmanagedType.Interface)] out IWbemLocator ppv); - - [DllImport("ole32.dll")] - private static extern int CoSetProxyBlanket( - [MarshalAs(UnmanagedType.IUnknown)] object pProxy, - int dwAuthnSvc, - int dwAuthzSvc, - IntPtr pServerPrincName, - int dwAuthnLevel, - int dwImpLevel, - IntPtr pAuthInfo, - int dwCapabilities); - - [ComImport] - [Guid("DC12A687-737F-11CF-884D-00AA004B2E24")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - private interface IWbemLocator - { - [PreserveSig] - int ConnectServer( - [MarshalAs(UnmanagedType.BStr)] string strNetworkResource, - [MarshalAs(UnmanagedType.BStr)] string? strUser, - [MarshalAs(UnmanagedType.BStr)] string? strPassword, - [MarshalAs(UnmanagedType.BStr)] string? strLocale, - int lSecurityFlags, - [MarshalAs(UnmanagedType.BStr)] string? strAuthority, - IntPtr pCtx, - [MarshalAs(UnmanagedType.Interface)] out IWbemServices ppNamespace); - } - - [Guid("44ACA674-E8FC-11D0-A07C-00C04FB68820")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [ComImport] - internal interface IWbemContext - { - [PreserveSig] - int Clone([MarshalAs(UnmanagedType.Interface)] out IWbemContext ppNewCopy); - - [PreserveSig] - int GetNames(int lFlags, IntPtr pNames); - - [PreserveSig] - int BeginEnumeration(int lFlags); - - [PreserveSig] - int Next(int lFlags, [MarshalAs(UnmanagedType.BStr)] out string pstrName, IntPtr pValue); - - [PreserveSig] - int EndEnumeration(); - - [PreserveSig] - int SetValue([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags, IntPtr pValue); - - [PreserveSig] - int GetValue([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags, IntPtr pValue); - - [PreserveSig] - int DeleteValue([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags); - - [PreserveSig] - int DeleteAll(); - } - - [ComImport] - [Guid("9556DC99-828C-11CF-A37E-00AA003240C7")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - private interface IWbemServices - { - [PreserveSig] - int OpenNamespace( - [MarshalAs(UnmanagedType.BStr)] string strNamespace, - int lFlags, - IntPtr pCtx, - IntPtr ppWorkingNamespace, - IntPtr ppResult); - - [PreserveSig] - int CancelAsyncCall(IntPtr pSink); - - [PreserveSig] - int QueryObjectSink(int lFlags, IntPtr ppResponseHandler); - - [PreserveSig] - int GetObject( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - int lFlags, - IntPtr pCtx, - IntPtr ppObject, - IntPtr ppCallResult); - - [PreserveSig] - int GetObjectAsync( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int PutClass(IntPtr pObject, int lFlags, IntPtr pCtx, IntPtr ppCallResult); - - [PreserveSig] - int PutClassAsync(IntPtr pObject, int lFlags, IntPtr pCtx, IntPtr pResponseHandler); - - [PreserveSig] - int DeleteClass( - [MarshalAs(UnmanagedType.BStr)] string strClass, - int lFlags, - IntPtr pCtx, - IntPtr ppCallResult); - - [PreserveSig] - int DeleteClassAsync( - [MarshalAs(UnmanagedType.BStr)] string strClass, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int CreateClassEnum( - [MarshalAs(UnmanagedType.BStr)] string strSuperclass, - int lFlags, - IntPtr pCtx, - [MarshalAs(UnmanagedType.Interface)] out IEnumWbemClassObject ppEnum); - - [PreserveSig] - int CreateClassEnumAsync( - [MarshalAs(UnmanagedType.BStr)] string strSuperclass, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int PutInstance(IntPtr pInst, int lFlags, IntPtr pCtx, IntPtr ppCallResult); - - [PreserveSig] - int PutInstanceAsync(IntPtr pInst, int lFlags, IntPtr pCtx, IntPtr pResponseHandler); - - [PreserveSig] - int DeleteInstance( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - int lFlags, - IntPtr pCtx, - IntPtr ppCallResult); - - [PreserveSig] - int DeleteInstanceAsync( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int CreateInstanceEnum( - [MarshalAs(UnmanagedType.BStr)] string strFilter, - int lFlags, - IntPtr pCtx, - [MarshalAs(UnmanagedType.Interface)] out IEnumWbemClassObject ppEnum); - - [PreserveSig] - int CreateInstanceEnumAsync( - [MarshalAs(UnmanagedType.BStr)] string strFilter, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int ExecQuery( - [In][MarshalAs(UnmanagedType.BStr)] string strQueryLanguage, - [In][MarshalAs(UnmanagedType.BStr)] string strQuery, - [In] int lFlags, - [In] IWbemContext? pCtx, - [MarshalAs(UnmanagedType.Interface)] out IEnumWbemClassObject ppEnum); - - [PreserveSig] - int ExecQueryAsync( - [MarshalAs(UnmanagedType.BStr)] string strQueryLanguage, - [MarshalAs(UnmanagedType.BStr)] string strQuery, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int ExecNotificationQuery( - [MarshalAs(UnmanagedType.BStr)] string strQueryLanguage, - [MarshalAs(UnmanagedType.BStr)] string strQuery, - int lFlags, - IntPtr pCtx, - IntPtr ppEnum); - - [PreserveSig] - int ExecNotificationQueryAsync( - [MarshalAs(UnmanagedType.BStr)] string strQueryLanguage, - [MarshalAs(UnmanagedType.BStr)] string strQuery, - int lFlags, - IntPtr pCtx, - IntPtr pResponseHandler); - - [PreserveSig] - int ExecMethod( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - [MarshalAs(UnmanagedType.BStr)] string strMethodName, - int lFlags, - IntPtr pCtx, - IntPtr pInParams, - IntPtr ppOutParams, - IntPtr ppCallResult); - - [PreserveSig] - int ExecMethodAsync( - [MarshalAs(UnmanagedType.BStr)] string strObjectPath, - [MarshalAs(UnmanagedType.BStr)] string strMethodName, - int lFlags, - IntPtr pCtx, - IntPtr pInParams, - IntPtr pResponseHandler); - } - - [ComImport] - [Guid("027947E1-D731-11CE-A357-000000000001")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - private interface IEnumWbemClassObject - { - [PreserveSig] - int Reset(); - - [PreserveSig] - int Next( - int lTimeout, - uint uCount, - [MarshalAs(UnmanagedType.Interface)] out IWbemClassObject apObjects, - out uint puReturned); - - [PreserveSig] - int NextAsync(uint uCount, IntPtr pSink); - - [PreserveSig] - int Clone([MarshalAs(UnmanagedType.Interface)] out IEnumWbemClassObject ppEnum); - - [PreserveSig] - int Skip(int lTimeout, uint nCount); - } - - [ComImport] - [Guid("DC12A681-737F-11CF-884D-00AA004B2E24")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - private interface IWbemClassObject - { - [PreserveSig] - int GetQualifierSet(IntPtr ppQualSet); - - [PreserveSig] - int Get( - [MarshalAs(UnmanagedType.LPWStr)] string wszName, - int lFlags, - ref object pVal, - IntPtr pType, - IntPtr plFlavor); - - [PreserveSig] - int Put([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags, ref object pVal, int type); - - [PreserveSig] - int Delete([MarshalAs(UnmanagedType.LPWStr)] string wszName); - - [PreserveSig] - int GetNames([MarshalAs(UnmanagedType.LPWStr)] string wszQualifierName, int lFlags, ref object pQualifierVal, IntPtr pNames); - - [PreserveSig] - int BeginEnumeration(int lEnumFlags); - - [PreserveSig] - int Next(int lFlags, [MarshalAs(UnmanagedType.BStr)] out string strName, ref object pVal, IntPtr pType, IntPtr plFlavor); - - [PreserveSig] - int EndEnumeration(); - - [PreserveSig] - int GetPropertyQualifierSet([MarshalAs(UnmanagedType.LPWStr)] string wszProperty, IntPtr ppQualSet); - - [PreserveSig] - int Clone([MarshalAs(UnmanagedType.Interface)] out IWbemClassObject ppCopy); - - [PreserveSig] - int GetObjectText(int lFlags, [MarshalAs(UnmanagedType.BStr)] out string pstrObjectText); - - [PreserveSig] - int SpawnDerivedClass(int lFlags, IntPtr ppNewClass); - - [PreserveSig] - int SpawnInstance(int lFlags, IntPtr ppNewInstance); - - [PreserveSig] - int CompareTo(int lFlags, IntPtr pCompareTo); - - [PreserveSig] - int GetPropertyOrigin([MarshalAs(UnmanagedType.LPWStr)] string wszName, [MarshalAs(UnmanagedType.BStr)] out string pstrClassName); - - [PreserveSig] - int InheritsFrom([MarshalAs(UnmanagedType.LPWStr)] string strAncestor); - - [PreserveSig] - int GetMethod([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags, IntPtr ppInSignature, IntPtr ppOutSignature); - - [PreserveSig] - int PutMethod([MarshalAs(UnmanagedType.LPWStr)] string wszName, int lFlags, IntPtr pInSignature, IntPtr pOutSignature); - - [PreserveSig] - int DeleteMethod([MarshalAs(UnmanagedType.LPWStr)] string wszName); - - [PreserveSig] - int BeginMethodEnumeration(int lEnumFlags); - - [PreserveSig] - int NextMethod(int lFlags, [MarshalAs(UnmanagedType.BStr)] out string pstrName, IntPtr ppInSignature, IntPtr ppOutSignature); - - [PreserveSig] - int EndMethodEnumeration(); - - [PreserveSig] - int GetMethodQualifierSet([MarshalAs(UnmanagedType.LPWStr)] string wszMethod, IntPtr ppQualSet); - - [PreserveSig] - int GetMethodOrigin([MarshalAs(UnmanagedType.LPWStr)] string wszMethodName, [MarshalAs(UnmanagedType.BStr)] out string pstrClassName); - } - - - /// - /// Retrieves the command line for a process by querying WMI Win32_Process via COM. - /// Runs: SELECT CommandLine FROM Win32_Process WHERE ProcessId='' - /// - internal static string? GetCommandLine(int processId) - { - int hr = CoInitializeSecurity( - IntPtr.Zero, - -1, - IntPtr.Zero, - IntPtr.Zero, - RPC_C_AUTHN_LEVEL_DEFAULT, - RPC_C_IMP_LEVEL_IMPERSONATE, - IntPtr.Zero, - EOAC_NONE, - IntPtr.Zero); - // RPC_E_TOO_LATE (0x80010119) means another call already set security — not fatal. - if (hr != WBEM_S_NO_ERROR && hr != RPC_E_TOO_LATE) - { - throw new InvalidOperationException( - $"WMI CoInitializeSecurity failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - Guid clsid = CLSID_WbemLocator; - Guid iid = IID_IWbemLocator; - hr = CoCreateInstance(ref clsid, IntPtr.Zero, CLSCTX_INPROC_SERVER, ref iid, out IWbemLocator locator); - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI CoCreateInstance failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - hr = locator.ConnectServer( - @"ROOT\CIMV2", - strUser: null, strPassword: null, strLocale: null, - lSecurityFlags: 0, strAuthority: null, - pCtx: IntPtr.Zero, - out IWbemServices services); - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI ConnectServer failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - hr = CoSetProxyBlanket( - services, - RPC_C_AUTHN_WINNT, - RPC_C_AUTHZ_NONE, - IntPtr.Zero, - RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, - IntPtr.Zero, - EOAC_NONE); - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI CoSetProxyBlanket failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - string query = $"SELECT CommandLine FROM Win32_Process WHERE ProcessId='{processId}'"; - hr = services.ExecQuery( - "WQL", - query, - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - null, - out IEnumWbemClassObject enumerator); - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI ExecQuery failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - hr = enumerator.Next(WBEM_INFINITE, 1, out IWbemClassObject obj, out uint returned); - if (hr == WBEM_S_FALSE || returned == 0) - { - // No matching process found. - return null; - } - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI IEnumWbemClassObject.Next failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - object val = null!; - hr = obj.Get("CommandLine", 0, ref val, IntPtr.Zero, IntPtr.Zero); - if (hr != WBEM_S_NO_ERROR) - { - throw new InvalidOperationException( - $"WMI IWbemClassObject.Get(\"CommandLine\") failed for PID {processId}. HRESULT: 0x{hr:X8}"); - } - - return val as string; - } - } -#endif - #if NET /// /// Linux-specific command line retrieval via /proc/{pid}/cmdline. diff --git a/src/Utilities.UnitTests/ProcessExtensions_Tests.cs b/src/Utilities.UnitTests/ProcessExtensions_Tests.cs index 7f4bbc61950..0b3eb198935 100644 --- a/src/Utilities.UnitTests/ProcessExtensions_Tests.cs +++ b/src/Utilities.UnitTests/ProcessExtensions_Tests.cs @@ -64,7 +64,8 @@ public async Task TryGetCommandLine_RunningProcess_ContainsExpectedExecutable() if (NativeMethodsShared.IsWindows) { - commandLine.ShouldContain("ping", Case.Insensitive); + // Windows is treated as an unsupported OS for command-line retrieval; commandLine is null. + commandLine.ShouldBeNull(); } else { @@ -94,8 +95,8 @@ public async Task TryGetCommandLine_RunningProcess_ContainsArguments() if (NativeMethodsShared.IsWindows) { - // ping -n 31 127.0.0.1 – at minimum "127.0.0.1" or "31" should appear - commandLine.ShouldMatch(@"(127\.0\.0\.1|31)"); + // Windows is treated as an unsupported OS for command-line retrieval; commandLine is null. + commandLine.ShouldBeNull(); } else { From c7c5f5ea028cf84e57919aa9798eb5e40050b043 Mon Sep 17 00:00:00 2001 From: Michal Pavlik Date: Tue, 28 Apr 2026 11:45:41 +0200 Subject: [PATCH 2/2] Updated version --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index af333cfdead..e5338d72c7e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,7 +3,7 @@ - 18.6.3release + 18.6.4release servicing 18.5.0-preview-26126-01 15.1.0.0