diff --git a/docs/debugging.md b/docs/debugging.md new file mode 100644 index 000000000..add94b320 --- /dev/null +++ b/docs/debugging.md @@ -0,0 +1,4 @@ +# Debugging + +https://marketplace.visualstudio.com/items?itemName=DennisMaxJung.vscode-dotnet-auto-attach +https://marketplace.visualstudio.com/items?itemName=ViktarKarpach.DebugAttachManager \ No newline at end of file diff --git a/src/Acoustics.Shared/Acoustics.Shared.csproj b/src/Acoustics.Shared/Acoustics.Shared.csproj index c4921b162..e77b81a6d 100644 --- a/src/Acoustics.Shared/Acoustics.Shared.csproj +++ b/src/Acoustics.Shared/Acoustics.Shared.csproj @@ -13,33 +13,6 @@ pdbonly - - - ..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte.dll - False - True - - - ..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte100.dll - False - True - - - ..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte80.dll - False - True - - - ..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte90.dll - False - True - - - ..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\envdte90a.dll - False - True - - AP.Settings.json diff --git a/src/Acoustics.Shared/Debugging/AutoAttachVs.cs b/src/Acoustics.Shared/Debugging/AutoAttachVs.cs deleted file mode 100644 index 66a76e141..000000000 --- a/src/Acoustics.Shared/Debugging/AutoAttachVs.cs +++ /dev/null @@ -1,234 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// All code in this file and all associated files are the copyright and property of the QUT Ecoacoustics Research Group (formerly MQUTeR, and formerly QUT Bioacoustics Research Group). -// -// -// Example taken from this gist. -// -// -------------------------------------------------------------------------------------------------------------------- - -#if DEBUG - -namespace Acoustics.Shared.Debugging -{ - using System; - using System.Collections.Generic; - using System.Diagnostics.CodeAnalysis; - using System.IO; - using System.Linq; - using System.Runtime.InteropServices; - using System.Runtime.InteropServices.ComTypes; - - using EnvDTE; - - using DTEProcess = EnvDTE.Process; - using Process = System.Diagnostics.Process; - - /// - /// Example taken from this gist. - /// - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", - Justification = "Reviewed. Suppression is OK here.", Scope = "class")] - public static class VisualStudioAttacher - { - [DllImport("ole32.dll")] - // ReSharper disable once IdentifierTypo - public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); - - [DllImport("ole32.dll")] - // ReSharper disable once IdentifierTypo - public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot); - - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern bool SetForegroundWindow(IntPtr hWnd); - - [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] - public static extern IntPtr SetFocus(IntPtr hWnd); - - public static string GetSolutionForVisualStudio(Process visualStudioProcess) - { - if (TryGetVsInstance(visualStudioProcess.Id, out var visualStudioInstance)) - { - try - { - return visualStudioInstance.Solution.FullName; - } - catch (Exception) - { - } - } - - return null; - } - - public static Process GetAttachedVisualStudio(Process applicationProcess) - { - IEnumerable visualStudios = GetVisualStudioProcesses(); - - foreach (Process visualStudio in visualStudios) - { - if (TryGetVsInstance(visualStudio.Id, out var visualStudioInstance)) - { - try - { - foreach (Process debuggedProcess in visualStudioInstance.Debugger.DebuggedProcesses) - { - if (debuggedProcess.Id == applicationProcess.Id) - { - return debuggedProcess; - } - } - } - catch (Exception) - { - } - } - } - - return null; - } - - /// - /// The method to use to attach visual studio to a specified process. - /// - /// - /// The visual studio process to attach to. - /// - /// - /// The application process that needs to be debugged. - /// - /// - /// Thrown when the application process is null. - /// - public static void AttachVisualStudioToProcess(Process visualStudioProcess, Process applicationProcess) - { - if (TryGetVsInstance(visualStudioProcess.Id, out var visualStudioInstance)) - { - // Find the process you want the VS instance to attach to... - DTEProcess processToAttachTo = - visualStudioInstance.Debugger.LocalProcesses.Cast() - .FirstOrDefault(process => process.ProcessID == applicationProcess.Id); - - // Attach to the process. - if (processToAttachTo != null) - { - processToAttachTo.Attach(); - - ShowWindow((int)visualStudioProcess.MainWindowHandle, 3); - SetForegroundWindow(visualStudioProcess.MainWindowHandle); - } - else - { - throw new InvalidOperationException( - "Visual Studio process cannot find specified application '" + applicationProcess.Id + "'"); - } - } - } - - /// - /// The get visual studio for solutions. - /// - /// - /// The solution names. - /// - /// - /// The . - /// - public static Process GetVisualStudioForSolutions(List solutionNames) - { - foreach (string solution in solutionNames) - { - Process visualStudioForSolution = GetVisualStudioForSolution(solution); - if (visualStudioForSolution != null) - { - return visualStudioForSolution; - } - } - - return null; - } - - /// - /// The get visual studio process that is running and has the specified solution loaded. - /// - /// - /// The solution name to look for. - /// - /// - /// The visual studio with the specified solution name. - /// - public static Process GetVisualStudioForSolution(string solutionName) - { - IEnumerable visualStudios = GetVisualStudioProcesses(); - - foreach (Process visualStudio in visualStudios) - { - if (TryGetVsInstance(visualStudio.Id, out var visualStudioInstance)) - { - try - { - string actualSolutionName = Path.GetFileName(visualStudioInstance.Solution.FullName); - - if (string.Compare( - actualSolutionName, - solutionName, - StringComparison.InvariantCultureIgnoreCase) == 0) - { - return visualStudio; - } - } - catch (Exception) - { - throw; - } - } - } - - return null; - } - - [DllImport("User32")] - private static extern int ShowWindow(int hwnd, int nCmdShow); - - private static IEnumerable GetVisualStudioProcesses() - { - Process[] processes = Process.GetProcesses(); - return processes.Where(o => o.ProcessName.Contains("devenv")); - } - - private static bool TryGetVsInstance(int processId, out _DTE instance) - { - IntPtr numFetched = IntPtr.Zero; - IMoniker[] monikers = new IMoniker[1]; - - GetRunningObjectTable(0, out var runningObjectTable); - runningObjectTable.EnumRunning(out var monikerEnumerator); - monikerEnumerator.Reset(); - - while (monikerEnumerator.Next(1, monikers, numFetched) == 0) - { - CreateBindCtx(0, out var ctx); - - monikers[0].GetDisplayName(ctx, null, out var runningObjectName); - - runningObjectTable.GetObject(monikers[0], out var runningObjectVal); - - if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio")) - { - int currentProcessId = int.Parse(runningObjectName.Split(':')[1]); - - if (currentProcessId == processId) - { - instance = (_DTE)runningObjectVal; - return true; - } - } - } - - instance = null; - return false; - } - } -} - -#endif \ No newline at end of file diff --git a/src/Acoustics.Shared/Meta.cs b/src/Acoustics.Shared/Meta.cs index 355e2d5b0..e4c50014d 100644 --- a/src/Acoustics.Shared/Meta.cs +++ b/src/Acoustics.Shared/Meta.cs @@ -21,6 +21,12 @@ public static class Meta public static readonly int NowYear = DateTime.Now.Year; + private static readonly Assembly[] OurAssemblies = + AppDomain.CurrentDomain + .GetAssemblies() + .Where(OurCodePredicate) + .ToArray(); + public static string Organization { get; } = "QUT"; public static string Website { get; } = "http://research.ecosounds.org/"; @@ -29,11 +35,10 @@ public static class Meta public static string Repository { get; } = "https://github.com/QutBioacoustics/audio-analysis"; - private static readonly Assembly[] OurAssemblies = - AppDomain.CurrentDomain - .GetAssemblies() - .Where(OurCodePredicate) - .ToArray(); + public static string GetDocsUrl(string page) + { + return $"{Repository}/blob/master/docs/{page}"; + } public static IEnumerable GetTypesFromQutAssemblies() { diff --git a/src/AnalysisPrograms/Production/MainEntryUtilities.cs b/src/AnalysisPrograms/Production/MainEntryUtilities.cs index c487bad6d..537998daa 100644 --- a/src/AnalysisPrograms/Production/MainEntryUtilities.cs +++ b/src/AnalysisPrograms/Production/MainEntryUtilities.cs @@ -19,15 +19,12 @@ namespace AnalysisPrograms using Acoustics.Shared; using Acoustics.Shared.Contracts; using Acoustics.Shared.Logging; - using log4net.Core; -#if DEBUG - using Acoustics.Shared.Debugging; -#endif using AnalysisPrograms.Production; using AnalysisPrograms.Production.Arguments; using AnalysisPrograms.Production.Parsers; using log4net; + using log4net.Core; using McMaster.Extensions.CommandLineUtils; using static System.Environment; @@ -115,19 +112,25 @@ public static void SetLogVerbosity(LogVerbosity logVerbosity, bool quietConsole //Logging.TestLogging(); } + [Conditional("DEBUG")] internal static void AttachDebugger(DebugOptions options) { if (options == DebugOptions.No) { return; } -#if DEBUG + if (!Debugger.IsAttached && !IsMsTestRunningMe) { if (options == DebugOptions.Prompt) { + var prompt = +$@"Do you wish to debug? +\tAttach now or press [Y] and [ENTER] to attach. Press [N] or [ENTER] to continue. +See {Meta.GetDocsUrl("debugging.md")} for help."; + var response = Prompt.GetYesNo( - "Do you wish to debug? Attach now or press [Y] and [ENTER] to attach. Press [N] or [ENTER] to continue.", + prompt, defaultAnswer: false, promptColor: ConsoleColor.Cyan); options = response ? DebugOptions.Yes : DebugOptions.No; @@ -135,19 +138,8 @@ internal static void AttachDebugger(DebugOptions options) if (options == DebugOptions.Yes || options == DebugOptions.YesSilent) { - var vsProcess = - VisualStudioAttacher.GetVisualStudioForSolutions( - new List { "AudioAnalysis.sln" }); - - if (vsProcess != null) - { - VisualStudioAttacher.AttachVisualStudioToProcess(vsProcess, Process.GetCurrentProcess()); - } - else - { - // try and attach the old fashioned way - Debugger.Launch(); - } + // try and attach the old fashioned way + Debugger.Launch(); } // ReSharper disable once ConditionIsAlwaysTrueOrFalse @@ -160,7 +152,6 @@ internal static void AttachDebugger(DebugOptions options) } } } -#endif } internal static void BeforeExecute(MainArgs main, CommandLineApplication application)