Skip to content

Commit f75543e

Browse files
Activate hotreload session on both OnAfterLaunchAsync in ProjectLaunchTargetsProvider (#9813)
* Enhance Hot Reload session management by updating ActivateSessionAsync method signature and adding process termination details * Refactor OnComplete method to ensure proper execution of OnAfterLaunchAsync for IDebugProfileLaunchTargetsProvider4 * Fix XML documentation for launchedProcess parameter in ActivateSessionAsync method * Remove unused using directive for Microsoft.VisualStudio.Debugger.Contracts in ProjectLaunchTargetsProvider.cs
1 parent d688c60 commit f75543e

File tree

4 files changed

+43
-10
lines changed

4 files changed

+43
-10
lines changed

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Debug/LaunchProfilesDebugLaunchProvider.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,8 @@ public void OnComplete(int hr, uint debugTargetCount, VsDebugTargetProcessInfo[]
149149

150150
if (targetsProvider is IDebugProfileLaunchTargetsProvider4 targetsProvider4)
151151
{
152-
threadingService.ExecuteSynchronously(() => targetsProvider4.OnAfterLaunchAsync(launchOptions, activeProfile, processInfoArray));
153-
154152
IVsLaunchedProcess? vsLaunchedProcess = null;
153+
155154
lock (_launchedProcesses)
156155
{
157156
if (_launchedProcesses.Count == 1)
@@ -167,6 +166,10 @@ public void OnComplete(int hr, uint debugTargetCount, VsDebugTargetProcessInfo[]
167166
{
168167
threadingService.ExecuteSynchronously(() => targetsProvider5.OnAfterLaunchAsync(launchOptions, activeProfile, debugLaunchSettings[0], vsLaunchedProcess, processInfoArray[0]));
169168
}
169+
else
170+
{
171+
threadingService.ExecuteSynchronously(() => targetsProvider4.OnAfterLaunchAsync(launchOptions, activeProfile, processInfoArray));
172+
}
170173
}
171174
else if (targetsProvider is not null)
172175
{

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Debug/ProjectLaunchTargetsProvider.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,11 @@ Task IDebugProfileLaunchTargetsProvider.OnAfterLaunchAsync(DebugLaunchOptions la
110110
throw new InvalidOperationException($"Wrong overload of {nameof(OnAfterLaunchAsync)} called.");
111111
}
112112

113-
public Task OnAfterLaunchAsync(DebugLaunchOptions launchOptions, ILaunchProfile profile, IReadOnlyList<VsDebugTargetProcessInfo> processInfos)
113+
public async Task OnAfterLaunchAsync(DebugLaunchOptions launchOptions, ILaunchProfile profile, IReadOnlyList<VsDebugTargetProcessInfo> processInfos)
114114
{
115-
return Task.CompletedTask;
115+
var configuredProjectForDebug = await GetConfiguredProjectForDebugAsync();
116+
var hotReloadSessionManager = configuredProjectForDebug.GetExportedService<IProjectHotReloadSessionManager>();
117+
await hotReloadSessionManager.ActivateSessionAsync(null, processInfos[0]);
116118
}
117119

118120
public async Task OnAfterLaunchAsync(

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/IProjectHotReloadSessionManager.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ Task<bool> TryCreatePendingSessionAsync(
2929

3030
/// <summary>
3131
/// Activates the pending Hot Reload session and associates it with the specified process.
32+
/// The <paramref name="launchedProcess"/> and/or <paramref name="vsDebugTargetProcessInfo"/> provide the launch information of the process.
33+
/// When the session is terminated, the <paramref name="launchedProcess"/> will be used to terminate the process if it is not null.
34+
/// Otherwise, the PID from <paramref name="vsDebugTargetProcessInfo"/> will be used to terminate the process.
3235
/// </summary>
33-
Task ActivateSessionAsync(IVsLaunchedProcess launchedProcess, VsDebugTargetProcessInfo vsDebugTargetProcessInfo);
36+
/// <param name="launchedProcess">if not null, it will be used to terminate the process.</param>
37+
/// <param name="vsDebugTargetProcessInfo">The process information of the launched process.</param>
38+
Task ActivateSessionAsync(IVsLaunchedProcess? launchedProcess, VsDebugTargetProcessInfo vsDebugTargetProcessInfo);
3439
}

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/HotReload/ProjectHotReloadSessionManager.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ async Task ApplyHotReloadUpdateInternalAsync()
192192
}
193193
}
194194

195-
public Task ActivateSessionAsync(IVsLaunchedProcess launchedProcess, VsDebugTargetProcessInfo vsDebugTargetProcessInfo)
195+
public Task ActivateSessionAsync(IVsLaunchedProcess? launchedProcess, VsDebugTargetProcessInfo vsDebugTargetProcessInfo)
196196
{
197197
Assumes.True(_pendingSessionState is not null, "No pending hot reload session to activate.");
198198

@@ -261,11 +261,34 @@ public async Task<bool> StopProjectAsync(CancellationToken cancellationToken)
261261
return true;
262262
}
263263

264-
// need to call on UI thread
265-
await threadingService.SwitchToUIThread(cancellationToken);
264+
// prefer to terminate launched process first if we have it
265+
if (LaunchedProcess is not null)
266+
{
267+
// need to call on UI thread
268+
await threadingService.SwitchToUIThread(cancellationToken);
266269

267-
// Ignore the debug option launching flags since we're just terminating the process, not the entire debug session
268-
LaunchedProcess.Terminate(ignoreLaunchFlags: 1);
270+
// Ignore the debug option launching flags since we're just terminating the process, not the entire debug session
271+
LaunchedProcess.Terminate(ignoreLaunchFlags: 1);
272+
}
273+
else
274+
{
275+
// stop the process by killing it
276+
try
277+
{
278+
if (Process is not null && !Process.HasExited)
279+
{
280+
// First try to close the process nicely and if that doesn't work kill it.
281+
if (!Process.CloseMainWindow())
282+
{
283+
Process.Kill();
284+
}
285+
}
286+
}
287+
catch (InvalidOperationException)
288+
{
289+
// Process has already exited.
290+
}
291+
}
269292

270293
if (Session is not null)
271294
{

0 commit comments

Comments
 (0)