Trigger live reload feature after successful builds in VS
This commit is contained in:
parent
5dfa857eab
commit
71a3e31799
|
|
@ -59,10 +59,16 @@
|
||||||
-->
|
-->
|
||||||
<Target Name="_BlazorIssueLiveReloadNotification"
|
<Target Name="_BlazorIssueLiveReloadNotification"
|
||||||
AfterTargets="Build"
|
AfterTargets="Build"
|
||||||
Condition="'$(UseBlazorLiveReloading)'=='true' AND '$(_BlazorDidCopyFilesToOutputDirectory)'=='true' AND '$(BuildingInsideVisualStudio)'!='true'">
|
Condition="'$(UseBlazorLiveReloading)'=='true' AND '$(_BlazorDidCopyFilesToOutputDirectory)'=='true'">
|
||||||
<!-- Touch the signal file to trigger a reload -->
|
<PropertyGroup>
|
||||||
<WriteLinesToFile File="$(ProjectDir)$(OutputPath)$(BlazorBuildCompletedSignalPath)" Lines="_" />
|
<_BlazorBuildCompletedSignalFullPath>$(ProjectDir)$(OutputPath)$(BlazorBuildCompletedSignalPath)</_BlazorBuildCompletedSignalFullPath>
|
||||||
<Delete Files="$(ProjectDir)$(OutputPath)$(BlazorBuildCompletedSignalPath)" />
|
</PropertyGroup>
|
||||||
|
<!--
|
||||||
|
If this is a command-line build, touch the signal file to trigger a reload.
|
||||||
|
If it's a VS build, then the VS extension will write the signal file instead.
|
||||||
|
-->
|
||||||
|
<WriteLinesToFile Condition="'$(BuildingInsideVisualStudio)'!='true'" File="$(_BlazorBuildCompletedSignalFullPath)" Lines="_" />
|
||||||
|
<Delete Condition="'$(BuildingInsideVisualStudio)'!='true'" Files="$(_BlazorBuildCompletedSignalFullPath)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<!-- Preparing blazor files for output:
|
<!-- Preparing blazor files for output:
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.VisualStudio.Shell;
|
using Microsoft.VisualStudio.Shell;
|
||||||
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
|
|
||||||
namespace Microsoft.VisualStudio.BlazorExtension
|
namespace Microsoft.VisualStudio.BlazorExtension
|
||||||
{
|
{
|
||||||
|
|
@ -11,8 +12,24 @@ namespace Microsoft.VisualStudio.BlazorExtension
|
||||||
[PackageRegistration(UseManagedResourcesOnly = true)]
|
[PackageRegistration(UseManagedResourcesOnly = true)]
|
||||||
[AboutDialogInfo(PackageGuidString, "ASP.NET Core Blazor Language Services", "#110", "112")]
|
[AboutDialogInfo(PackageGuidString, "ASP.NET Core Blazor Language Services", "#110", "112")]
|
||||||
[Guid(BlazorPackage.PackageGuidString)]
|
[Guid(BlazorPackage.PackageGuidString)]
|
||||||
|
[ProvideAutoLoad(UIContextGuids80.SolutionExists)]
|
||||||
public sealed class BlazorPackage : Package
|
public sealed class BlazorPackage : Package
|
||||||
{
|
{
|
||||||
public const string PackageGuidString = "d9fe04bc-57a7-4107-915e-3a5c2f9e19fb";
|
public const string PackageGuidString = "d9fe04bc-57a7-4107-915e-3a5c2f9e19fb";
|
||||||
|
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
RegisterLiveReloadBuildWatcher();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterLiveReloadBuildWatcher()
|
||||||
|
{
|
||||||
|
// No need to unadvise, as this only happens once anyway
|
||||||
|
ThreadHelper.ThrowIfNotOnUIThread();
|
||||||
|
var buildManager = (IVsSolutionBuildManager)GetService(typeof(SVsSolutionBuildManager));
|
||||||
|
var hr = buildManager.AdviseUpdateSolutionEvents(new LiveReloadBuildWatcher(), out var cookie);
|
||||||
|
Marshal.ThrowExceptionForHR(hr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using Microsoft.VisualStudio.ProjectSystem.Properties;
|
||||||
|
using Microsoft.VisualStudio.Shell;
|
||||||
|
using Microsoft.VisualStudio.Shell.Interop;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.VisualStudio.BlazorExtension
|
||||||
|
{
|
||||||
|
internal class LiveReloadBuildWatcher : IVsUpdateSolutionEvents2
|
||||||
|
{
|
||||||
|
const string BlazorProjectCapability = "Blazor";
|
||||||
|
|
||||||
|
private bool _isListeningForProjectBuilds = false;
|
||||||
|
private List<string> _signalFilePathsToNotify = new List<string>();
|
||||||
|
|
||||||
|
public int UpdateSolution_Begin(ref int pfCancelUpdate)
|
||||||
|
{
|
||||||
|
_signalFilePathsToNotify.Clear();
|
||||||
|
_isListeningForProjectBuilds = true;
|
||||||
|
return VSConstants.S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
|
||||||
|
{
|
||||||
|
_isListeningForProjectBuilds = false;
|
||||||
|
|
||||||
|
foreach (var fullPath in _signalFilePathsToNotify)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(fullPath, string.Empty);
|
||||||
|
File.Delete(fullPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AttemptLogError($"Blazor live reloading was unable to write to the signal " +
|
||||||
|
$"file at {fullPath}. To disable live reloading, set the property " +
|
||||||
|
$"'UseBlazorLiveReloading' to 'false' in your project file." +
|
||||||
|
$"\nThe exception was: {ex.Message}\n{ex.StackTrace}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return VSConstants.S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AttemptLogError(string message)
|
||||||
|
{
|
||||||
|
ThreadHelper.ThrowIfNotOnUIThread();
|
||||||
|
var outputWindow = (IVsOutputWindow)Package.GetGlobalService(typeof(SVsOutputWindow));
|
||||||
|
if (outputWindow != null)
|
||||||
|
{
|
||||||
|
outputWindow.GetPane(VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid, out var pane);
|
||||||
|
if (pane != null)
|
||||||
|
{
|
||||||
|
pane.OutputString(message);
|
||||||
|
pane.Activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int UpdateSolution_StartUpdate(ref int pfCancelUpdate)
|
||||||
|
=> VSConstants.S_OK;
|
||||||
|
|
||||||
|
public int UpdateSolution_Cancel()
|
||||||
|
=> VSConstants.S_OK;
|
||||||
|
|
||||||
|
public int OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
|
||||||
|
=> VSConstants.S_OK;
|
||||||
|
|
||||||
|
public int UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel)
|
||||||
|
=> VSConstants.S_OK;
|
||||||
|
|
||||||
|
public int UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel)
|
||||||
|
{
|
||||||
|
if (_isListeningForProjectBuilds
|
||||||
|
&& fSuccess == 1 // i.e., build succeeded
|
||||||
|
&& pHierProj.IsCapabilityMatch(BlazorProjectCapability))
|
||||||
|
{
|
||||||
|
var configuredProject = ((IVsBrowseObjectContext)pCfgProj).ConfiguredProject;
|
||||||
|
var projectLockService = configuredProject
|
||||||
|
.UnconfiguredProject
|
||||||
|
.ProjectService
|
||||||
|
.Services
|
||||||
|
.ProjectLockService;
|
||||||
|
|
||||||
|
ThreadHelper.JoinableTaskFactory.Run(async delegate
|
||||||
|
{
|
||||||
|
using (var access = await projectLockService.ReadLockAsync())
|
||||||
|
{
|
||||||
|
var project = await access.GetProjectAsync(configuredProject);
|
||||||
|
|
||||||
|
// Now we can evaluate MSBuild properties
|
||||||
|
var signalFileFullPath = project.GetPropertyValue("_BlazorBuildCompletedSignalFullPath");
|
||||||
|
if (!string.IsNullOrEmpty(signalFileFullPath))
|
||||||
|
{
|
||||||
|
_signalFilePathsToNotify.Add(signalFileFullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return VSConstants.S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -275,6 +275,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AboutDialogInfoAttribute.cs" />
|
<Compile Include="AboutDialogInfoAttribute.cs" />
|
||||||
<Compile Include="BlazorPackage.cs" />
|
<Compile Include="BlazorPackage.cs" />
|
||||||
|
<Compile Include="LiveReloadBuildWatcher.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue