Skip to content

Commit cafc1a2

Browse files
Started re-implementing events without the DTE
1 parent c0c2784 commit cafc1a2

File tree

6 files changed

+302
-14
lines changed

6 files changed

+302
-14
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System;
2+
using Microsoft;
3+
using Microsoft.VisualStudio;
4+
using Microsoft.VisualStudio.Shell;
5+
using Microsoft.VisualStudio.Shell.Interop;
6+
7+
namespace Community.VisualStudio.Toolkit
8+
{
9+
/// <summary>
10+
/// Events related to the editor documents.
11+
/// </summary>
12+
public class BuildEvents : IVsUpdateSolutionEvents2
13+
{
14+
internal BuildEvents()
15+
{
16+
ThreadHelper.ThrowIfNotOnUIThread();
17+
var svc = ServiceProvider.GlobalProvider.GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager;
18+
Assumes.Present(svc);
19+
svc!.AdviseUpdateSolutionEvents(this, out _);
20+
}
21+
22+
/// <summary>
23+
/// Fires when the solution starts building.
24+
/// </summary>
25+
public event EventHandler? SolutionBuildStarted;
26+
27+
/// <summary>
28+
/// Fires when the solution is done building.
29+
/// </summary>
30+
public event EventHandler<bool>? SolutionBuildDone;
31+
32+
/// <summary>
33+
/// Fires when the solution build was cancelled
34+
/// </summary>
35+
public event EventHandler? SolutionBuilCancelled;
36+
37+
/// <summary>
38+
/// Fires when a project starts building.
39+
/// </summary>
40+
public event EventHandler<IVsHierarchy>? ProjectBuildStarted;
41+
42+
/// <summary>
43+
/// Fires when a project is done building.
44+
/// </summary>
45+
public event EventHandler<IVsHierarchy>? ProjectBuildDone;
46+
47+
/// <summary>
48+
/// Fires when a project starts cleaning.
49+
/// </summary>
50+
public event EventHandler<IVsHierarchy>? ProjectCleanStarted;
51+
52+
/// <summary>
53+
/// Fires when a project is done cleaning.
54+
/// </summary>
55+
public event EventHandler<IVsHierarchy>? ProjectCleanDone;
56+
57+
int IVsUpdateSolutionEvents.UpdateSolution_Begin(ref int pfCancelUpdate) => VSConstants.S_OK;
58+
int IVsUpdateSolutionEvents2.UpdateSolution_Begin(ref int pfCancelUpdate)
59+
{
60+
SolutionBuildStarted?.Invoke(this, EventArgs.Empty);
61+
return VSConstants.S_OK;
62+
}
63+
64+
int IVsUpdateSolutionEvents.UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand) => VSConstants.S_OK;
65+
int IVsUpdateSolutionEvents2.UpdateSolution_Done(int fSucceeded, int fModified, int fCancelCommand)
66+
{
67+
SolutionBuildDone?.Invoke(this, fSucceeded == 0);
68+
return VSConstants.S_OK;
69+
}
70+
71+
int IVsUpdateSolutionEvents.UpdateSolution_StartUpdate(ref int pfCancelUpdate) => VSConstants.S_OK;
72+
int IVsUpdateSolutionEvents2.UpdateSolution_StartUpdate(ref int pfCancelUpdate)
73+
{
74+
return VSConstants.S_OK;
75+
}
76+
77+
int IVsUpdateSolutionEvents2.UpdateSolution_Cancel() => VSConstants.S_OK;
78+
int IVsUpdateSolutionEvents.UpdateSolution_Cancel()
79+
{
80+
SolutionBuilCancelled?.Invoke(this, EventArgs.Empty);
81+
return VSConstants.S_OK;
82+
}
83+
84+
int IVsUpdateSolutionEvents.OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy) => VSConstants.S_OK;
85+
int IVsUpdateSolutionEvents2.OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
86+
{
87+
return VSConstants.S_OK;
88+
}
89+
90+
int IVsUpdateSolutionEvents2.UpdateProjectCfg_Begin(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, ref int pfCancel)
91+
{
92+
// This method is called when a specific project begins building.
93+
94+
// if clean project or solution, dwAction == 0x100000
95+
// if build project or solution, dwAction == 0x010000
96+
// if rebuild project or solution, dwAction == 0x410000
97+
98+
// Clean
99+
if (dwAction == 0x100000)
100+
{
101+
ProjectCleanStarted?.Invoke(this, pHierProj);
102+
}
103+
// Build and rebuild
104+
else
105+
{
106+
ProjectBuildStarted?.Invoke(this, pHierProj);
107+
}
108+
109+
return VSConstants.S_OK;
110+
}
111+
112+
int IVsUpdateSolutionEvents2.UpdateProjectCfg_Done(IVsHierarchy pHierProj, IVsCfg pCfgProj, IVsCfg pCfgSln, uint dwAction, int fSuccess, int fCancel)
113+
{
114+
// This method is called when a specific project finishes building.
115+
116+
// Clean
117+
if (dwAction == 0x100000)
118+
{
119+
ProjectCleanDone?.Invoke(this, pHierProj);
120+
}
121+
// Build and rebuild
122+
else
123+
{
124+
ProjectBuildDone?.Invoke(this, pHierProj);
125+
}
126+
127+
return VSConstants.S_OK;
128+
}
129+
}
130+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using Microsoft.VisualStudio;
3+
using Microsoft.VisualStudio.Shell;
4+
using Microsoft.VisualStudio.Shell.Interop;
5+
6+
namespace Community.VisualStudio.Toolkit
7+
{
8+
/// <summary>
9+
/// Events related to the editor documents.
10+
/// </summary>
11+
public class DocumentEvents : IVsRunningDocTableEvents
12+
{
13+
private readonly RunningDocumentTable _rdt;
14+
15+
internal DocumentEvents()
16+
{
17+
_rdt = new RunningDocumentTable();
18+
_rdt.Advise(this);
19+
}
20+
21+
/// <summary>
22+
/// Happens when a file is saved to disk.
23+
/// </summary>
24+
public event EventHandler<string>? Saved;
25+
26+
/// <summary>
27+
/// Fires after the document was opened in the editor.
28+
/// </summary>
29+
public event EventHandler<string>? Opened;
30+
31+
/// <summary>
32+
/// Fires after the document was closed.s
33+
/// </summary>
34+
public event EventHandler<string>? Closed;
35+
36+
int IVsRunningDocTableEvents.OnAfterFirstDocumentLock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
37+
{
38+
var file = _rdt.GetDocumentInfo(docCookie).Moniker;
39+
Opened!.Invoke(this, file);
40+
41+
return VSConstants.S_OK;
42+
}
43+
44+
int IVsRunningDocTableEvents.OnBeforeLastDocumentUnlock(uint docCookie, uint dwRDTLockType, uint dwReadLocksRemaining, uint dwEditLocksRemaining)
45+
{
46+
var file = _rdt.GetDocumentInfo(docCookie).Moniker;
47+
Closed!.Invoke(this, file);
48+
49+
return VSConstants.S_OK;
50+
}
51+
52+
int IVsRunningDocTableEvents.OnAfterSave(uint docCookie)
53+
{
54+
var file = _rdt.GetDocumentInfo(docCookie).Moniker;
55+
Saved?.Invoke(this, file);
56+
57+
return VSConstants.S_OK;
58+
}
59+
60+
int IVsRunningDocTableEvents.OnAfterAttributeChange(uint docCookie, uint grfAttribs)
61+
{
62+
return VSConstants.S_OK;
63+
}
64+
65+
int IVsRunningDocTableEvents.OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame)
66+
{
67+
return VSConstants.S_OK;
68+
}
69+
70+
int IVsRunningDocTableEvents.OnAfterDocumentWindowHide(uint docCookie, IVsWindowFrame pFrame)
71+
{
72+
return VSConstants.S_OK;
73+
}
74+
}
75+
}

src/Community.VisualStudio.Toolkit.Shared/Services/Events.cs renamed to src/Community.VisualStudio.Toolkit.Shared/Events/Events.cs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ internal Events()
1818
_events = (Events2)dte.Events;
1919
}
2020

21-
private BuildEvents? _buildEvents;
22-
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
23-
public BuildEvents? BuildEvents => _buildEvents ??= _events?.BuildEvents;
24-
21+
/// <summary>
22+
/// Events related to the editor documents.
23+
/// </summary>
24+
public BuildEvents BuildEvents => new();
2525

26+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
2627
private CodeModelEvents? _codeModelEvents;
2728
public CodeModelEvents? CodeModelEvents => _codeModelEvents ??= _events?.CodeModelEvents;
2829

@@ -42,9 +43,10 @@ internal Events()
4243
private DebuggerProcessEvents? _debuggerProcessEvents;
4344
public DebuggerProcessEvents? DebuggerProcessEvents => _debuggerProcessEvents ??= _events?.DebuggerProcessEvents;
4445

45-
46-
private DocumentEvents? _documentEvents;
47-
public DocumentEvents? DocumentEvents => _documentEvents ??= _events?.DocumentEvents;
46+
/// <summary>
47+
/// Events related to the editor documents.
48+
/// </summary>
49+
public DocumentEvents DocumentEvents => new();
4850

4951

5052
private DTEEvents? _dteEvents;
@@ -78,9 +80,10 @@ internal Events()
7880
private SelectionEvents? _selectionEvents;
7981
public SelectionEvents? SelectionEvents => _selectionEvents ??= _events?.SelectionEvents;
8082

81-
82-
private SolutionEvents? _solutionEvents;
83-
public SolutionEvents? SolutionEvents => _solutionEvents ??= _events?.SolutionEvents;
83+
/// <summary>
84+
/// Events related to the editor documents.
85+
/// </summary>
86+
public SolutionEvents SolutionEvents => new();
8487

8588

8689
private ProjectItemsEvents? _solutionItemEvents;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using Microsoft.VisualStudio.Shell.Events;
3+
using e = Microsoft.VisualStudio.Shell.Events.SolutionEvents;
4+
5+
namespace Community.VisualStudio.Toolkit
6+
{
7+
/// <summary>
8+
/// Events related to the editor documents.
9+
/// </summary>
10+
public class SolutionEvents
11+
{
12+
internal SolutionEvents()
13+
{ }
14+
15+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
16+
public event EventHandler OnAfterCloseSolution
17+
{
18+
add { e.OnAfterCloseSolution += value; }
19+
remove { e.OnAfterCloseSolution -= value; }
20+
}
21+
22+
public event EventHandler<LoadProjectEventArgs> OnAfterLoadProject
23+
{
24+
add { e.OnAfterLoadProject += value; }
25+
remove { e.OnAfterLoadProject -= value; }
26+
}
27+
28+
public event EventHandler<OpenProjectEventArgs> OnAfterOpenProject
29+
{
30+
add { e.OnAfterOpenProject += value; }
31+
remove { e.OnAfterOpenProject -= value; }
32+
}
33+
34+
public event EventHandler<OpenSolutionEventArgs> OnAfterOpenSolution
35+
{
36+
add { e.OnAfterOpenSolution += value; }
37+
remove { e.OnAfterOpenSolution -= value; }
38+
}
39+
40+
public event EventHandler<CloseProjectEventArgs> OnBeforeCloseProject
41+
{
42+
add { e.OnBeforeCloseProject += value; }
43+
remove { e.OnBeforeCloseProject -= value; }
44+
}
45+
46+
public event EventHandler OnBeforeCloseSolution
47+
{
48+
add { e.OnBeforeCloseSolution += value; }
49+
remove { e.OnBeforeCloseSolution -= value; }
50+
}
51+
52+
public event EventHandler<LoadProjectEventArgs> OnBeforeUnloadProject
53+
{
54+
add { e.OnBeforeUnloadProject += value; }
55+
remove { e.OnBeforeUnloadProject -= value; }
56+
}
57+
58+
public event EventHandler<HierarchyEventArgs> OnAfterRenameProject
59+
{
60+
add { e.OnAfterRenameProject += value; }
61+
remove { e.OnAfterRenameProject -= value; }
62+
}
63+
64+
public event EventHandler<BeforeOpenProjectEventArgs> OnBeforeOpenProject
65+
{
66+
add { e.OnBeforeOpenProject += value; }
67+
remove { e.OnBeforeOpenProject -= value; }
68+
}
69+
70+
public event EventHandler<BeforeOpenSolutionEventArgs> OnBeforeOpenSolution
71+
{
72+
add { e.OnBeforeOpenSolution += value; }
73+
remove { e.OnBeforeOpenSolution -= value; }
74+
}
75+
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
76+
}
77+
}

src/Community.VisualStudio.Toolkit.Shared/ExtensionMethods/SolutionExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ public static async Task<bool> BuildAsync(this Solution solution)
2424

2525
if (VS.Events.BuildEvents != null)
2626
{
27-
VS.Events.BuildEvents.OnBuildDone += BuildEvents_OnBuildDone;
27+
VS.Events.BuildEvents.SolutionBuildDone += BuildEvents_OnBuildDone;
2828
dte.Solution.SolutionBuild.Build(false);
2929

30-
void BuildEvents_OnBuildDone(vsBuildScope scope, vsBuildAction action)
30+
void BuildEvents_OnBuildDone(object sender, bool e)
3131
{
32-
VS.Events.BuildEvents!.OnBuildDone -= BuildEvents_OnBuildDone;
32+
VS.Events.BuildEvents.SolutionBuildDone -= BuildEvents_OnBuildDone;
3333

3434
// Returns 'true' if the number of failed projects == 0
3535
buildTaskCompletionSource.TrySetResult(dte.Solution.SolutionBuild.LastBuildInfo == 0);

src/Community.VisualStudio.Toolkit.Shared/VSSDK.Helpers.Shared.projitems

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
<ItemGroup>
1212
<Compile Include="$(MSBuildThisFileDirectory)Commands\CommandAttribute.cs" />
1313
<Compile Include="$(MSBuildThisFileDirectory)Editor\WpfTextViewCreationListener.cs" />
14+
<Compile Include="$(MSBuildThisFileDirectory)Events\BuildEvents.cs" />
15+
<Compile Include="$(MSBuildThisFileDirectory)Events\SolutionEvents.cs" />
16+
<Compile Include="$(MSBuildThisFileDirectory)Events\DocumentEvents.cs" />
1417
<Compile Include="$(MSBuildThisFileDirectory)ExtensionMethods\ExceptionExtensions.cs" />
1518
<Compile Include="$(MSBuildThisFileDirectory)ExtensionMethods\ImageMonikerExtensions.cs" />
1619
<Compile Include="$(MSBuildThisFileDirectory)ExtensionMethods\IVsHierarchyExtensions.cs" />
@@ -40,7 +43,7 @@
4043
<Compile Include="$(MSBuildThisFileDirectory)Themes\Themes.cs" />
4144
<Compile Include="$(MSBuildThisFileDirectory)Notifications\MessageBox.cs" />
4245
<Compile Include="$(MSBuildThisFileDirectory)Commands\Commanding.cs" />
43-
<Compile Include="$(MSBuildThisFileDirectory)Services\Events.cs" />
46+
<Compile Include="$(MSBuildThisFileDirectory)Events\Events.cs" />
4447
<Compile Include="$(MSBuildThisFileDirectory)ToolkitPackage.cs" />
4548
<Compile Include="$(MSBuildThisFileDirectory)ToolWindows\BaseToolWindow.cs" />
4649
<Compile Include="$(MSBuildThisFileDirectory)ToolWindows\IToolWindowProvider.cs" />

0 commit comments

Comments
 (0)