From 81826bd53c738d69877d8d5e50822f0531ed39b9 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Thu, 10 Oct 2024 16:54:28 -0700 Subject: [PATCH 01/24] implement IManagedHotReloadAgent2 --- .../VS/HotReload/ProjectHotReloadSession.cs | 13 ++++++++++++- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 80f4bc406d3..5e25fec11b3 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -2,10 +2,11 @@ using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; +using static Microsoft.VisualStudio.ProjectSystem.VS.HotReload.ProjectHotReloadSessionManager; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { - internal class ProjectHotReloadSession : IManagedHotReloadAgent, IProjectHotReloadSession, IProjectHotReloadSessionInternal + internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotReloadAgent2, IProjectHotReloadSession, IProjectHotReloadSessionInternal { private readonly string _variant; private readonly string _runtimeVersion; @@ -288,5 +289,15 @@ private void EnsureDeltaApplierforSession() ?? _deltaApplierCreator.Value.CreateManagedDeltaApplier(_runtimeVersion); } } + + public ValueTask GetTargetLocalProcessIdAsync(CancellationToken cancellationToken) + { + if (_callback is HotReloadState hotReloadState) + { + return new ValueTask(hotReloadState.Process?.Id); + } + + return new ValueTask(); + } } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 1815c2611d7..d942a729e0b 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -449,7 +449,7 @@ async Task ApplyHotReloadUpdateInternalAsync() } } - private class HotReloadState : IProjectHotReloadSessionCallback + internal class HotReloadState : IProjectHotReloadSessionCallback { private readonly ProjectHotReloadSessionManager _sessionManager; From c93988ed8fe459b9efdbd29dc80252fb7ebfbb3c Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Thu, 10 Oct 2024 19:05:54 -0700 Subject: [PATCH 02/24] return project full path --- .../VS/HotReload/ProjectHotReloadSession.cs | 10 ++++++++++ .../VS/HotReload/ProjectHotReloadSessionManager.cs | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 5e25fec11b3..30a6ed91f0d 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -299,5 +299,15 @@ private void EnsureDeltaApplierforSession() return new ValueTask(); } + + public ValueTask GetProjectFullPathAsync(CancellationToken cancellationToken) + { + if (_callback is HotReloadState hrs) + { + return new ValueTask(hrs.Project?.FullPath); + } + + return new ValueTask(); + } } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index d942a729e0b..8e481a0d064 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -459,9 +459,12 @@ internal class HotReloadState : IProjectHotReloadSessionCallback // TODO: Support restarting the session. public bool SupportsRestart => false; + public UnconfiguredProject? Project { get; } + public HotReloadState(ProjectHotReloadSessionManager sessionManager) { _sessionManager = sessionManager; + Project = _sessionManager._project; } internal void OnProcessExited(object sender, EventArgs e) From fd6a5292f9ce98a2e02e4d1de4a80c155f8a5529 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Sun, 13 Oct 2024 21:23:26 -0700 Subject: [PATCH 03/24] update --- Directory.Packages.props | 5 +++-- nuget.config | 1 + .../ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 9d7e5ed66e9..eca5c586233 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,6 +5,7 @@ true + 17.12.0-dev ProjectSystem net472 + RoslynDev Extensions diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 1f7356c906c..e5c2255e377 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { - internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotReloadAgent2, IManagedHotReloadAgent3, IManagedHotReloadAgent4, IProjectHotReloadSession, IProjectHotReloadSessionInternal + internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotReloadAgent2, IManagedHotReloadAgent4, IProjectHotReloadSession, IProjectHotReloadSessionInternal { private readonly string _variant; private readonly string _runtimeVersion; @@ -310,10 +310,5 @@ private void EnsureDeltaApplierforSession() return new ValueTask(); } - - public ValueTask GetProcessInformationAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } } } From 1166c77bba8472c1e15c9ddacbe570ed20405446 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 16 Oct 2024 18:56:32 -0700 Subject: [PATCH 05/24] implement RestartProject --- Directory.Packages.props | 2 +- .../ProjectSystemSetup.csproj | 2 +- .../VS/HotReload/ProjectHotReloadAgent.cs | 9 +++- .../VS/HotReload/ProjectHotReloadSession.cs | 13 +++--- .../ProjectHotReloadSessionManager.cs | 42 ++++++++++++++++--- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index eca5c586233..2f5767e11ac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ true - 17.12.0-dev + 17.12.5-dev ProjectSystem net472 - + RoslynDev Extensions Microsoft\ManagedProjectSystem diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs index ea6f6415816..ccd52dfac3c 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs @@ -2,6 +2,7 @@ using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; +using Microsoft.VisualStudio.ProjectSystem.VS.Build; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { @@ -11,16 +12,19 @@ internal class ProjectHotReloadAgent : IProjectHotReloadAgent private readonly Lazy _hotReloadAgentManagerClient; private readonly Lazy _hotReloadDiagnosticOutputService; private readonly Lazy _managedDeltaApplierCreator; + private readonly Lazy _solutionBuildManager; [ImportingConstructor] public ProjectHotReloadAgent( Lazy hotReloadAgentManagerClient, Lazy hotReloadDiagnosticOutputService, - Lazy managedDeltaApplierCreator) + Lazy managedDeltaApplierCreator, + Lazy solutionBuildManager) { _hotReloadAgentManagerClient = hotReloadAgentManagerClient; _hotReloadDiagnosticOutputService = hotReloadDiagnosticOutputService; _managedDeltaApplierCreator = managedDeltaApplierCreator; + _solutionBuildManager = solutionBuildManager; } public IProjectHotReloadSession? CreateHotReloadSession(string id, int variant, string runtimeVersion, IProjectHotReloadSessionCallback callback) @@ -32,7 +36,8 @@ public ProjectHotReloadAgent( _hotReloadAgentManagerClient, _hotReloadDiagnosticOutputService, _managedDeltaApplierCreator, - callback); + callback, + _solutionBuildManager); } public IProjectHotReloadSession? CreateHotReloadSession(string id, string runtimeVersion, IProjectHotReloadSessionCallback callback) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 1f7356c906c..070a4dc1864 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -3,11 +3,12 @@ using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue; using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; +using Microsoft.VisualStudio.ProjectSystem.VS.Build; using static Microsoft.VisualStudio.ProjectSystem.VS.HotReload.ProjectHotReloadSessionManager; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { - internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotReloadAgent2, IManagedHotReloadAgent3, IManagedHotReloadAgent4, IProjectHotReloadSession, IProjectHotReloadSessionInternal + internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotReloadAgent2, IManagedHotReloadAgent4, IProjectHotReloadSession, IProjectHotReloadSessionInternal { private readonly string _variant; private readonly string _runtimeVersion; @@ -15,6 +16,7 @@ internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotRelo private readonly Lazy _hotReloadOutputService; private readonly Lazy _deltaApplierCreator; private readonly IProjectHotReloadSessionCallback _callback; + private readonly Lazy _solutionBuildManager; private bool _sessionActive; private IDeltaApplier? _deltaApplier; @@ -26,7 +28,8 @@ public ProjectHotReloadSession( Lazy hotReloadAgentManagerClient, Lazy hotReloadOutputService, Lazy deltaApplierCreator, - IProjectHotReloadSessionCallback callback) + IProjectHotReloadSessionCallback callback, + Lazy solutionBuildManager) { Name = name; _variant = variant.ToString(); @@ -35,6 +38,7 @@ public ProjectHotReloadSession( _hotReloadOutputService = hotReloadOutputService; _deltaApplierCreator = deltaApplierCreator; _callback = callback; + _solutionBuildManager = solutionBuildManager; } // IProjectHotReloadSession @@ -310,10 +314,5 @@ private void EnsureDeltaApplierforSession() return new ValueTask(); } - - public ValueTask GetProcessInformationAsync(CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 8e481a0d064..433f0699490 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -5,6 +5,8 @@ using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; using Microsoft.VisualStudio.ProjectSystem.Debug; using Microsoft.VisualStudio.ProjectSystem.Properties; +using Microsoft.VisualStudio.ProjectSystem.VS.Build; +using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload @@ -19,6 +21,8 @@ internal class ProjectHotReloadSessionManager : OnceInitializedOnceDisposedAsync private readonly Lazy _projectHotReloadAgent; private readonly Lazy _hotReloadDiagnosticOutputService; private readonly Lazy _projectHotReloadNotificationService; + private readonly Lazy _solutionBuildManager; + private readonly IProjectThreadingService _projectThreadingService; // Protect the state from concurrent access. For example, our Process.Exited event // handler may run on one thread while we're still setting up the session on @@ -39,15 +43,18 @@ public ProjectHotReloadSessionManager( IActiveDebugFrameworkServices activeDebugFrameworkServices, Lazy projectHotReloadAgent, Lazy hotReloadDiagnosticOutputService, - Lazy projectHotReloadNotificationService) + Lazy projectHotReloadNotificationService, + Lazy solutionBuilderManager) : base(threadingService.JoinableTaskContext) { _project = project; + _projectThreadingService = threadingService; _projectFaultHandlerService = projectFaultHandlerService; _activeDebugFrameworkServices = activeDebugFrameworkServices; _projectHotReloadAgent = projectHotReloadAgent; _hotReloadDiagnosticOutputService = hotReloadDiagnosticOutputService; _projectHotReloadNotificationService = projectHotReloadNotificationService; + _solutionBuildManager = solutionBuilderManager; _semaphore = ReentrantSemaphore.Create( initialCount: 1, @@ -352,10 +359,35 @@ private async Task OnProcessExitedAsync(HotReloadState hotReloadState) return null; } - private static Task RestartProjectAsync(HotReloadState hotReloadState, CancellationToken cancellationToken) + private async Task RestartProjectAsync(HotReloadState hotReloadState, CancellationToken cancellationToken) { // TODO: Support restarting the project. - return TaskResult.False; + Assumes.NotNull(_project.Services.HostObject); + await _projectThreadingService.SwitchToUIThread(); + + var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; + _solutionBuildManager.Value.SaveDocumentsBeforeBuild(projectVsHierarchy, (uint)VSConstants.VSITEMID.Root, docCookie: 0); + // We need to make sure dependencies are built so they can go into the package + _solutionBuildManager.Value.CalculateProjectDependencies(); + + // Assembly our list of projects to build + var projects = new List + { + projectVsHierarchy + }; + + projects.AddRange(_solutionBuildManager.Value.GetProjectDependencies(projectVsHierarchy)); + + uint dwFlags = (uint)(VSSOLNBUILDUPDATEFLAGS.SBF_SUPPRESS_SAVEBEFOREBUILD_QUERY | VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD); + + uint[] buildFlags = new uint[projects.Count]; + // We tell the Solution Build Manager to Package our project, which will call the Pack target, which will build if necessary. + // Any dependent projects will just do a normal build + buildFlags[0] = VSConstants.VS_BUILDABLEPROJECTCFGOPTS_PACKAGE; + + _solutionBuildManager.Value.StartUpdateSpecificProjectConfigurations(projects.ToArray(), buildFlags, dwFlags); + + return true; } private static Task OnAfterChangesAppliedAsync(HotReloadState hotReloadState, CancellationToken cancellationToken) @@ -457,7 +489,7 @@ internal class HotReloadState : IProjectHotReloadSessionCallback public IProjectHotReloadSession? Session { get; set; } // TODO: Support restarting the session. - public bool SupportsRestart => false; + public bool SupportsRestart => true; public UnconfiguredProject? Project { get; } @@ -484,7 +516,7 @@ public Task StopProjectAsync(CancellationToken cancellationToken) public Task RestartProjectAsync(CancellationToken cancellationToken) { - return ProjectHotReloadSessionManager.RestartProjectAsync(this, cancellationToken); + return _sessionManager.RestartProjectAsync(this, cancellationToken); } public IDeltaApplier? GetDeltaApplier() From 0deb4cba3a09ee6b3c3e27eecb58028b109384de Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 16 Oct 2024 21:16:19 -0700 Subject: [PATCH 06/24] update debug contract version --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2f5767e11ac..eca5c586233 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ true - 17.12.5-dev + 17.12.0-dev ProjectSystem net472 - RoslynDev + Extensions Microsoft\ManagedProjectSystem From 4d35fc81a5dde2570a2f9b981c50afa353c99a47 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Mon, 21 Oct 2024 14:12:05 -0700 Subject: [PATCH 10/24] add ISolutionBuildManager mock to test --- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 14 -------------- .../ProjectHotReloadSessionManagerTests.cs | 4 +++- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 8203764e94c..4fe0de75432 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -370,20 +370,6 @@ private async Task RestartProjectAsync(HotReloadState hotReloadState, Canc // We need to make sure dependencies are built so they can go into the package _solutionBuildManager.Value.CalculateProjectDependencies(); - // Assembly our list of projects to build - var projects = new List - { - projectVsHierarchy - }; - - projects.AddRange(_solutionBuildManager.Value.GetProjectDependencies(projectVsHierarchy)); - - uint dwFlags = (uint)(VSSOLNBUILDUPDATEFLAGS.SBF_SUPPRESS_SAVEBEFOREBUILD_QUERY | VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD); - - uint[] buildFlags = new uint[projects.Count]; - // We tell the Solution Build Manager to Package our project, which will call the Pack target, which will build if necessary. - // Any dependent projects will just do a normal build - buildFlags[0] = VSConstants.VS_BUILDABLEPROJECTCFGOPTS_PACKAGE; //_solutionBuildManager.Value.StartUpdateSpecificProjectConfigurations(projects.ToArray(), buildFlags, dwFlags); _solutionBuildManager.Value.SetStartupProject(projectVsHierarchy); diff --git a/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs b/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs index 572ecc14f5f..8594238704e 100644 --- a/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs +++ b/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. using Microsoft.VisualStudio.ProjectSystem.Debug; +using Microsoft.VisualStudio.ProjectSystem.VS.Build; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { @@ -176,7 +177,8 @@ private static ProjectHotReloadSessionManager CreateHotReloadSessionManager(Conf activeDebugFrameworkServices, new Lazy(() => IProjectHotReloadAgentFactory.Create()), new Lazy(() => IHotReloadDiagnosticOutputServiceFactory.Create(outputServiceCallback)), - new Lazy(() => IProjectHotReloadNotificationServiceFactory.Create())); + new Lazy(() => IProjectHotReloadNotificationServiceFactory.Create()), + new Lazy(() => ISolutionBuildManagerFactory.Create(null, null, false, false))); return manager; } From 10266203bdfa5d9f748d8a923c7d6c27f58ba93f Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Mon, 21 Oct 2024 14:16:15 -0700 Subject: [PATCH 11/24] return _sessionManager._project --- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 4fe0de75432..3b0087c5607 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -479,12 +479,11 @@ internal class HotReloadState : IProjectHotReloadSessionCallback // TODO: Support restarting the session. public bool SupportsRestart => true; - public UnconfiguredProject? Project { get; } + public UnconfiguredProject? Project => _sessionManager._project; public HotReloadState(ProjectHotReloadSessionManager sessionManager) { _sessionManager = sessionManager; - Project = _sessionManager._project; } internal void OnProcessExited(object sender, EventArgs e) From 6910c67561b7df9d680108d5d8b69ed5d1872264 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Tue, 29 Oct 2024 17:15:06 -0700 Subject: [PATCH 12/24] update --- .../VS/Build/ISolutionBuildManager.cs | 12 ++ .../VS/Build/SolutionBuildManager.cs | 28 +++- .../VS/HotReload/ProjectHotReloadSession.cs | 19 ++- .../ProjectHotReloadSessionManager.cs | 132 +++++++++++++++--- 4 files changed, 167 insertions(+), 24 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs index 102ec27d01b..392ab86660e 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs @@ -32,6 +32,18 @@ internal interface ISolutionBuildManager int DebugLaunch(uint grfLaunch); + int QueryDebugLaunch(uint grfLaunch); + void StartUpdateSpecificProjectConfigurations(IVsHierarchy[] hierarchy, uint[] buildFlags, uint dwFlags); + + int StartSimpleUpdateProjectConfiguration( + IVsHierarchy pIVsHierarchyToBuild, + IVsHierarchy? pIVsHierarchyDependent, + string? pszDependentConfigurationCanonicalName, + uint dwFlags, + uint dwDefQueryResults, + int fSuppressUI); + + IVsProjectCfg2[] FindActiveProjectCfg(IntPtr pvReserved1, IntPtr pvReserved2, IVsHierarchy pIVsHierarchy_RequestedProject); } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs index 8e5a842668c..06248383f1b 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs @@ -1,5 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Runtime.InteropServices; +using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; @@ -108,10 +110,17 @@ public uint QueryBuildManagerBusyEx() JoinableFactory.Context.VerifyIsOnMainThread(); ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager3.QueryBuildManagerBusyEx(out uint flags)); - return flags; } + public int QueryDebugLaunch(uint grfLaunch) + { + Assumes.NotNull(_vsSolutionBuildManager2); + JoinableFactory.Context.VerifyIsOnMainThread(); + ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.QueryDebugLaunch(grfLaunch, out int pfCanLaunch)); + return pfCanLaunch; + } + public void SaveDocumentsBeforeBuild(IVsHierarchy hierarchy, uint itemId, uint docCookie) { Assumes.NotNull(_vsSolutionBuildManager2); @@ -184,5 +193,22 @@ public int DebugLaunch(uint grfLaunch) return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.DebugLaunch(grfLaunch)); } + + public int StartSimpleUpdateProjectConfiguration(IVsHierarchy pIVsHierarchyToBuild, IVsHierarchy? pIVsHierarchyDependent, string? pszDependentConfigurationCanonicalName, uint dwFlags, uint dwDefQueryResults, int fSuppressUI) + { + Assumes.NotNull(_vsSolutionBuildManager2); + JoinableFactory.Context.VerifyIsOnMainThread(); + + return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.StartSimpleUpdateProjectConfiguration(pIVsHierarchyToBuild, pIVsHierarchyDependent, pszDependentConfigurationCanonicalName, dwFlags, dwDefQueryResults, fSuppressUI)); + } + + public IVsProjectCfg2[] FindActiveProjectCfg(IntPtr pvReserved1, IntPtr pvReserved2, IVsHierarchy pIVsHierarchy_RequestedProject) + { + Assumes.NotNull(_vsSolutionBuildManager2); + JoinableFactory.Context.VerifyIsOnMainThread(); + IVsProjectCfg2[] ppIVsProjectCfg_Active = new IVsProjectCfg2[1]; + ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.FindActiveProjectCfg(pvReserved1, pvReserved2, pIVsHierarchy_RequestedProject, ppIVsProjectCfg_Active)); + return ppIVsProjectCfg_Active; + } } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 070a4dc1864..0a42ef8ea7a 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -19,6 +19,9 @@ internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotRelo private readonly Lazy _solutionBuildManager; private bool _sessionActive; + + // This flag is used to identify Debug|NonDebug cases + private bool _isRunningUnderDebugger; private IDeltaApplier? _deltaApplier; public ProjectHotReloadSession( @@ -105,6 +108,7 @@ public async Task StartSessionAsync(bool runningUnderDebugger, CancellationToken ), default); _sessionActive = true; + _isRunningUnderDebugger = runningUnderDebugger; EnsureDeltaApplierforSession(); } @@ -113,7 +117,7 @@ public async Task StopSessionAsync(CancellationToken cancellationToken) if (_sessionActive) { _sessionActive = false; - + _isRunningUnderDebugger = false; await _hotReloadAgentManagerClient.Value.AgentTerminatedAsync(this, cancellationToken); WriteToOutputWindow( new HotReloadLogMessage( @@ -254,10 +258,15 @@ public async ValueTask RestartAsync(CancellationToken cancellationToken) ), cancellationToken); - await _callback.RestartProjectAsync(cancellationToken); - // TODO: Should we stop the session here? Or does someone else do it? - // TODO: Should we handle rebuilding here? Or do we expect the callback to handle it? + if (_callback is HotReloadState hrs) + { + await hrs.RestartProjectAsync(_isRunningUnderDebugger, cancellationToken); + + return; + } + + await _callback.RestartProjectAsync(cancellationToken); } public async ValueTask StopAsync(CancellationToken cancellationToken) @@ -278,7 +287,7 @@ public async ValueTask StopAsync(CancellationToken cancellationToken) public ValueTask SupportsRestartAsync(CancellationToken cancellationToken) { - return new ValueTask(_callback.SupportsRestart); + return new ValueTask(_callback is HotReloadState); } private void WriteToOutputWindow(HotReloadLogMessage hotReloadLogMessage, CancellationToken cancellationToken) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 3b0087c5607..40e0a575e1e 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -1,11 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. using System.Diagnostics; +using System.Runtime.InteropServices; using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; using Microsoft.VisualStudio.ProjectSystem.Debug; using Microsoft.VisualStudio.ProjectSystem.Properties; using Microsoft.VisualStudio.ProjectSystem.VS.Build; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; @@ -32,6 +34,7 @@ internal class ProjectHotReloadSessionManager : OnceInitializedOnceDisposedAsync private readonly Dictionary _activeSessions = []; private HotReloadState? _pendingSessionState = null; private int _nextUniqueId = 1; + private IAsyncDisposable? _solutionBuildEventsSubscription = null; public bool HasActiveHotReloadSessions => _activeSessions.Count != 0; @@ -359,22 +362,53 @@ private async Task OnProcessExitedAsync(HotReloadState hotReloadState) return null; } - private async Task RestartProjectAsync(HotReloadState hotReloadState, CancellationToken cancellationToken) + private async Task RestartProjectAsync( + HotReloadState hotReloadState, + bool isRunningUnderDebug, + CancellationToken cancellationToken) { - // TODO: Support restarting the project. Assumes.NotNull(_project.Services.HostObject); await _projectThreadingService.SwitchToUIThread(); - var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; - _solutionBuildManager.Value.SaveDocumentsBeforeBuild(projectVsHierarchy, (uint)VSConstants.VSITEMID.Root, docCookie: 0); - // We need to make sure dependencies are built so they can go into the package - _solutionBuildManager.Value.CalculateProjectDependencies(); + // Step 0: Dispose existing solution build events subscription if any + if (_solutionBuildEventsSubscription is not null) + { + await _solutionBuildEventsSubscription.DisposeAsync(); + _solutionBuildEventsSubscription = null; + } + // Step 1: Stop running project + await StopProjectAsync(hotReloadState, cancellationToken); - //_solutionBuildManager.Value.StartUpdateSpecificProjectConfigurations(projects.ToArray(), buildFlags, dwFlags); - _solutionBuildManager.Value.SetStartupProject(projectVsHierarchy); - var result = _solutionBuildManager.Value.DebugLaunch((uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_NoDebug); + // Step 2: Debug or NonDebug? + uint dbgLaunchFlag = isRunningUnderDebug ? (uint)0 : (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_NoDebug; + // Step 3: Find IVsDebuggableProjectCfg + var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; + var activeCfg = _solutionBuildManager.Value.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, projectVsHierarchy); + Equals(activeCfg.Length, 1); + var result = activeCfg[0].get_CfgType(typeof(IVsDebuggableProjectCfg).GUID, out var cfgType); + Equals(result, HResult.OK); + + var debuggableCfg = Marshal.GetObjectForIUnknown(cfgType) as IVsDebuggableProjectCfg; + Assumes.NotNull(debuggableCfg); + + result = debuggableCfg.get_BuildableProjectCfg(out var buildableProjectCfg); + Equals(result, HResult.OK); + Assumes.NotNull(buildableProjectCfg); + + // register for the solution build events + var slnEvent = new SlnEvent(projectVsHierarchy, debuggableCfg, (int)dbgLaunchFlag); + _solutionBuildEventsSubscription = await _solutionBuildManager.Value.SubscribeSolutionEventsAsync(slnEvent); + + result = _solutionBuildManager.Value.StartSimpleUpdateProjectConfiguration( + pIVsHierarchyToBuild: projectVsHierarchy, + pIVsHierarchyDependent: null, + pszDependentConfigurationCanonicalName: null, + dwFlags: (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD, + dwDefQueryResults: (uint)VSSOLNBUILDQUERYRESULTS.VSSBQR_SAVEBEFOREBUILD_QUERY_YES, + fSuppressUI: 0); + return result == HResult.OK; } @@ -471,24 +505,23 @@ async Task ApplyHotReloadUpdateInternalAsync() internal class HotReloadState : IProjectHotReloadSessionCallback { - private readonly ProjectHotReloadSessionManager _sessionManager; - public Process? Process { get; set; } public IProjectHotReloadSession? Session { get; set; } - // TODO: Support restarting the session. - public bool SupportsRestart => true; + public ProjectHotReloadSessionManager SessionManager { get; } - public UnconfiguredProject? Project => _sessionManager._project; + public bool SupportsRestart => false; + + public UnconfiguredProject? Project => SessionManager._project; public HotReloadState(ProjectHotReloadSessionManager sessionManager) { - _sessionManager = sessionManager; + SessionManager = sessionManager; } internal void OnProcessExited(object sender, EventArgs e) { - _sessionManager.OnProcessExited(this); + SessionManager.OnProcessExited(this); } public Task OnAfterChangesAppliedAsync(CancellationToken cancellationToken) @@ -498,12 +531,17 @@ public Task OnAfterChangesAppliedAsync(CancellationToken cancellationToken) public Task StopProjectAsync(CancellationToken cancellationToken) { - return _sessionManager.StopProjectAsync(this, cancellationToken).AsTask(); + return SessionManager.StopProjectAsync(this, cancellationToken).AsTask(); } public Task RestartProjectAsync(CancellationToken cancellationToken) { - return _sessionManager.RestartProjectAsync(this, cancellationToken); + return Task.FromResult(false); + } + + public Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken) + { + return SessionManager.RestartProjectAsync(this, isRunningUnderDebug, cancellationToken); } public IDeltaApplier? GetDeltaApplier() @@ -511,5 +549,63 @@ public Task RestartProjectAsync(CancellationToken cancellationToken) return ProjectHotReloadSessionManager.GetDeltaApplier(this); } } + + internal class SlnEvent : IVsUpdateSolutionEvents2 + { + private readonly IVsDebuggableProjectCfg _debuggableProjectCfg; + private readonly IVsHierarchy _pHierProj; + private readonly int _dbgLaunchFlag; + + // resolved when done + + public SlnEvent(IVsHierarchy pHierProj, IVsDebuggableProjectCfg debuggableProjectCfg, int dbgLaunchFlag) + { + _debuggableProjectCfg = debuggableProjectCfg; + _pHierProj = pHierProj; + _dbgLaunchFlag = dbgLaunchFlag; + } + + public int UpdateSolution_Begin(ref int pfCancelUpdate) + { + return HResult.OK; + } + + public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand) + { + return HResult.OK; + } + + public int UpdateSolution_StartUpdate(ref int pfCancelUpdate) + { + return HResult.OK; + } + + public int UpdateSolution_Cancel() + { + return HResult.OK; + } + + public int OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy) + { + return HResult.OK; + } + + public int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel) + { + return HResult.OK; + } + + public int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel) + { + var projectName = pHierProj.GetProjectFilePath(); + var thisProjectName = _pHierProj.GetProjectFilePath(); + if (projectName == thisProjectName) + { + return _debuggableProjectCfg.DebugLaunch((uint)_dbgLaunchFlag); + } + + return HResult.OK; + } + } } } From 7c4f9cf0bb00172db99a70fce5fd73384d2f4694 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 30 Oct 2024 09:51:04 -0700 Subject: [PATCH 13/24] dispose event listenr when stop project --- .../HotReload/ProjectHotReloadSessionManager.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 40e0a575e1e..cf46b0f72a8 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -370,15 +370,9 @@ private async Task RestartProjectAsync( Assumes.NotNull(_project.Services.HostObject); await _projectThreadingService.SwitchToUIThread(); - // Step 0: Dispose existing solution build events subscription if any - if (_solutionBuildEventsSubscription is not null) - { - await _solutionBuildEventsSubscription.DisposeAsync(); - _solutionBuildEventsSubscription = null; - } - // Step 1: Stop running project await StopProjectAsync(hotReloadState, cancellationToken); + Assumes.Null(_solutionBuildEventsSubscription); // Step 2: Debug or NonDebug? uint dbgLaunchFlag = isRunningUnderDebug ? (uint)0 : (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_NoDebug; @@ -464,6 +458,13 @@ async ValueTask StopProjectInternalAsync() { await _projectHotReloadNotificationService.Value.SetHotReloadStateAsync(isInHotReload: false); } + + // Dispose the solution build events subscription if there are no active sessions + if (_solutionBuildEventsSubscription is not null) + { + await _solutionBuildEventsSubscription.DisposeAsync(); + _solutionBuildEventsSubscription = null; + } } return true; From 86a6bc3ce20ffe55fb05125f1482fba1aef3967e Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Thu, 31 Oct 2024 15:45:57 -0700 Subject: [PATCH 14/24] update --- .../ProjectHotReloadSessionManager.cs | 81 +------------------ 1 file changed, 4 insertions(+), 77 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index cf46b0f72a8..73d193d9f72 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -375,31 +375,16 @@ private async Task RestartProjectAsync( Assumes.Null(_solutionBuildEventsSubscription); // Step 2: Debug or NonDebug? - uint dbgLaunchFlag = isRunningUnderDebug ? (uint)0 : (uint)__VSDBGLAUNCHFLAGS.DBGLAUNCH_NoDebug; + uint dbgLaunchFlag = isRunningUnderDebug ? (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCHDEBUG : (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCH; - // Step 3: Find IVsDebuggableProjectCfg + // Step 3: Build and Launch Debug var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; - var activeCfg = _solutionBuildManager.Value.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, projectVsHierarchy); - Equals(activeCfg.Length, 1); - var result = activeCfg[0].get_CfgType(typeof(IVsDebuggableProjectCfg).GUID, out var cfgType); - Equals(result, HResult.OK); - var debuggableCfg = Marshal.GetObjectForIUnknown(cfgType) as IVsDebuggableProjectCfg; - Assumes.NotNull(debuggableCfg); - - result = debuggableCfg.get_BuildableProjectCfg(out var buildableProjectCfg); - Equals(result, HResult.OK); - Assumes.NotNull(buildableProjectCfg); - - // register for the solution build events - var slnEvent = new SlnEvent(projectVsHierarchy, debuggableCfg, (int)dbgLaunchFlag); - _solutionBuildEventsSubscription = await _solutionBuildManager.Value.SubscribeSolutionEventsAsync(slnEvent); - - result = _solutionBuildManager.Value.StartSimpleUpdateProjectConfiguration( + var result = _solutionBuildManager.Value.StartSimpleUpdateProjectConfiguration( pIVsHierarchyToBuild: projectVsHierarchy, pIVsHierarchyDependent: null, pszDependentConfigurationCanonicalName: null, - dwFlags: (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD, + dwFlags: (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD | dbgLaunchFlag, dwDefQueryResults: (uint)VSSOLNBUILDQUERYRESULTS.VSSBQR_SAVEBEFOREBUILD_QUERY_YES, fSuppressUI: 0); @@ -550,63 +535,5 @@ public Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToke return ProjectHotReloadSessionManager.GetDeltaApplier(this); } } - - internal class SlnEvent : IVsUpdateSolutionEvents2 - { - private readonly IVsDebuggableProjectCfg _debuggableProjectCfg; - private readonly IVsHierarchy _pHierProj; - private readonly int _dbgLaunchFlag; - - // resolved when done - - public SlnEvent(IVsHierarchy pHierProj, IVsDebuggableProjectCfg debuggableProjectCfg, int dbgLaunchFlag) - { - _debuggableProjectCfg = debuggableProjectCfg; - _pHierProj = pHierProj; - _dbgLaunchFlag = dbgLaunchFlag; - } - - public int UpdateSolution_Begin(ref int pfCancelUpdate) - { - return HResult.OK; - } - - public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand) - { - return HResult.OK; - } - - public int UpdateSolution_StartUpdate(ref int pfCancelUpdate) - { - return HResult.OK; - } - - public int UpdateSolution_Cancel() - { - return HResult.OK; - } - - public int OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy) - { - return HResult.OK; - } - - public int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel) - { - return HResult.OK; - } - - public int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel) - { - var projectName = pHierProj.GetProjectFilePath(); - var thisProjectName = _pHierProj.GetProjectFilePath(); - if (projectName == thisProjectName) - { - return _debuggableProjectCfg.DebugLaunch((uint)_dbgLaunchFlag); - } - - return HResult.OK; - } - } } } From fea82ecbac5c18274f31e18efe76c5c5bc687c3f Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Fri, 1 Nov 2024 16:12:38 -0700 Subject: [PATCH 15/24] remove restarting seesion from project system side --- .../ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs | 1 - .../VS/HotReload/ProjectHotReloadSessionManager.cs | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 0a42ef8ea7a..aa5ed76acf1 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -117,7 +117,6 @@ public async Task StopSessionAsync(CancellationToken cancellationToken) if (_sessionActive) { _sessionActive = false; - _isRunningUnderDebugger = false; await _hotReloadAgentManagerClient.Value.AgentTerminatedAsync(this, cancellationToken); WriteToOutputWindow( new HotReloadLogMessage( diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 73d193d9f72..d911cb89f6a 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -370,10 +370,6 @@ private async Task RestartProjectAsync( Assumes.NotNull(_project.Services.HostObject); await _projectThreadingService.SwitchToUIThread(); - // Step 1: Stop running project - await StopProjectAsync(hotReloadState, cancellationToken); - Assumes.Null(_solutionBuildEventsSubscription); - // Step 2: Debug or NonDebug? uint dbgLaunchFlag = isRunningUnderDebug ? (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCHDEBUG : (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCH; From e622839ea5bbc805922a76dcf0fcae5fdf3b4c24 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Tue, 12 Nov 2024 12:44:46 -0800 Subject: [PATCH 16/24] clean up --- Directory.Packages.props | 2 +- .../ProjectSystemSetup.csproj | 1 + .../VS/Build/ISolutionBuildManager.cs | 8 ----- .../VS/Build/SolutionBuildManager.cs | 36 +------------------ 4 files changed, 3 insertions(+), 44 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 89a0ccc6d1b..7ee4a14f952 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,7 +5,7 @@ true - 17.13.0-beta.24518.1 + 17.13.0-beta.24561.1 <_ManagedProjectName>Microsoft.VisualStudio.ProjectSystem.Managed + RoslynDev diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs index 392ab86660e..7dbeb8fffe6 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs @@ -28,12 +28,6 @@ internal interface ISolutionBuildManager IVsHierarchy[] GetProjectDependencies(IVsHierarchy hierarchy); - int SetStartupProject(IVsHierarchy hierarchy); - - int DebugLaunch(uint grfLaunch); - - int QueryDebugLaunch(uint grfLaunch); - void StartUpdateSpecificProjectConfigurations(IVsHierarchy[] hierarchy, uint[] buildFlags, uint dwFlags); int StartSimpleUpdateProjectConfiguration( @@ -43,7 +37,5 @@ int StartSimpleUpdateProjectConfiguration( uint dwFlags, uint dwDefQueryResults, int fSuppressUI); - - IVsProjectCfg2[] FindActiveProjectCfg(IntPtr pvReserved1, IntPtr pvReserved2, IVsHierarchy pIVsHierarchy_RequestedProject); } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs index 06248383f1b..68aa6276cfd 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs @@ -1,7 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Runtime.InteropServices; -using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Threading; @@ -99,7 +97,7 @@ public int QueryBuildManagerBusy() JoinableFactory.Context.VerifyIsOnMainThread(); ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.QueryBuildManagerBusy(out int flags)); - + return flags; } @@ -113,13 +111,6 @@ public uint QueryBuildManagerBusyEx() return flags; } - public int QueryDebugLaunch(uint grfLaunch) - { - Assumes.NotNull(_vsSolutionBuildManager2); - JoinableFactory.Context.VerifyIsOnMainThread(); - ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.QueryDebugLaunch(grfLaunch, out int pfCanLaunch)); - return pfCanLaunch; - } public void SaveDocumentsBeforeBuild(IVsHierarchy hierarchy, uint itemId, uint docCookie) { @@ -178,22 +169,6 @@ public void StartUpdateSpecificProjectConfigurations(IVsHierarchy[] hierarchy, u fSuppressUI: 0)); } - public int SetStartupProject(IVsHierarchy hierarchy) - { - Assumes.NotNull(_vsSolutionBuildManager2); - - JoinableFactory.Context.VerifyIsOnMainThread(); - return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.set_StartupProject(hierarchy)); - } - - public int DebugLaunch(uint grfLaunch) - { - Assumes.NotNull(_vsSolutionBuildManager2); - JoinableFactory.Context.VerifyIsOnMainThread(); - - return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.DebugLaunch(grfLaunch)); - } - public int StartSimpleUpdateProjectConfiguration(IVsHierarchy pIVsHierarchyToBuild, IVsHierarchy? pIVsHierarchyDependent, string? pszDependentConfigurationCanonicalName, uint dwFlags, uint dwDefQueryResults, int fSuppressUI) { Assumes.NotNull(_vsSolutionBuildManager2); @@ -201,14 +176,5 @@ public int StartSimpleUpdateProjectConfiguration(IVsHierarchy pIVsHierarchyToBui return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.StartSimpleUpdateProjectConfiguration(pIVsHierarchyToBuild, pIVsHierarchyDependent, pszDependentConfigurationCanonicalName, dwFlags, dwDefQueryResults, fSuppressUI)); } - - public IVsProjectCfg2[] FindActiveProjectCfg(IntPtr pvReserved1, IntPtr pvReserved2, IVsHierarchy pIVsHierarchy_RequestedProject) - { - Assumes.NotNull(_vsSolutionBuildManager2); - JoinableFactory.Context.VerifyIsOnMainThread(); - IVsProjectCfg2[] ppIVsProjectCfg_Active = new IVsProjectCfg2[1]; - ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.FindActiveProjectCfg(pvReserved1, pvReserved2, pIVsHierarchy_RequestedProject, ppIVsProjectCfg_Active)); - return ppIVsProjectCfg_Active; - } } } From cad337fe9f5e7041caed3acc215218738efa62ca Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Tue, 12 Nov 2024 15:58:05 -0800 Subject: [PATCH 17/24] fix comment --- .../ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs | 3 +-- .../ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs | 7 ++----- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs index ccd52dfac3c..3abdbe144d4 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs @@ -36,8 +36,7 @@ public ProjectHotReloadAgent( _hotReloadAgentManagerClient, _hotReloadDiagnosticOutputService, _managedDeltaApplierCreator, - callback, - _solutionBuildManager); + callback); } public IProjectHotReloadSession? CreateHotReloadSession(string id, string runtimeVersion, IProjectHotReloadSessionCallback callback) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index aa5ed76acf1..d18c8775315 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -16,7 +16,6 @@ internal class ProjectHotReloadSession : IManagedHotReloadAgent, IManagedHotRelo private readonly Lazy _hotReloadOutputService; private readonly Lazy _deltaApplierCreator; private readonly IProjectHotReloadSessionCallback _callback; - private readonly Lazy _solutionBuildManager; private bool _sessionActive; @@ -31,8 +30,7 @@ public ProjectHotReloadSession( Lazy hotReloadAgentManagerClient, Lazy hotReloadOutputService, Lazy deltaApplierCreator, - IProjectHotReloadSessionCallback callback, - Lazy solutionBuildManager) + IProjectHotReloadSessionCallback callback) { Name = name; _variant = variant.ToString(); @@ -41,7 +39,6 @@ public ProjectHotReloadSession( _hotReloadOutputService = hotReloadOutputService; _deltaApplierCreator = deltaApplierCreator; _callback = callback; - _solutionBuildManager = solutionBuildManager; } // IProjectHotReloadSession @@ -286,7 +283,7 @@ public async ValueTask StopAsync(CancellationToken cancellationToken) public ValueTask SupportsRestartAsync(CancellationToken cancellationToken) { - return new ValueTask(_callback is HotReloadState); + return new ValueTask(_callback.SupportsRestart); } private void WriteToOutputWindow(HotReloadLogMessage hotReloadLogMessage, CancellationToken cancellationToken) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index d911cb89f6a..934d4ccf9d1 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -492,7 +492,7 @@ internal class HotReloadState : IProjectHotReloadSessionCallback public ProjectHotReloadSessionManager SessionManager { get; } - public bool SupportsRestart => false; + public bool SupportsRestart => true; public UnconfiguredProject? Project => SessionManager._project; From 240c2a54a34aa11343118c8a070ade1b2d23fcb7 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Tue, 12 Nov 2024 16:02:55 -0800 Subject: [PATCH 18/24] remove unused subscription listener --- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 934d4ccf9d1..12ffa3467d1 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -34,7 +34,6 @@ internal class ProjectHotReloadSessionManager : OnceInitializedOnceDisposedAsync private readonly Dictionary _activeSessions = []; private HotReloadState? _pendingSessionState = null; private int _nextUniqueId = 1; - private IAsyncDisposable? _solutionBuildEventsSubscription = null; public bool HasActiveHotReloadSessions => _activeSessions.Count != 0; @@ -370,10 +369,10 @@ private async Task RestartProjectAsync( Assumes.NotNull(_project.Services.HostObject); await _projectThreadingService.SwitchToUIThread(); - // Step 2: Debug or NonDebug? + // Step 1: Debug or NonDebug? uint dbgLaunchFlag = isRunningUnderDebug ? (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCHDEBUG : (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCH; - // Step 3: Build and Launch Debug + // Step 2: Build and Launch Debug var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; var result = _solutionBuildManager.Value.StartSimpleUpdateProjectConfiguration( @@ -439,13 +438,6 @@ async ValueTask StopProjectInternalAsync() { await _projectHotReloadNotificationService.Value.SetHotReloadStateAsync(isInHotReload: false); } - - // Dispose the solution build events subscription if there are no active sessions - if (_solutionBuildEventsSubscription is not null) - { - await _solutionBuildEventsSubscription.DisposeAsync(); - _solutionBuildEventsSubscription = null; - } } return true; From 135231a0a681eb575f680f5b9a07ce7adf0c24fa Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 13 Nov 2024 12:08:17 -0800 Subject: [PATCH 19/24] revert change in solution build manager --- .../ProjectSystemSetup.csproj | 1 - .../VS/Build/ISolutionBuildManager.cs | 8 -------- .../VS/Build/SolutionBuildManager.cs | 12 ++---------- .../ProjectHotReloadSessionManager.cs | 18 +++++++++++++----- .../ProjectHotReloadSessionManagerTests.cs | 5 ++++- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/setup/ProjectSystemSetup/ProjectSystemSetup.csproj b/setup/ProjectSystemSetup/ProjectSystemSetup.csproj index 59b495d6236..8bfc0729ffd 100644 --- a/setup/ProjectSystemSetup/ProjectSystemSetup.csproj +++ b/setup/ProjectSystemSetup/ProjectSystemSetup.csproj @@ -8,7 +8,6 @@ <_ManagedProjectName>Microsoft.VisualStudio.ProjectSystem.Managed - RoslynDev diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs index 7dbeb8fffe6..41f5b90a5a7 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/ISolutionBuildManager.cs @@ -29,13 +29,5 @@ internal interface ISolutionBuildManager IVsHierarchy[] GetProjectDependencies(IVsHierarchy hierarchy); void StartUpdateSpecificProjectConfigurations(IVsHierarchy[] hierarchy, uint[] buildFlags, uint dwFlags); - - int StartSimpleUpdateProjectConfiguration( - IVsHierarchy pIVsHierarchyToBuild, - IVsHierarchy? pIVsHierarchyDependent, - string? pszDependentConfigurationCanonicalName, - uint dwFlags, - uint dwDefQueryResults, - int fSuppressUI); } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs index 68aa6276cfd..369e1697a1f 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Build/SolutionBuildManager.cs @@ -97,7 +97,7 @@ public int QueryBuildManagerBusy() JoinableFactory.Context.VerifyIsOnMainThread(); ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.QueryBuildManagerBusy(out int flags)); - + return flags; } @@ -108,10 +108,10 @@ public uint QueryBuildManagerBusyEx() JoinableFactory.Context.VerifyIsOnMainThread(); ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager3.QueryBuildManagerBusyEx(out uint flags)); + return flags; } - public void SaveDocumentsBeforeBuild(IVsHierarchy hierarchy, uint itemId, uint docCookie) { Assumes.NotNull(_vsSolutionBuildManager2); @@ -168,13 +168,5 @@ public void StartUpdateSpecificProjectConfigurations(IVsHierarchy[] hierarchy, u dwFlags: dwFlags, fSuppressUI: 0)); } - - public int StartSimpleUpdateProjectConfiguration(IVsHierarchy pIVsHierarchyToBuild, IVsHierarchy? pIVsHierarchyDependent, string? pszDependentConfigurationCanonicalName, uint dwFlags, uint dwDefQueryResults, int fSuppressUI) - { - Assumes.NotNull(_vsSolutionBuildManager2); - JoinableFactory.Context.VerifyIsOnMainThread(); - - return ErrorHandler.ThrowOnFailure(_vsSolutionBuildManager2.StartSimpleUpdateProjectConfiguration(pIVsHierarchyToBuild, pIVsHierarchyDependent, pszDependentConfigurationCanonicalName, dwFlags, dwDefQueryResults, fSuppressUI)); - } } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 12ffa3467d1..0fce1e02fd1 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -23,7 +23,8 @@ internal class ProjectHotReloadSessionManager : OnceInitializedOnceDisposedAsync private readonly Lazy _projectHotReloadAgent; private readonly Lazy _hotReloadDiagnosticOutputService; private readonly Lazy _projectHotReloadNotificationService; - private readonly Lazy _solutionBuildManager; + private readonly IVsService _vsSolutionBuildManagerService; + private IVsSolutionBuildManager2? _vsSolutionBuildManager2; private readonly IProjectThreadingService _projectThreadingService; // Protect the state from concurrent access. For example, our Process.Exited event @@ -46,7 +47,7 @@ public ProjectHotReloadSessionManager( Lazy projectHotReloadAgent, Lazy hotReloadDiagnosticOutputService, Lazy projectHotReloadNotificationService, - Lazy solutionBuilderManager) + IVsService solutionBuildManagerService) : base(threadingService.JoinableTaskContext) { _project = project; @@ -56,7 +57,7 @@ public ProjectHotReloadSessionManager( _projectHotReloadAgent = projectHotReloadAgent; _hotReloadDiagnosticOutputService = hotReloadDiagnosticOutputService; _projectHotReloadNotificationService = projectHotReloadNotificationService; - _solutionBuildManager = solutionBuilderManager; + _vsSolutionBuildManagerService = solutionBuildManagerService; _semaphore = ReentrantSemaphore.Create( initialCount: 1, @@ -369,20 +370,27 @@ private async Task RestartProjectAsync( Assumes.NotNull(_project.Services.HostObject); await _projectThreadingService.SwitchToUIThread(); + if (_vsSolutionBuildManager2 is null) + { + _vsSolutionBuildManager2 = await _vsSolutionBuildManagerService.GetValueAsync(cancellationToken); + } + // Step 1: Debug or NonDebug? uint dbgLaunchFlag = isRunningUnderDebug ? (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCHDEBUG : (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_LAUNCH; // Step 2: Build and Launch Debug var projectVsHierarchy = (IVsHierarchy)_project.Services.HostObject; - var result = _solutionBuildManager.Value.StartSimpleUpdateProjectConfiguration( + var result = _vsSolutionBuildManager2.StartSimpleUpdateProjectConfiguration( pIVsHierarchyToBuild: projectVsHierarchy, pIVsHierarchyDependent: null, pszDependentConfigurationCanonicalName: null, dwFlags: (uint)VSSOLNBUILDUPDATEFLAGS.SBF_OPERATION_BUILD | dbgLaunchFlag, dwDefQueryResults: (uint)VSSOLNBUILDQUERYRESULTS.VSSBQR_SAVEBEFOREBUILD_QUERY_YES, fSuppressUI: 0); - + + ErrorHandler.ThrowOnFailure(result); + return result == HResult.OK; } diff --git a/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs b/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs index 8594238704e..0e83bb2f2b7 100644 --- a/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs +++ b/tests/Microsoft.VisualStudio.ProjectSystem.Managed.VS.UnitTests/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManagerTests.cs @@ -2,6 +2,7 @@ using Microsoft.VisualStudio.ProjectSystem.Debug; using Microsoft.VisualStudio.ProjectSystem.VS.Build; +using Microsoft.VisualStudio.Shell.Interop; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { @@ -170,6 +171,8 @@ private static ProjectHotReloadSessionManager CreateHotReloadSessionManager(Conf .ImplementGetConfiguredProjectForActiveFrameworkAsync(activeConfiguredProject) .Object; + var iVSSolutionBuildManagerServiceMock = new Mock>(); + var manager = new ProjectHotReloadSessionManager( UnconfiguredProjectFactory.Create(), IProjectThreadingServiceFactory.Create(), @@ -178,7 +181,7 @@ private static ProjectHotReloadSessionManager CreateHotReloadSessionManager(Conf new Lazy(() => IProjectHotReloadAgentFactory.Create()), new Lazy(() => IHotReloadDiagnosticOutputServiceFactory.Create(outputServiceCallback)), new Lazy(() => IProjectHotReloadNotificationServiceFactory.Create()), - new Lazy(() => ISolutionBuildManagerFactory.Create(null, null, false, false))); + iVSSolutionBuildManagerServiceMock.Object); return manager; } From c8bbcbcac2c89509a8e954b109aaa64f19b2115a Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 13 Nov 2024 12:28:03 -0800 Subject: [PATCH 20/24] make HotReloadState back to private again --- .../IProjectHotReloadSessionCallback.cs | 5 +++++ .../VS/HotReload/ProjectHotReloadAgent.cs | 6 +----- .../VS/HotReload/ProjectHotReloadSession.cs | 14 ++++++-------- .../HotReload/ProjectHotReloadSessionManager.cs | 16 ++++++++-------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs index 11fb5e141ea..11ce8331dc6 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs @@ -16,4 +16,9 @@ public interface IProjectHotReloadSessionCallback IDeltaApplier? GetDeltaApplier(); } + + internal interface IProjectHotReloadSessionCallback2 : IProjectHotReloadSessionCallback + { + Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken); + } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs index 3abdbe144d4..ea6f6415816 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadAgent.cs @@ -2,7 +2,6 @@ using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; -using Microsoft.VisualStudio.ProjectSystem.VS.Build; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload { @@ -12,19 +11,16 @@ internal class ProjectHotReloadAgent : IProjectHotReloadAgent private readonly Lazy _hotReloadAgentManagerClient; private readonly Lazy _hotReloadDiagnosticOutputService; private readonly Lazy _managedDeltaApplierCreator; - private readonly Lazy _solutionBuildManager; [ImportingConstructor] public ProjectHotReloadAgent( Lazy hotReloadAgentManagerClient, Lazy hotReloadDiagnosticOutputService, - Lazy managedDeltaApplierCreator, - Lazy solutionBuildManager) + Lazy managedDeltaApplierCreator) { _hotReloadAgentManagerClient = hotReloadAgentManagerClient; _hotReloadDiagnosticOutputService = hotReloadDiagnosticOutputService; _managedDeltaApplierCreator = managedDeltaApplierCreator; - _solutionBuildManager = solutionBuildManager; } public IProjectHotReloadSession? CreateHotReloadSession(string id, int variant, string runtimeVersion, IProjectHotReloadSessionCallback callback) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index d18c8775315..e617f661cbb 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -1,9 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. -using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue; using Microsoft.VisualStudio.Debugger.Contracts.HotReload; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; -using Microsoft.VisualStudio.ProjectSystem.VS.Build; using static Microsoft.VisualStudio.ProjectSystem.VS.HotReload.ProjectHotReloadSessionManager; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload @@ -255,14 +253,14 @@ public async ValueTask RestartAsync(CancellationToken cancellationToken) cancellationToken); - if (_callback is HotReloadState hrs) + if (_callback is IProjectHotReloadSessionCallback2 callBack2) { - await hrs.RestartProjectAsync(_isRunningUnderDebugger, cancellationToken); - - return; + await callBack2.RestartProjectAsync(_isRunningUnderDebugger, cancellationToken); + } + else + { + await _callback.RestartProjectAsync(cancellationToken); } - - await _callback.RestartProjectAsync(cancellationToken); } public async ValueTask StopAsync(CancellationToken cancellationToken) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index 0fce1e02fd1..a0f21e6ce4f 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -485,25 +485,25 @@ async Task ApplyHotReloadUpdateInternalAsync() } } - internal class HotReloadState : IProjectHotReloadSessionCallback + private class HotReloadState : IProjectHotReloadSessionCallback2 { + private readonly ProjectHotReloadSessionManager _sessionManager; + public Process? Process { get; set; } public IProjectHotReloadSession? Session { get; set; } - public ProjectHotReloadSessionManager SessionManager { get; } - public bool SupportsRestart => true; - public UnconfiguredProject? Project => SessionManager._project; + public UnconfiguredProject? Project => _sessionManager._project; public HotReloadState(ProjectHotReloadSessionManager sessionManager) { - SessionManager = sessionManager; + _sessionManager = sessionManager; } internal void OnProcessExited(object sender, EventArgs e) { - SessionManager.OnProcessExited(this); + _sessionManager.OnProcessExited(this); } public Task OnAfterChangesAppliedAsync(CancellationToken cancellationToken) @@ -513,7 +513,7 @@ public Task OnAfterChangesAppliedAsync(CancellationToken cancellationToken) public Task StopProjectAsync(CancellationToken cancellationToken) { - return SessionManager.StopProjectAsync(this, cancellationToken).AsTask(); + return _sessionManager.StopProjectAsync(this, cancellationToken).AsTask(); } public Task RestartProjectAsync(CancellationToken cancellationToken) @@ -523,7 +523,7 @@ public Task RestartProjectAsync(CancellationToken cancellationToken) public Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken) { - return SessionManager.RestartProjectAsync(this, isRunningUnderDebug, cancellationToken); + return _sessionManager.RestartProjectAsync(this, isRunningUnderDebug, cancellationToken); } public IDeltaApplier? GetDeltaApplier() From 299f64e5130f3405228861380b4552aa7adc79f5 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 13 Nov 2024 14:12:22 -0800 Subject: [PATCH 21/24] fix build error --- .../VS/HotReload/IProjectHotReloadSessionCallback.cs | 7 +++++++ .../ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs index 11ce8331dc6..5f55ac879a3 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs @@ -1,5 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Diagnostics; using Microsoft.VisualStudio.HotReload.Components.DeltaApplier; namespace Microsoft.VisualStudio.ProjectSystem.VS.HotReload @@ -19,6 +20,12 @@ public interface IProjectHotReloadSessionCallback internal interface IProjectHotReloadSessionCallback2 : IProjectHotReloadSessionCallback { + public UnconfiguredProject? Project { get; } + + public Process? Process { get; set; } + + public IProjectHotReloadSession? Session { get; set; } + Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken); } } diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index e617f661cbb..9c3eabc28be 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -300,7 +300,7 @@ private void EnsureDeltaApplierforSession() public ValueTask GetTargetLocalProcessIdAsync(CancellationToken cancellationToken) { - if (_callback is HotReloadState hotReloadState) + if (_callback is IProjectHotReloadSessionCallback2 hotReloadState) { return new ValueTask(hotReloadState.Process?.Id); } @@ -310,7 +310,7 @@ private void EnsureDeltaApplierforSession() public ValueTask GetProjectFullPathAsync(CancellationToken cancellationToken) { - if (_callback is HotReloadState hrs) + if (_callback is IProjectHotReloadSessionCallback2 hrs) { return new ValueTask(hrs.Project?.FullPath); } From 54b93b9f9f28b68cef8604fa18c776e0d7e4cf53 Mon Sep 17 00:00:00 2001 From: Xiaoyun Zhang Date: Wed, 13 Nov 2024 17:54:46 -0800 Subject: [PATCH 22/24] Update src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs Co-authored-by: Drew Noakes --- .../ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs index 9c3eabc28be..8e1e9a7d1c2 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSession.cs @@ -300,9 +300,9 @@ private void EnsureDeltaApplierforSession() public ValueTask GetTargetLocalProcessIdAsync(CancellationToken cancellationToken) { - if (_callback is IProjectHotReloadSessionCallback2 hotReloadState) + if (_callback is IProjectHotReloadSessionCallback2 callback2) { - return new ValueTask(hotReloadState.Process?.Id); + return new ValueTask(callback2.Process?.Id); } return new ValueTask(); @@ -310,9 +310,9 @@ private void EnsureDeltaApplierforSession() public ValueTask GetProjectFullPathAsync(CancellationToken cancellationToken) { - if (_callback is IProjectHotReloadSessionCallback2 hrs) + if (_callback is IProjectHotReloadSessionCallback2 callback2) { - return new ValueTask(hrs.Project?.FullPath); + return new ValueTask(callback2.Project?.FullPath); } return new ValueTask(); From 31c664e73468864939d0802d786fa790156d46d6 Mon Sep 17 00:00:00 2001 From: XiaoYun Zhang Date: Wed, 13 Nov 2024 17:55:26 -0800 Subject: [PATCH 23/24] fix comment --- .../VS/HotReload/ProjectHotReloadSessionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs index a0f21e6ce4f..4f84366b1b0 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs @@ -518,7 +518,7 @@ public Task StopProjectAsync(CancellationToken cancellationToken) public Task RestartProjectAsync(CancellationToken cancellationToken) { - return Task.FromResult(false); + return TaskResult.False; } public Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken) From e89e342ae5c64fa1bd0bec90795eb683f331d20a Mon Sep 17 00:00:00 2001 From: Xiaoyun Zhang Date: Wed, 13 Nov 2024 17:56:40 -0800 Subject: [PATCH 24/24] Update src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs Co-authored-by: Drew Noakes --- .../VS/HotReload/IProjectHotReloadSessionCallback.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs index 5f55ac879a3..b92f3148d2d 100644 --- a/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs +++ b/src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionCallback.cs @@ -20,11 +20,11 @@ public interface IProjectHotReloadSessionCallback internal interface IProjectHotReloadSessionCallback2 : IProjectHotReloadSessionCallback { - public UnconfiguredProject? Project { get; } + UnconfiguredProject? Project { get; } - public Process? Process { get; set; } + Process? Process { get; } - public IProjectHotReloadSession? Session { get; set; } + IProjectHotReloadSession? Session { get; } Task RestartProjectAsync(bool isRunningUnderDebug, CancellationToken cancellationToken); }