Наша сборка Qt VS Tools
giy
2022-09-02 ca47896204482bf4a6979e3838bf7f09f61cebeb
QtVsTools.Package/QML/Debugging/QmlDebugLauncher.cs
@@ -35,39 +35,50 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.VCProjectEngine;
using QtVsTools.Core;
using QtVsTools.Core.QtMsBuild;
using QtVsTools.SyntaxAnalysis;
using static QtVsTools.SyntaxAnalysis.RegExpr;
namespace QtVsTools.Qml.Debug
{
    using AD7;
    using Common;
    using Core;
    using Core.QtMsBuild;
    using SyntaxAnalysis;
    using VisualStudio;
    using static SyntaxAnalysis.RegExpr;
    class Launcher : Disposable, IDebugEventCallback2
    {
        public static Launcher Instance { get; private set; }
        LazyFactory Lazy { get; } = new LazyFactory();
        private static Launcher Instance { get; set; }
        IVsDebugger debugger;
        IVsDebugger4 debugger4;
        HashSet<Guid> _ExcludedProcesses;
        HashSet<Guid> ExcludedProcesses => _ExcludedProcesses
            ?? (_ExcludedProcesses = new HashSet<Guid>());
        HashSet<Guid> ExcludedProcesses => Lazy.Get(() =>
            ExcludedProcesses, () => new HashSet<Guid>());
        public static void Initialize()
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            Instance = new Launcher();
            Instance.debugger = VsServiceProvider.GetService<IVsDebugger>();
            Instance.debugger4 = VsServiceProvider.GetService<IVsDebugger, IVsDebugger4>();
            if (Instance.debugger != null && Instance.debugger4 != null)
                Instance.debugger.AdviseDebugEventCallback(Instance);
        }
        protected override void DisposeManaged()
        {
            if (debugger != null)
                debugger.UnadviseDebugEventCallback(this);
            if (debugger != null) {
                ThreadHelper.JoinableTaskFactory.Run(async () =>
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                    debugger.UnadviseDebugEventCallback(this);
                });
            }
        }
        int IDebugEventCallback2.Event(
@@ -79,6 +90,8 @@
            ref Guid riidEvent,
            uint dwAttrib)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            if (!QtVsToolsPackage.Instance.Options.QmlDebuggerEnabled)
                return VSConstants.S_OK;
@@ -90,8 +103,7 @@
            if (pProcess == null && pProgram.GetProcess(out pProcess) != VSConstants.S_OK)
                return VSConstants.S_OK;
            Guid procGuid;
            if (pProcess.GetProcessId(out procGuid) != VSConstants.S_OK)
            if (pProcess.GetProcessId(out Guid procGuid) != VSConstants.S_OK)
                return VSConstants.S_OK;
            // Run only once per process
@@ -119,14 +131,10 @@
            else
                return VSConstants.S_OK;
            string execPath;
            uint procId;
            if (!GetProcessInfo(pProcess, native, out execPath, out procId))
            if (!GetProcessInfo(pProcess, native, out string execPath, out uint procId))
                return VSConstants.S_OK;
            string execCmd;
            IEnumerable<string> rccItems;
            if (!GetProjectInfo(execPath, native, out execCmd, out rccItems))
            if (!GetProjectInfo(execPath, native, out string execCmd, out IEnumerable<string> rccItems))
                return VSConstants.S_OK;
            LaunchDebug(execPath, execCmd, procId, rccItems);
@@ -135,9 +143,7 @@
        Guid GetEngineId(IDebugProgram2 pProgram)
        {
            string engineName;
            Guid engineGuid;
            if (pProgram.GetEngineInfo(out engineName, out engineGuid) != VSConstants.S_OK)
            if (pProgram.GetEngineInfo(out _, out Guid engineGuid) != VSConstants.S_OK)
                return Guid.Empty;
            return engineGuid;
        }
@@ -152,7 +158,7 @@
            }
        }
        static RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
        static readonly RegExpr wslPathRegex = new Token("WSLPATH", SkipWs_Disable, StartOfFile
            & "/mnt/" & new Token("DRIVE", CharWord) & "/" & new Token("PATH", AnyChar.Repeat()))
        {
            new Rule<WslPath>
@@ -161,15 +167,14 @@
                Update("PATH", (WslPath wslPath, string path) => wslPath.Path = path),
            }
        };
        static RegExpr.Parser wslPathParser = wslPathRegex.Render();
        static readonly RegExpr.Parser wslPathParser = wslPathRegex.Render();
        bool GetProcessInfo(IDebugProcess2 pProcess, bool native, out string execPath, out uint procId)
        {
            execPath = "";
            procId = 0;
            string fileName;
            if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out fileName) != VSConstants.S_OK)
            if (pProcess.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName) != VSConstants.S_OK)
                return false;
            var pProcessId = new AD_PROCESS_ID[1];
@@ -193,6 +198,8 @@
        bool GetProjectInfo(string execPath, bool native, out string execCmd, out IEnumerable<string> rccItems)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            execCmd = "";
            rccItems = null;
@@ -290,6 +297,8 @@
            uint procId,
            IEnumerable<string> rccItems)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            var targets = new[] { new VsDebugTargetInfo4
            {
                dlo = (uint)DEBUG_LAUNCH_OPERATION.DLO_CreateProcess,
@@ -305,8 +314,8 @@
            try {
                debugger4.LaunchDebugTargets4((uint)targets.Length, targets, processInfo);
            } catch (System.Exception e) {
                OutputWriteLine(e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
            } catch (Exception exception) {
                exception.Log();
            }
        }
    }