diff --git a/src/AttachVS/AttachVs.cs b/src/AttachVS/AttachVs.cs index 407c1a5045..7b6c28aaa4 100644 --- a/src/AttachVS/AttachVs.cs +++ b/src/AttachVS/AttachVs.cs @@ -10,8 +10,6 @@ using System.Runtime.InteropServices.ComTypes; using System.Threading; -#nullable disable - namespace Microsoft.TestPlatform.AttachVS; internal class DebuggerUtility @@ -25,8 +23,9 @@ internal static bool AttachVSToProcess(int? pid, int? vsPid) Trace($"FAIL: Pid is null."); return false; } + var process = Process.GetProcessById(pid.Value); - Trace($"Starting with pid '{pid}({process?.ProcessName})', and vsPid '{vsPid}'"); + Trace($"Starting with pid '{pid}({process.ProcessName})', and vsPid '{vsPid}'"); Trace($"Using pid: {pid} to get parent VS."); var vs = GetVsFromPid(Process.GetProcessById(vsPid ?? process.Id)); @@ -34,11 +33,13 @@ internal static bool AttachVSToProcess(int? pid, int? vsPid) { Trace($"Parent VS is {vs.ProcessName} ({vs.Id})."); AttachTo(process, vs); + return true; } - else - { - Trace($"Parent VS not found, finding the first VS that started."); - var processes = Process.GetProcesses().Where(p => p.ProcessName == "devenv").Select(p => + + Trace($"Parent VS not found, finding the first VS that started."); + var firstVs = Process.GetProcesses() + .Where(p => p.ProcessName == "devenv") + .Select(p => { try { @@ -48,19 +49,26 @@ internal static bool AttachVSToProcess(int? pid, int? vsPid) { return null; } - }).Where(p => p != null && !p.HasExited).OrderBy(p => p.StartTime).ToList(); + }) + .Where(p => p != null && !p.HasExited) + .OrderBy(p => p!.StartTime) + .FirstOrDefault(); - var firstVs = processes.FirstOrDefault(); + if (firstVs != null) + { Trace($"Found VS {firstVs.Process.Id}"); AttachTo(process, firstVs.Process); + return true; } - return true; + + Trace("Could not find any started VS."); } catch (Exception ex) { Trace($"ERROR: {ex}, {ex.StackTrace}"); - return false; } + + return false; } private static void AttachTo(Process process, Process vs) @@ -79,9 +87,9 @@ private static void AttachTo(Process process, Process vs) private static bool AttachVs(Process vs, int pid) { - IBindCtx bindCtx = null; - IRunningObjectTable runninObjectTable = null; - IEnumMoniker enumMoniker = null; + IBindCtx? bindCtx = null; + IRunningObjectTable? runninObjectTable = null; + IEnumMoniker? enumMoniker = null; try { var r = CreateBindCtx(0, out bindCtx); @@ -183,18 +191,18 @@ private static bool AttachVs(Process vs, int pid) } } - private static Process GetVsFromPid(Process process) + private static Process? GetVsFromPid(Process process) { var parent = process; while (!IsVsOrNull(parent)) { - parent = GetParentProcess(parent); + parent = GetParentProcess(parent!); } return parent; } - private static bool IsVsOrNull(Process process) + private static bool IsVsOrNull(Process? process) { if (process == null) { @@ -219,7 +227,7 @@ private static bool IsCorrectParent(Process currentProcess, Process parent) { try { - // Parent needs to start before the child, otherwise it might be a different process + // Parent needs to start before the child, otherwise it might be a different process // that is just reusing the same PID. if (parent.StartTime <= currentProcess.StartTime) { @@ -227,38 +235,25 @@ private static bool IsCorrectParent(Process currentProcess, Process parent) } Trace($"Process {parent.ProcessName} ({parent.Id}) is not a valid parent because it started after the current process."); - return false; } catch { // Access denied or process exited while we were holding the Process object. - return false; } + + return false; } - private static Process GetParentProcess(Process process) + private static Process? GetParentProcess(Process process) { - int id; - try - { - var handle = process.Handle; - var res = NtQueryInformationProcess(handle, 0, out var pbi, Marshal.SizeOf(), out int size); - - var p = res != 0 ? -1 : pbi.InheritedFromUniqueProcessId.ToInt32(); - - id = p; - } - catch - { - id = -1; - } - - Process parent = null; + int id = GetParentProcessId(process); if (id != -1) { try { - parent = Process.GetProcessById(id); + var parent = Process.GetProcessById(id); + if (IsCorrectParent(process, parent)) + return parent; } catch { @@ -266,10 +261,27 @@ private static Process GetParentProcess(Process process) } } - return IsCorrectParent(process, parent) ? parent : null; + return null; + + static int GetParentProcessId(Process process) + { + try + { + var handle = process.Handle; + var res = NtQueryInformationProcess(handle, 0, out var pbi, Marshal.SizeOf(), out int size); + + var p = res != 0 ? -1 : pbi.InheritedFromUniqueProcessId.ToInt32(); + + return p; + } + catch + { + return -1; + } + } } - private static void Trace(string message, [CallerMemberName] string methodName = null) + private static void Trace(string message, [CallerMemberName] string? methodName = null) { System.Diagnostics.Trace.WriteLine($"[AttachVS]{methodName}: {message}"); } diff --git a/src/AttachVS/Program.cs b/src/AttachVS/Program.cs index 74268fb5e5..d062e64c94 100644 --- a/src/AttachVS/Program.cs +++ b/src/AttachVS/Program.cs @@ -5,13 +5,11 @@ using System.Diagnostics; using System.Linq; -#nullable disable - namespace Microsoft.TestPlatform.AttachVS; internal class Program { - static void Main(string[] args) + static void Main(string[] args!!) { Trace.Listeners.Add(new ConsoleTraceListener());