From e35d79695acfba0cf0624e368f331fe8b4ea724f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 10:45:10 +0200 Subject: [PATCH 1/6] Fix get process architecture --- .../common/System/ProcessHelper.cs | 12 +++- .../net451/System/ProcessHelper.cs | 65 ++++++++++++++----- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/System/ProcessHelper.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/System/ProcessHelper.cs index 16eb766281..f64e40a410 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/System/ProcessHelper.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/System/ProcessHelper.cs @@ -23,6 +23,7 @@ namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; public partial class ProcessHelper : IProcessHelper { private static readonly string Arm = "arm"; + private readonly Process _currentProcess = Process.GetCurrentProcess(); /// public object LaunchProcess(string processPath, string arguments, string workingDirectory, IDictionary envVariables, Action errorCallback, Action exitCallBack, Action outputCallBack) @@ -139,7 +140,7 @@ void InitializeAndStart() /// public string GetCurrentProcessFileName() { - return Process.GetCurrentProcess().MainModule.FileName; + return _currentProcess.MainModule.FileName; } /// @@ -151,12 +152,17 @@ public string GetTestEngineDirectory() /// public int GetCurrentProcessId() { - return Process.GetCurrentProcess().Id; + return _currentProcess.Id; } /// public string GetProcessName(int processId) { + if (processId == _currentProcess.Id) + { + return _currentProcess.ProcessName; + } + return Process.GetProcessById(processId).ProcessName; } @@ -184,7 +190,7 @@ public void SetExitCallback(int processId, Action callbackAction) { try { - var process = Process.GetProcessById(processId); + var process = processId == _currentProcess.Id ? _currentProcess : Process.GetProcessById(processId); process.EnableRaisingEvents = true; process.Exited += (sender, args) => callbackAction?.Invoke(sender); } diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs index 1dc87a5e3f..3b963f43c4 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs @@ -23,37 +23,71 @@ public string GetCurrentProcessLocation() => Path.GetDirectoryName(GetCurrentProcessFileName()); /// - public IntPtr GetProcessHandle(int processId) - => Process.GetProcessById(processId).Handle; + public IntPtr GetProcessHandle(int processId) => + processId == _currentProcess.Id + ? _currentProcess.Handle + : Process.GetProcessById(processId).Handle; /// public PlatformArchitecture GetCurrentProcessArchitecture() - => _currentProcessArchitecture ??= GetProcessArchitecture(Process.GetCurrentProcess().Id); - + { + _currentProcessArchitecture ??= GetProcessArchitecture(_currentProcess.Id); + return _currentProcessArchitecture.Value; + } public PlatformArchitecture GetProcessArchitecture(int processId) - => IntPtr.Size == 8 - ? IsArm64(processId) - ? PlatformArchitecture.ARM64 - : PlatformArchitecture.X64 - : PlatformArchitecture.X86; - - private static bool IsArm64(int processId) { try { - var process = Process.GetProcessById(processId); + if (_currentProcess.Id == processId) + { + // If we already cached the current process architecture, no need to figure it out again. + if (_currentProcessArchitecture != null) + { + return _currentProcessArchitecture.Value; + } + + // When this is current process, we can just check if IntPointer size to get if we are 64-bit or 32-bit. + // When it is 32-bit we can just return, if it is 64-bit we need to clarify if x64 or arm64. + if (IntPtr.Size == 4) + { + return PlatformArchitecture.X86; + } + } + + + + // If the current process is 64-bit, or this is any remote process, we need to query it via native api. + var process = processId == _currentProcess.Id ? _currentProcess : Process.GetProcessById(processId); if (!NativeMethods.IsWow64Process2(process.Handle, out ushort processMachine, out ushort nativeMachine)) { throw new Win32Exception(); } - // If processMachine is IMAGE_FILE_MACHINE_UNKNOWN mean that we're not running using WOW64 x86 emulation. + if (processMachine != NativeMethods.IMAGE_FILE_MACHINE_UNKNOWN) + { + // The process is running using WOW64, which suggests it is 32-bit (or any of the other machines, that we cannot + // handle, so we just assume x86). + return PlatformArchitecture.X86; + } + + // If processMachine is IMAGE_FILE_MACHINE_UNKNOWN mean that we're not running using WOW64 emulation. // If nativeMachine is IMAGE_FILE_MACHINE_ARM64 mean that we're running on ARM64 architecture device. if (processMachine == NativeMethods.IMAGE_FILE_MACHINE_UNKNOWN && nativeMachine == NativeMethods.IMAGE_FILE_MACHINE_ARM64) { // To distinguish between ARM64 and x64 emulated on ARM64 we check the PE header of the current running executable. - return IsArm64Executable(process.MainModule.FileName); + if (IsArm64Executable(process.MainModule.FileName)) + { + return PlatformArchitecture.ARM64; + } + else + { + return PlatformArchitecture.X64; + } + } + else + { + return PlatformArchitecture.X64; } } catch @@ -66,7 +100,8 @@ private static bool IsArm64(int processId) // a MissedMethodException. } - return false; + // In case of error just return the current process architecture. + return GetCurrentProcessArchitecture(); } private static bool IsArm64Executable(string path) From 156ccaf005a259f12ba1d29cf6401bd3aa96f1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 11:27:31 +0200 Subject: [PATCH 2/6] Fix getting process architecture, when it is not the current process --- .../common/NativeMethods.cs | 7 +++ .../net451/System/PlatformEnvironment.cs | 4 +- .../net451/System/ProcessHelper.cs | 61 +++++++++++++------ 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs index 6ffd54aa10..e6627ab1c9 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs @@ -15,6 +15,13 @@ internal class NativeMethods [DllImport("kernel32.dll", SetLastError = true)] public static extern bool IsWow64Process2(IntPtr process, out ushort processMachine, out ushort nativeMachine); + + // A pointer to a value that is set to TRUE if the process is running under WOW64. + // If the process is running under 32-bit Windows, the value is set to FALSE. + // If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE. + [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process); } #endif diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs index b5df2faab5..3e26150533 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/PlatformEnvironment.cs @@ -16,12 +16,14 @@ namespace Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; /// public class PlatformEnvironment : IEnvironment { + private PlatformArchitecture? _architecture; + /// public PlatformArchitecture Architecture { get { - return Environment.Is64BitOperatingSystem + return _architecture ??= Environment.Is64BitOperatingSystem ? IsArm64() ? PlatformArchitecture.ARM64 : PlatformArchitecture.X64 diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs index 3b963f43c4..9e361e1beb 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs @@ -37,28 +37,26 @@ public PlatformArchitecture GetCurrentProcessArchitecture() public PlatformArchitecture GetProcessArchitecture(int processId) { - try + if (_currentProcess.Id == processId) { - if (_currentProcess.Id == processId) + // If we already cached the current process architecture, no need to figure it out again. + if (_currentProcessArchitecture != null) { - // If we already cached the current process architecture, no need to figure it out again. - if (_currentProcessArchitecture != null) - { - return _currentProcessArchitecture.Value; - } - - // When this is current process, we can just check if IntPointer size to get if we are 64-bit or 32-bit. - // When it is 32-bit we can just return, if it is 64-bit we need to clarify if x64 or arm64. - if (IntPtr.Size == 4) - { - return PlatformArchitecture.X86; - } + return _currentProcessArchitecture.Value; } + // When this is current process, we can just check if IntPointer size to get if we are 64-bit or 32-bit. + // When it is 32-bit we can just return, if it is 64-bit we need to clarify if x64 or arm64. + if (IntPtr.Size == 4) + { + return PlatformArchitecture.X86; + } + } - - // If the current process is 64-bit, or this is any remote process, we need to query it via native api. - var process = processId == _currentProcess.Id ? _currentProcess : Process.GetProcessById(processId); + // If the current process is 64-bit, or this is any remote process, we need to query it via native api. + var process = processId == _currentProcess.Id ? _currentProcess : Process.GetProcessById(processId); + try + { if (!NativeMethods.IsWow64Process2(process.Handle, out ushort processMachine, out ushort nativeMachine)) { throw new Win32Exception(); @@ -98,10 +96,33 @@ public PlatformArchitecture GetProcessArchitecture(int processId) // we loaded runner version of Microsoft.TestPlatform.PlatformAbstractions but newer version Microsoft.TestPlatform.ObjectModel(the one close // to the test container) and the old PlatformAbstractions doesn't contain the methods expected by the new ObjectModel throwing // a MissedMethodException. - } - // In case of error just return the current process architecture. - return GetCurrentProcessArchitecture(); + try + { + if (!Environment.Is64BitOperatingSystem) + { + // When we know this is not 64-bit operating system, then all processes are running as 32-bit, both + // the current process and other processes. + return PlatformArchitecture.X86; + } + + var isWow64Process = NativeMethods.IsWow64Process(process.Handle, out var isWow64); + if (!isWow64Process) + { + // Do nothing we cannot log errors here. + } + + // The process is running using WOW64, which suggests it is 32-bit (or any of the other machines, that we cannot + // handle, so we just assume x86). If it is not wow, we assume x64, because we failed the call to more advanced api + // that can tell us if this is arm64, so we are probably on older version of OS which is x64. + // We could call PlatformArchitecture.Architecture, but that uses the same api that we just failed to invoke. + return isWow64 ? PlatformArchitecture.X86 : PlatformArchitecture.X64; + } + catch + { + // Do nothing we cannot log errors here. + } + } } private static bool IsArm64Executable(string path) From 049ebbf53074b4c43345adbe712f93673f18368d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 11:34:37 +0200 Subject: [PATCH 3/6] Remove extra class --- .../NativeMethodsHelper.cs | 41 ------------------- .../common/NativeMethods.cs | 2 +- 2 files changed, 1 insertion(+), 42 deletions(-) delete mode 100644 src/Microsoft.TestPlatform.Extensions.BlameDataCollector/NativeMethodsHelper.cs diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/NativeMethodsHelper.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/NativeMethodsHelper.cs deleted file mode 100644 index dc0d78fd81..0000000000 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/NativeMethodsHelper.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; - -using Microsoft.VisualStudio.TestPlatform.ObjectModel; - -namespace Microsoft.TestPlatform.Extensions.BlameDataCollector; - -public class NativeMethodsHelper : INativeMethodsHelper -{ - /// - /// Returns if a process is 64 bit process - /// - /// Process Handle - /// Bool for Is64Bit - public bool Is64Bit(IntPtr processHandle) - { - // WOW64 is the x86 emulator that allows 32 bit Windows - based applications to run seamlessly on 64 bit Windows. - - // If the function succeeds, the return value is a nonzero value. - var isWow64Process = IsWow64Process(processHandle, out var isWow64); - if (!isWow64Process) - { - EqtTrace.Verbose("NativeMethodsHelper: The call to IsWow64Process failed."); - } - - var is64Bit = !isWow64; - EqtTrace.Verbose($"NativeMethodsHelper: is Wow64Process: {isWow64Process} is 64bit: {is64Bit}."); - - return is64Bit; - } - - // A pointer to a value that is set to TRUE if the process is running under WOW64. - // If the process is running under 32-bit Windows, the value is set to FALSE. - // If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE. - [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process); -} diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs index e6627ab1c9..5b94ab94eb 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs @@ -14,7 +14,7 @@ internal class NativeMethods public const ushort IMAGE_FILE_MACHINE_UNKNOWN = 0; [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool IsWow64Process2(IntPtr process, out ushort processMachine, out ushort nativeMachine); + public static extern bool IsWow64Process2([In] IntPtr process, [Out] out ushort processMachine, [Out] out ushort nativeMachine); // A pointer to a value that is set to TRUE if the process is running under WOW64. // If the process is running under 32-bit Windows, the value is set to FALSE. From dc0b8caa1a36d1c0559accccea70dd4d79b4d3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 11:55:05 +0200 Subject: [PATCH 4/6] One more fallback to x64 --- .../net451/System/ProcessHelper.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs index 9e361e1beb..411069c36f 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs @@ -97,15 +97,15 @@ public PlatformArchitecture GetProcessArchitecture(int processId) // to the test container) and the old PlatformAbstractions doesn't contain the methods expected by the new ObjectModel throwing // a MissedMethodException. - try + if (!Environment.Is64BitOperatingSystem) { - if (!Environment.Is64BitOperatingSystem) - { - // When we know this is not 64-bit operating system, then all processes are running as 32-bit, both - // the current process and other processes. - return PlatformArchitecture.X86; - } + // When we know this is not 64-bit operating system, then all processes are running as 32-bit, both + // the current process and other processes. + return PlatformArchitecture.X86; + } + try + { var isWow64Process = NativeMethods.IsWow64Process(process.Handle, out var isWow64); if (!isWow64Process) { @@ -120,7 +120,8 @@ public PlatformArchitecture GetProcessArchitecture(int processId) } catch { - // Do nothing we cannot log errors here. + // We are on 64-bit system, let's assume x64 when we fail to determine the value. + return PlatformArchitecture.X64; } } } From 287bcba42a453d81b945afcc628c4218ac384075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 12:56:11 +0200 Subject: [PATCH 5/6] Apply review comments --- .../common/NativeMethods.cs | 3 ++- .../net451/System/ProcessHelper.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs index 5b94ab94eb..680aae6d57 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/common/NativeMethods.cs @@ -13,7 +13,8 @@ internal class NativeMethods public const ushort IMAGE_FILE_MACHINE_ARM64 = 0xAA64; public const ushort IMAGE_FILE_MACHINE_UNKNOWN = 0; - [DllImport("kernel32.dll", SetLastError = true)] + [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWow64Process2([In] IntPtr process, [Out] out ushort processMachine, [Out] out ushort nativeMachine); // A pointer to a value that is set to TRUE if the process is running under WOW64. diff --git a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs index 411069c36f..de79250b99 100644 --- a/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs +++ b/src/Microsoft.TestPlatform.PlatformAbstractions/net451/System/ProcessHelper.cs @@ -40,7 +40,7 @@ public PlatformArchitecture GetProcessArchitecture(int processId) if (_currentProcess.Id == processId) { // If we already cached the current process architecture, no need to figure it out again. - if (_currentProcessArchitecture != null) + if (_currentProcessArchitecture is not null) { return _currentProcessArchitecture.Value; } From 0c2d602323e859ad28aeac778757b3fd3e86cf4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jun 2022 15:59:25 +0200 Subject: [PATCH 6/6] Fix --- .../ProcDumpDumper.cs | 4 ++-- .../PublicAPI/PublicAPI.Shipped.txt | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcDumpDumper.cs b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcDumpDumper.cs index f5767f1af8..b10f64cc79 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcDumpDumper.cs +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/ProcDumpDumper.cs @@ -37,11 +37,11 @@ public class ProcDumpDumper : ICrashDumper, IHangDumper private string? _outputFilePrefix; public ProcDumpDumper() - : this(new ProcessHelper(), new FileHelper(), new PlatformEnvironment(), new NativeMethodsHelper()) + : this(new ProcessHelper(), new FileHelper(), new PlatformEnvironment()) { } - public ProcDumpDumper(IProcessHelper processHelper, IFileHelper fileHelper, IEnvironment environment, INativeMethodsHelper? nativeMethodsHelper) + public ProcDumpDumper(IProcessHelper processHelper, IFileHelper fileHelper, IEnvironment environment) { _processHelper = processHelper; _fileHelper = fileHelper; diff --git a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/PublicAPI/PublicAPI.Shipped.txt b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/PublicAPI/PublicAPI.Shipped.txt index c9f6f04366..a61100a66f 100644 --- a/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Microsoft.TestPlatform.Extensions.BlameDataCollector/PublicAPI/PublicAPI.Shipped.txt @@ -60,9 +60,6 @@ Microsoft.TestPlatform.Extensions.BlameDataCollector.IProcessDumpUtility.DetachF Microsoft.TestPlatform.Extensions.BlameDataCollector.IProcessDumpUtility.GetDumpFiles(bool warnOnNoDumpFiles, bool processCrashed) -> System.Collections.Generic.IEnumerable! Microsoft.TestPlatform.Extensions.BlameDataCollector.IProcessDumpUtility.StartHangBasedProcessDump(int processId, string! testResultsDirectory, bool isFullDump, string! targetFramework, System.Action? logWarning = null) -> void Microsoft.TestPlatform.Extensions.BlameDataCollector.IProcessDumpUtility.StartTriggerBasedProcessDump(int processId, string! testResultsDirectory, bool isFullDump, string! targetFramework, bool collectAlways, System.Action! logWarning) -> void -Microsoft.TestPlatform.Extensions.BlameDataCollector.NativeMethodsHelper -Microsoft.TestPlatform.Extensions.BlameDataCollector.NativeMethodsHelper.Is64Bit(System.IntPtr processHandle) -> bool -Microsoft.TestPlatform.Extensions.BlameDataCollector.NativeMethodsHelper.NativeMethodsHelper() -> void Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpArgsBuilder Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpArgsBuilder.BuildHangBasedProcDumpArgs(int processId, string! filename, bool isFullDump) -> string! Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpArgsBuilder.BuildTriggerBasedProcDumpArgs(int processId, string! filename, System.Collections.Generic.IEnumerable! procDumpExceptionsList, bool isFullDump) -> string! @@ -74,7 +71,7 @@ Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.Dump(int pro Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.GetDumpFiles(bool processCrashed) -> System.Collections.Generic.IEnumerable! Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.OutputReceivedCallback.get -> System.Action! Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.ProcDumpDumper() -> void -Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.ProcDumpDumper(Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IProcessHelper! processHelper, Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces.IFileHelper! fileHelper, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment! environment, Microsoft.TestPlatform.Extensions.BlameDataCollector.INativeMethodsHelper? nativeMethodsHelper) -> void +Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.ProcDumpDumper(Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IProcessHelper! processHelper, Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces.IFileHelper! fileHelper, Microsoft.VisualStudio.TestPlatform.PlatformAbstractions.Interfaces.IEnvironment! environment) -> void Microsoft.TestPlatform.Extensions.BlameDataCollector.ProcDumpDumper.WaitForDumpToFinish() -> void Microsoft.TestPlatform.Extensions.BlameDataCollector.Win32NamedEvent Microsoft.TestPlatform.Extensions.BlameDataCollector.Win32NamedEvent.Set() -> void