Skip to content

Commit 69c3587

Browse files
authored
Merge pull request #2463 from comintern/next
Add build number to logging, use `Application` to find host app, stubs event hooks.
2 parents 1de88d4 + 129b98f commit 69c3587

File tree

6 files changed

+310
-2
lines changed

6 files changed

+310
-2
lines changed

RetailCoder.VBE/App.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
using System.IO;
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Reflection;
24
using Infralution.Localization.Wpf;
35
using NLog;
6+
using NLog.Fluent;
47
using Rubberduck.Common;
58
using Rubberduck.Parsing;
69
using Rubberduck.Parsing.Symbols;
@@ -145,6 +148,7 @@ private void UpdateLoggingLevel()
145148
public void Startup()
146149
{
147150
EnsureLogFolderPathExists();
151+
LogRubberduckSart();
148152
LoadConfig();
149153
CheckForLegacyIndenterSettings();
150154
_appMenus.Initialize();
@@ -223,6 +227,21 @@ private void CheckForLegacyIndenterSettings()
223227
}
224228
}
225229

230+
private void LogRubberduckSart()
231+
{
232+
var version = GetType().Assembly.GetName().Version.ToString();
233+
GlobalDiagnosticsContext.Set("RubberduckVersion", version);
234+
var headers = new List<string>
235+
{
236+
string.Format("Rubberduck version {0} loading:", version),
237+
string.Format("\tOperating System: {0} {1}", Environment.OSVersion.VersionString, Environment.Is64BitOperatingSystem ? "x64" : "x86"),
238+
string.Format("\tHost Product: {0} {1}", Application.ProductName, Environment.Is64BitProcess ? "x64" : "x86"),
239+
string.Format("\tHost Version: {0}", Application.ProductVersion),
240+
string.Format("\tHost Executable: {0}", Path.GetFileName(Application.ExecutablePath)),
241+
};
242+
Logger.Log(LogLevel.Info, string.Join(Environment.NewLine, headers));
243+
}
244+
226245
private bool _disposed;
227246
public void Dispose()
228247
{

RetailCoder.VBE/NLog.dll.nlog

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
xsi:type="File"
88
name="file"
99
fileName="${specialfolder:folder=ApplicationData}/Rubberduck/Logs/RubberduckLog.txt"
10-
layout="${longdate};${uppercase:${level}};${logger};${message};${exception:format=tostring}"
10+
layout="${longdate};${uppercase:${level}}-${gdc:item=RubberduckVersion};${logger};${message};${exception:format=tostring}"
1111
archiveFileName="${specialfolder:folder=ApplicationData}/Rubberduck/Logs/archives/RubberduckLog.{#}.txt"
1212
archiveAboveSize="5242880"
1313
archiveNumbering="Sequence"

Rubberduck.VBEEditor/Extensions/IDEExtensions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,43 @@
55
using Rubberduck.VBEditor.Application;
66
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
77
using Rubberduck.VBEditor.SafeComWrappers.MSForms;
8+
using Exception = System.Exception;
89

910
namespace Rubberduck.VBEditor.Extensions
1011
{
1112
public static class VBEExtensions
1213
{
14+
private static readonly Dictionary<string, Type> HostAppMap = new Dictionary<string, Type>
15+
{
16+
{"EXCEL.EXE", typeof(ExcelApp)},
17+
{"WINWORD.EXE", typeof(WordApp)},
18+
{"MSACCESS.EXE", typeof(AccessApp)},
19+
{"POWERPNT.EXE", typeof(PowerPointApp)},
20+
{"OUTLOOK.EXE", typeof(OutlookApp)},
21+
{"WINPROJ.EXE", typeof(ProjectApp)},
22+
{"MSPUB.EXE", typeof(PublisherApp)},
23+
{"VISIO.EXE", typeof(VisioApp)},
24+
{"ACAD.EXE", typeof(AutoCADApp)},
25+
{"CORELDRW.EXE", typeof(CorelDRAWApp)},
26+
{"SLDWORKS.EXE", typeof(SolidWorksApp)},
27+
};
28+
1329
/// <summary> Returns the type of Office Application that is hosting the VBE. </summary>
1430
public static IHostApplication HostApplication(this IVBE vbe)
1531
{
32+
var host = Path.GetFileName(System.Windows.Forms.Application.ExecutablePath).ToUpperInvariant();
33+
//This needs the VBE as a ctor argument.
34+
if (host.Equals("SLDWORKS.EXE"))
35+
{
36+
return new SolidWorksApp(vbe);
37+
}
38+
//The rest don't.
39+
if (HostAppMap.ContainsKey(host))
40+
{
41+
return (IHostApplication)Activator.CreateInstance(HostAppMap[host]);
42+
}
43+
44+
//Guessing the above will work like 99.9999% of the time for supported applications.
1645
var project = vbe.ActiveVBProject;
1746
{
1847
if (project.IsWrappingNullReference)
@@ -114,6 +143,10 @@ public static IHostApplication HostApplication(this IVBE vbe)
114143
/// <summary> Returns whether the host supports unit tests.</summary>
115144
public static bool HostSupportsUnitTests(this IVBE vbe)
116145
{
146+
var host = Path.GetFileName(System.Windows.Forms.Application.ExecutablePath).ToUpperInvariant();
147+
if (HostAppMap.ContainsKey(host)) return true;
148+
//Guessing the above will work like 99.9999% of the time for supported applications.
149+
117150
var project = vbe.ActiveVBProject;
118151
{
119152
if (project.IsWrappingNullReference)
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
7+
namespace Rubberduck.VBEditor.Native
8+
{
9+
public static class WinEvents
10+
{
11+
#region Debugging symbol lookups
12+
public static readonly Dictionary<uint, string> EventNameLookup = new Dictionary<uint, string>
13+
{
14+
{0x1, "EVENT_SYSTEM_SOUND"},
15+
{0x2, "EVENT_SYSTEM_ALERT"},
16+
{0x3, "EVENT_SYSTEM_FOREGROUND"},
17+
{0x4, "EVENT_SYSTEM_MENUSTART"},
18+
{0x5, "EVENT_SYSTEM_MENUEND"},
19+
{0x6, "EVENT_SYSTEM_MENUPOPUPSTART"},
20+
{0x7, "EVENT_SYSTEM_MENUPOPUPEND"},
21+
{0x8, "EVENT_SYSTEM_CAPTURESTART"},
22+
{0x9, "EVENT_SYSTEM_CAPTUREEND"},
23+
{0xa, "EVENT_SYSTEM_MOVESIZESTART"},
24+
{0xb, "EVENT_SYSTEM_MOVESIZEEND"},
25+
{0xc, "EVENT_SYSTEM_CONTEXTHELPSTART"},
26+
{0xd, "EVENT_SYSTEM_CONTEXTHELPEND"},
27+
{0xe, "EVENT_SYSTEM_DRAGDROPSTART"},
28+
{0xf, "EVENT_SYSTEM_DRAGDROPEND"},
29+
{0x10, "EVENT_SYSTEM_DIALOGSTART"},
30+
{0x11, "EVENT_SYSTEM_DIALOGEND"},
31+
{0x12, "EVENT_SYSTEM_SCROLLINGSTART"},
32+
{0x13, "EVENT_SYSTEM_SCROLLINGEND"},
33+
{0x14, "EVENT_SYSTEM_SWITCHSTART"},
34+
{0x15, "EVENT_SYSTEM_SWITCHEND"},
35+
{0x16, "EVENT_SYSTEM_MINIMIZESTART"},
36+
{0x17, "EVENT_SYSTEM_MINIMIZEEND"},
37+
{0x8000, "EVENT_OBJECT_CREATE"},
38+
{0x8001, "EVENT_OBJECT_DESTROY"},
39+
{0x8002, "EVENT_OBJECT_SHOW"},
40+
{0x8003, "EVENT_OBJECT_HIDE"},
41+
{0x8004, "EVENT_OBJECT_REORDER"},
42+
{0x8005, "EVENT_OBJECT_FOCUS"},
43+
{0x8006, "EVENT_OBJECT_SELECTION"},
44+
{0x8007, "EVENT_OBJECT_SELECTIONADD"},
45+
{0x8008, "EVENT_OBJECT_SELECTIONREMOVE"},
46+
{0x8009, "EVENT_OBJECT_SELECTIONWITHIN"},
47+
{0x800A, "EVENT_OBJECT_STATECHANGE"},
48+
{0x800B, "EVENT_OBJECT_LOCATIONCHANGE"},
49+
{0x800C, "EVENT_OBJECT_NAMECHANGE"},
50+
{0x800D, "EVENT_OBJECT_DESCRIPTIONCHANGE"},
51+
{0x800E, "EVENT_OBJECT_VALUECHANGE"},
52+
{0x800F, "EVENT_OBJECT_PARENTCHANGE"},
53+
{0x8010, "EVENT_OBJECT_HELPCHANGE"},
54+
{0x8011, "EVENT_OBJECT_DEFACTIONCHANGE"},
55+
{0x8012, "EVENT_OBJECT_ACCELERATORCHANGE"},
56+
};
57+
58+
public static readonly Dictionary<uint, string> ObjectIdNameLookup = new Dictionary<uint, string>
59+
{
60+
{ 0x00000000, "OBJID_WINDOW" },
61+
{ 0xFFFFFFFF, "OBJID_SYSMENU" },
62+
{ 0xFFFFFFFE, "OBJID_TITLEBAR" },
63+
{ 0xFFFFFFFD, "OBJID_MENU" },
64+
{ 0xFFFFFFFC, "OBJID_CLIENT" },
65+
{ 0xFFFFFFFB, "OBJID_VSCROLL" },
66+
{ 0xFFFFFFFA, "OBJID_HSCROLL" },
67+
{ 0xFFFFFFF9, "OBJID_SIZEGRIP" },
68+
{ 0xFFFFFFF8, "OBJID_CARET" },
69+
{ 0xFFFFFFF7, "OBJID_CURSOR" },
70+
{ 0xFFFFFFF6, "OBJID_ALERT" },
71+
{ 0xFFFFFFF5, "OBJID_SOUND" },
72+
{ 0xFFFFFFF4, "OBJID_QUERYCLASSNAMEIDX" },
73+
{ 0xFFFFFFF0, "OBJID_NATIVEOM" },
74+
};
75+
#endregion
76+
77+
#region System enumerations
78+
// ReSharper disable InconsistentNaming
79+
//See https://msdn.microsoft.com/en-us/library/windows/desktop/dd318066(v=vs.85).aspx
80+
public enum EventConstant : uint
81+
{
82+
EVENT_MIN = 0x1,
83+
EVENT_SYSTEM_SOUND = 0x1,
84+
EVENT_SYSTEM_ALERT = 0x2,
85+
EVENT_SYSTEM_FOREGROUND = 0x3,
86+
EVENT_SYSTEM_MENUSTART = 0x4,
87+
EVENT_SYSTEM_MENUEND = 0x5,
88+
EVENT_SYSTEM_MENUPOPUPSTART = 0x6,
89+
EVENT_SYSTEM_MENUPOPUPEND = 0x7,
90+
EVENT_SYSTEM_CAPTURESTART = 0x8,
91+
EVENT_SYSTEM_CAPTUREEND = 0x9,
92+
EVENT_SYSTEM_MOVESIZESTART = 0xa,
93+
EVENT_SYSTEM_MOVESIZEEND = 0xb,
94+
EVENT_SYSTEM_CONTEXTHELPSTART = 0xc,
95+
EVENT_SYSTEM_CONTEXTHELPEND = 0xd,
96+
EVENT_SYSTEM_DRAGDROPSTART = 0xe,
97+
EVENT_SYSTEM_DRAGDROPEND = 0xf,
98+
EVENT_SYSTEM_DIALOGSTART = 0x10,
99+
EVENT_SYSTEM_DIALOGEND = 0x11,
100+
EVENT_SYSTEM_SCROLLINGSTART = 0x12,
101+
EVENT_SYSTEM_SCROLLINGEND = 0x13,
102+
EVENT_SYSTEM_SWITCHSTART = 0x14,
103+
EVENT_SYSTEM_SWITCHEND = 0x15,
104+
EVENT_SYSTEM_MINIMIZESTART = 0x16,
105+
EVENT_SYSTEM_MINIMIZEEND = 0x17,
106+
EVENT_OEM_DEFINED_START = 0x0101,
107+
EVENT_OEM_DEFINED_END = 0x01FF,
108+
EVENT_AIA_START = 0xA000,
109+
EVENT_AIA_END = 0xAFFF,
110+
EVENT_UIA_EVENTID_START = 0x4E00,
111+
EVENT_UIA_EVENTID_END = 0x4EFF,
112+
EVENT_UIA_PROPID_START = 0x7500,
113+
EVENT_UIA_PROPID_END = 0x75FF,
114+
EVENT_OBJECT_START = 0x8000,
115+
EVENT_OBJECT_CREATE = 0x8000,
116+
EVENT_OBJECT_DESTROY = 0x8001,
117+
EVENT_OBJECT_SHOW = 0x8002,
118+
EVENT_OBJECT_HIDE = 0x8003,
119+
EVENT_OBJECT_REORDER = 0x8004,
120+
EVENT_OBJECT_FOCUS = 0x8005,
121+
EVENT_OBJECT_SELECTION = 0x8006,
122+
EVENT_OBJECT_SELECTIONADD = 0x8007,
123+
EVENT_OBJECT_SELECTIONREMOVE = 0x8008,
124+
EVENT_OBJECT_SELECTIONWITHIN = 0x8009,
125+
EVENT_OBJECT_STATECHANGE = 0x800A,
126+
EVENT_OBJECT_LOCATIONCHANGE = 0x800B,
127+
EVENT_OBJECT_NAMECHANGE = 0x800C,
128+
EVENT_OBJECT_DESCRIPTIONCHANGE = 0x800D,
129+
EVENT_OBJECT_VALUECHANGE = 0x800E,
130+
EVENT_OBJECT_PARENTCHANGE = 0x800F,
131+
EVENT_OBJECT_HELPCHANGE = 0x8010,
132+
EVENT_OBJECT_DEFACTIONCHANGE = 0x8011,
133+
EVENT_OBJECT_ACCELERATORCHANGE = 0x8012,
134+
EVENT_OBJECT_INVOKED = 0x8013,
135+
EVENT_OBJECT_CONTENTSCROLLED = 0x8015,
136+
EVENT_SYSTEM_ARRANGMENTPREVIEW = 0x8016,
137+
EVENT_OBJECT_LIVEREGIONCHANGED = 0x8019,
138+
EVENT_OBJECT_HOSTEDOBJECTSINVALIDATED = 0x8020,
139+
EVENT_OBJECT_DRAGSTART = 0x8021,
140+
EVENT_OBJECT_DRAGCANCEL = 0x8022,
141+
EVENT_OBJECT_DRAGCOMPLETE = 0x8023,
142+
EVENT_OBJECT_DRAGENTER = 0x8024,
143+
EVENT_OBJECT_DRAGLEAVE = 0x8025,
144+
EVENT_OBJECT_DRAGDROPPED = 0x8026,
145+
EVENT_OBJECT_IME_SHOW = 0x8027,
146+
EVENT_OBJECT_IME_HIDE = 0x8028,
147+
EVENT_OBJECT_IME_CHANGE = 0x8029,
148+
EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED = 0x8030,
149+
EVENT_OBJECT_TEXTSELECTIONCHANGED = 0x8014,
150+
EVENT_OBJECT_END = 0x80FF,
151+
EVENT_MAX = 0x7FFFFFFF
152+
}
153+
// possible marshaling unmanaged type conflict/problem between 32/64 bit
154+
155+
public enum ObjId : uint
156+
{
157+
OBJID_WINDOW = 0x00000000,
158+
OBJID_SYSMENU = 0xFFFFFFFF,
159+
OBJID_TITLEBAR = 0xFFFFFFFE,
160+
OBJID_MENU = 0xFFFFFFFD,
161+
OBJID_CLIENT = 0xFFFFFFFC,
162+
OBJID_VSCROLL = 0xFFFFFFFB,
163+
OBJID_HSCROLL = 0xFFFFFFFA,
164+
OBJID_SIZEGRIP = 0xFFFFFFF9,
165+
OBJID_CARET = 0xFFFFFFF8,
166+
OBJID_CURSOR = 0xFFFFFFF7,
167+
OBJID_ALERT = 0xFFFFFFF6,
168+
OBJID_SOUND = 0xFFFFFFF5,
169+
OBJID_QUERYCLASSNAMEIDX = 0xFFFFFFF4,
170+
OBJID_NATIVEOM = 0xFFFFFFF0
171+
}
172+
173+
public enum WinEventFlags : uint
174+
{
175+
WINEVENT_OUTOFCONTEXT = 0x0000,
176+
WINEVENT_SKIPOWNTHREAD = 0x0001,
177+
WINEVENT_SKIPOWNPROCESS = 0x0002,
178+
WINEVENT_INCONTEXT = 0x0004
179+
}
180+
// ReSharper restore InconsistentNaming
181+
#endregion
182+
183+
#region API declarations
184+
185+
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, uint idObject, uint idChild, uint dwEventThread, uint dwmsEventTime);
186+
187+
[DllImport("user32.dll")]
188+
public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, IntPtr lpfnWinEventProc, uint idProcess,
189+
uint idThread, uint dwFlags);
190+
191+
[DllImport("user32.dll")]
192+
public static extern int GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
193+
194+
[DllImport("user32.dll")]
195+
public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
196+
197+
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
198+
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
199+
200+
#endregion
201+
202+
#region Extension methods
203+
204+
public static string ToObjectIdString(this uint objectId)
205+
{
206+
return ObjectIdNameLookup.ContainsKey(objectId) ? ObjectIdNameLookup[objectId] : objectId.ToString(CultureInfo.InvariantCulture);
207+
}
208+
209+
public static string ToEventIdString(this uint eventId)
210+
{
211+
return EventNameLookup.ContainsKey(eventId) ? EventNameLookup[eventId] : eventId.ToString(CultureInfo.InvariantCulture);
212+
}
213+
214+
public static string ToClassName(this IntPtr hwnd)
215+
{
216+
var buffer = new StringBuilder(256);
217+
if (hwnd != IntPtr.Zero)
218+
{
219+
return GetClassName(hwnd, buffer, buffer.Capacity) != 0 ? buffer.ToString() : string.Empty;
220+
}
221+
return string.Empty;
222+
}
223+
224+
#endregion
225+
}
226+
}

Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<Compile Include="Events\ProjectEventArgs.cs" />
128128
<Compile Include="Events\ProjectRenamedEventArgs.cs" />
129129
<Compile Include="Extensions\MSAccessComponentTypeExtensions.cs" />
130+
<Compile Include="Native\WinEvents.cs" />
130131
<Compile Include="SafeComWrappers\Abstract\ISafeComWrapper.cs" />
131132
<Compile Include="SafeComWrappers\Abstract\IVBComponentsEventsSink.cs" />
132133
<Compile Include="SafeComWrappers\Abstract\IVBProjectsEventsSink.cs" />

0 commit comments

Comments
 (0)