Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
9f5ec6d
Add reusable Button component and migrate generic button markup app-wide
jschick04 Jun 19, 2026
2f6a3c9
Route focus restoration through ElementFocus.SafelyAsync to drop dupl…
jschick04 Jun 19, 2026
69b16fa
Anchor scoped CSS ::deep button rules to their component roots
jschick04 Jun 19, 2026
3e2f13e
Separate the Button icon from its label with a space when both are pr…
jschick04 Jun 19, 2026
fec5e47
Expose MouseEventArgs on the Button OnClick callback
jschick04 Jun 19, 2026
127dc8d
Normalize a blank Button Type to "button" to prevent accidental form …
jschick04 Jun 19, 2026
f71e816
Assert Button icon ordering and spacing via DOM nodes instead of Inne…
jschick04 Jun 19, 2026
f7f580a
Route CriticalBanner reload-button focus through ElementFocus.SafelyA…
jschick04 Jun 19, 2026
18f7fc7
Standardize icon buttons on IconClass and fix rotating-caret centering
jschick04 Jun 20, 2026
5fbc5a1
Rename FilterPane button component references to drop the misleading …
jschick04 Jun 20, 2026
1f6cf65
Exempt loading spinners from the reduced-motion animation reset
jschick04 Jun 20, 2026
491f9f0
Add ChromelessButton and migrate bespoke buttons with centralized dis…
jschick04 Jun 20, 2026
8371b4d
Extend ButtonBase with keyboard events and migrate remaining buttons …
jschick04 Jun 20, 2026
e8a9ad8
Wire ButtonBase onclick and onmouseenter only when their handlers are…
jschick04 Jun 20, 2026
51b73ba
Make @ref-populated button collections nullable to match runtime reality
jschick04 Jun 20, 2026
5310698
Wire ButtonBase onkeydown when StopKeyDownPropagation is requested
jschick04 Jun 20, 2026
c6d2d54
Build the app separately from libraries and tests to drop the -m:1 bu…
jschick04 Jun 20, 2026
909b870
Enable native ARM64 builds for the explorer shell extension
jschick04 Jun 20, 2026
9a23d6f
Derive the native shell-extension platform from Platform and guard ag…
jschick04 Jun 20, 2026
e4a9bfc
Update the SDK import and build-split comments to cover ARM64
jschick04 Jun 20, 2026
9b20c40
Remove the empty placeholder integration test projects
jschick04 Jun 20, 2026
18123ed
Clarify the native-build error messages reference the SDK NuGet packages
jschick04 Jun 20, 2026
3f82133
Remove references to the deleted EventDbTool integration test project
jschick04 Jun 20, 2026
723c2b5
Reference elevationhelper instead of removed eventdbtool in test docs
jschick04 Jun 20, 2026
15ccb63
Fix the force-kill disposition race and the helper connect harness
jschick04 Jun 21, 2026
a33ac93
Build the solution in one pass and drop the slnf build split
jschick04 Jun 21, 2026
e1cc293
Make the in-app updater select the multi-architecture bundle only
jschick04 Jun 20, 2026
254ad7a
Add reverse-read support and a direction-agnostic newest bookmark to …
jschick04 Jun 20, 2026
bf7401a
Read logs newest-first and eagerly paint the first screenful
jschick04 Jun 20, 2026
1c26000
Read event variants via pointer and match EvtVariant to MSDN
jschick04 Jun 20, 2026
44ee2df
Read value-type system properties without boxing in GetEventRecord
jschick04 Jun 20, 2026
98c904a
Prioritize a newly-opened log's first screenful over bulk resolution
jschick04 Jun 20, 2026
095017d
Enable Server GC for faster parallel event resolution
jschick04 Jun 20, 2026
d3a2cae
Read event batches of 256 and release handles on a failed read
jschick04 Jun 20, 2026
1cd32f5
Store provider messages compactly to cut resolver memory
jschick04 Jun 21, 2026
19fd77c
Load provider message-table entries on demand to cut resolver memory
jschick04 Jun 21, 2026
8436a1f
Harden EVT_VARIANT type checks and order partial load newest-first
jschick04 Jun 21, 2026
0559fee
Document the self-contained multi-arch bundle install and update
jschick04 Jun 21, 2026
563732d
Fix doc screenshots hidden by a same-line HTML comment
jschick04 Jun 21, 2026
e4c460d
Use the dashboard splash as the README hero and note requirements
jschick04 Jun 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/PullRequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Restore dependencies
run: dotnet restore EventLogExpert.slnx
- name: Build
run: dotnet build EventLogExpert.slnx --no-restore -c Release -p:PublishReadyToRun=false -m:1
run: dotnet build EventLogExpert.slnx --no-restore -c Release -p:PublishReadyToRun=false -p:WindowsPackageType=None
- name: Test (unit)
shell: pwsh
run: |
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DebugType>embedded</DebugType>
<!-- CsWinRT1030 fires for List<T> of any public type because IT could theoretically cross the WinRT ABI in AOT/trimmed scenarios. We never marshal these collections across the ABI, so the warning is benign. -->
<NoWarn>$(NoWarn);CsWinRT1030</NoWarn>
</PropertyGroup>
Expand Down
7 changes: 7 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<ItemGroup Condition="'$(OutputType)' == 'Exe' or '$(OutputType)' == 'WinExe'">
<ProjectReference Update="@(ProjectReference)">
<GlobalPropertiesToRemove>$(GlobalPropertiesToRemoveFromProjectReferences);RuntimeIdentifier;SelfContained</GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
</Project>
3 changes: 0 additions & 3 deletions EventLogExpert.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,11 @@
<Project Path="tests/Unit/EventLogExpert.Provider.Tests/EventLogExpert.Provider.Tests.csproj" />
</Folder>
<Folder Name="/tests/Integration/">
<Project Path="tests/Integration/EventLogExpert.EventDbTool.IntegrationTests/EventLogExpert.EventDbTool.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.Eventing.IntegrationTests/EventLogExpert.Eventing.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.Filtering.IntegrationTests/EventLogExpert.Filtering.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.Runtime.IntegrationTests/EventLogExpert.Runtime.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.Provider.Database.IntegrationTests/EventLogExpert.Provider.Database.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.DatabaseTools.IntegrationTests/EventLogExpert.DatabaseTools.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.ElevationHelper.IntegrationTests/EventLogExpert.ElevationHelper.IntegrationTests.csproj" />
<Project Path="tests/Integration/EventLogExpert.UI.IntegrationTests/EventLogExpert.UI.IntegrationTests.csproj" />
</Folder>
<Folder Name="/tests/Shared/">
<Project Path="tests/Shared/EventLogExpert.Eventing.TestUtils/EventLogExpert.Eventing.TestUtils.csproj" />
Expand Down
16 changes: 6 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Windows Event Log viewer for tech support and IT professionals.

![Screenshot showing a filtered combined view of three event logs](docs/.images/EventLogExpert-CombinedView.png)
![EventLogExpert dashboard: Quick Launch live-log buttons and a categorized library of common investigations](docs/.images/EventLogExpert-Dashboard.png)

## Key features

Expand All @@ -21,20 +21,16 @@ For more information, check our [docs](docs/Home.md).

## Quick Start

Download the `EventLogExpert_{version}_x64.appinstaller` (or the matching `EventLogExpert_{version}_x64.msix`) from the latest release and run it: <https://github.com/microsoft/EventLogExpert/releases/latest>.
Download `EventLogExpert_{version}.msixbundle` from the latest release and double-click it to install: <https://github.com/microsoft/EventLogExpert/releases/latest>.

The `.appinstaller` declares its dependency on the Windows App Runtime (currently `Microsoft.WindowsAppRuntime.1.7.msix`, also published in the same release) so App Installer fetches the runtime automatically on a clean machine. Updates are checked on launch.
The bundle runs natively on both x64 and ARM64, and Windows installs the matching architecture automatically. It is self-contained (the Windows App Runtime ships inside the package), so there is no separate runtime to install. Updates are checked on launch.

If you'd rather install the runtime manually first, grab `Microsoft.WindowsAppRuntime.1.7.msix` from the release and install it with:
**Requirements:** Windows 11, Windows Server 2022, or Windows Server 2025 (x64 or ARM64).

```
Add-AppxPackage $home\Downloads\Microsoft.WindowsAppRuntime.1.7.msix
```

Then install the app:
Prefer the command line? Install the same bundle with:

```
Add-AppxPackage $home\Downloads\EventLogExpert_{version}_x64.msix
Add-AppxPackage $home\Downloads\EventLogExpert_{version}.msixbundle
```

### First time setup
Expand Down
7 changes: 0 additions & 7 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ services:
- --logger
- "trx;LogFileName=runtime.trx"

eventdbtool:
<<: *base
command:
- tests/Integration/EventLogExpert.EventDbTool.IntegrationTests/EventLogExpert.EventDbTool.IntegrationTests.csproj
- --logger
- "trx;LogFileName=eventdbtool.trx"

elevationhelper:
<<: *base
command:
Expand Down
Binary file added docs/.images/EventLogExpert-Dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/Explorer-Context-Menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The MAUI receiving side:

## Build prerequisites

The native shell extension requires the **MSVC C++ workload** to build. The **Windows 10/11 SDK (10.0.26100+)** it compiles against is delivered as NuGet packages (`Microsoft.Windows.SDK.CPP` + `Microsoft.Windows.SDK.CPP.x64`, restored to `src/packages`), so a machine-installed Windows SDK is **not** required on build agents the OneBranch release container ships the C++ toolset but no SDK, and the packages supply the headers, import libs, winmd, and SDK tools (`rc.exe`, `mt.exe`, `midlrt.exe`). Specifically:
The native shell extension requires the **MSVC C++ workload** to build. The **Windows 10/11 SDK (10.0.26100+)** it compiles against is delivered as NuGet packages (`Microsoft.Windows.SDK.CPP` + the per-architecture `Microsoft.Windows.SDK.CPP.x64` / `Microsoft.Windows.SDK.CPP.arm64`, restored to `src/packages`), so a machine-installed Windows SDK is **not** required on build agents - the OneBranch release container ships the C++ toolset but no SDK, and the packages supply the headers, import libs, winmd, and SDK tools (`rc.exe`, `mt.exe`, `midlrt.exe`). Specifically:

- Visual Studio 2026 (or 2022) with the **Desktop development with C++** workload
- The Windows SDK NuGet packages above (restored automatically by the `BuildExplorerExtensionNative` target; see below). A locally-installed Windows SDK 10.0.26100+ is still honored as a fallback when those packages are not restored — the vcxproj's `WindowsTargetPlatformVersion` then stays a bare `10.0` (latest installed SDK).
Expand All @@ -46,7 +46,7 @@ cd src/EventLogExpert.ExplorerExtensionNative
nuget restore packages.config -PackagesDirectory ..\packages
```

This populates `src/packages/` with `Microsoft.Windows.CppWinRT.*`, `Microsoft.Windows.ImplementationLibrary.*` (WIL), and the Windows SDK packages `Microsoft.Windows.SDK.CPP.*` + `Microsoft.Windows.SDK.CPP.x64.*` (the SDK packages are large several hundred MB extracted). All are gitignored.
This populates `src/packages/` with `Microsoft.Windows.CppWinRT.*`, `Microsoft.Windows.ImplementationLibrary.*` (WIL), and the Windows SDK packages `Microsoft.Windows.SDK.CPP.*` + the per-architecture `Microsoft.Windows.SDK.CPP.x64.*` / `Microsoft.Windows.SDK.CPP.arm64.*` (the SDK packages are large - several hundred MB extracted). All are gitignored.

## Local dev install (signed MSIX)

Expand Down
3 changes: 2 additions & 1 deletion docs/Filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

The Filter pane sits above the event table. Every event in the active log set is evaluated against the applied filters; non-matches are hidden.

<!-- screenshot: filter-pane --> ![Filter pane header showing the left-side action buttons, active-filter indicator, and right-side icon trio](.images/filter-pane.png)
<!-- screenshot: filter-pane -->
![Filter pane header showing the left-side action buttons, active-filter indicator, and right-side icon trio](.images/filter-pane.png)

The pane header carries the row-adding actions on the left and the persistence / management actions on the right:

Expand Down
3 changes: 2 additions & 1 deletion docs/Saved-Filters.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ The Filter Library is the single persisted surface for filter reuse. It replaces

Open it from the [Filter pane](Filtering.md) header — the bookmarks icon labeled `Open Filter Library`. When the library fails to load or is still loading, the filter pane's `Recent` menu item and the `Apply Filter Set` picker surface guidance pointing back to this same button (the library does not auto-open from those flows).

<!-- screenshot: filter-library-saved --> ![Filter Library modal, Saved tab](.images/filter-library-saved.png)
<!-- screenshot: filter-library-saved -->
![Filter Library modal, Saved tab](.images/filter-library-saved.png)

### Modal layout

Expand Down
3 changes: 2 additions & 1 deletion docs/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

`Save` writes the form fields and any pending enable/disable toggles you've made on database rows; `Exit` discards them. `Remove` and `Upgrade` are immediate side effects that persist regardless of `Save` / `Exit`. `Import Database` is also immediate, but a successful import additionally applies any pending form fields and toggles and closes the modal — make any other changes you want to keep before clicking it.

<!-- screenshot: settings-modal --> ![Settings modal](.images/settings-modal.png)
<!-- screenshot: settings-modal -->
![Settings modal](.images/settings-modal.png)

### Time Zone

Expand Down
5 changes: 3 additions & 2 deletions docs/Updates-And-Diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The check ends with one of four user-facing alerts:

Background checks (the automatic check that runs on app start) surface `Update Available` so a fresh release is offered as soon as the app launches. The other three alerts are suppressed on background checks so a missing network at startup does not produce a popup. `Update Failure` does fire on a background check, but only after you've accepted the `Update Available` prompt and the resulting installer attempt fails; pre-prompt failures (e.g., feed unreachable, or you click `No` on the prompt and the queued-for-next-restart scheduling fails) stay silent and only land in the debug log.

The `.appinstaller` distributed with each release also wires up app-installer-driven background update checks on every launch, so this entry is mostly for "what's the latest right now" the app finds new releases on its own.
Because the app already runs that background check on launch, the `Check for Updates` entry is mostly a manual "what's the latest right now" lookup; the app finds new releases on its own.

### Release Notes

Expand All @@ -39,7 +39,8 @@ Opens the Release Notes modal, which renders the markdown body of the published

Opens the Debug Log modal — the in-app view of the rolling diagnostic log written by the running session. The same log is also accessible as a file under the per-user app data directory; `View Logs` is the in-app surface.

<!-- screenshot: debug-log-modal --> ![Debug Log modal](.images/debug-log-modal.png)
<!-- screenshot: debug-log-modal -->
![Debug Log modal](.images/debug-log-modal.png)

Filter bar:

Expand Down
3 changes: 2 additions & 1 deletion docs/Viewing-Events.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

The main view has three regions: the **tab strip** (one tab per open log, plus a `Combined` tab when more than one log is open), the **event table**, and the **Details pane** (collapsible, bottom). The status bar runs along the very bottom — see [Opening Logs](Opening-Logs.md#live-log-behavior) for what it shows for live logs.

<!-- screenshot: main-view --> ![Main view: tabs, event table, Details pane](.images/EventLogExpert-CombinedView.png)
<!-- screenshot: main-view -->
![Main view: tabs, event table, Details pane](.images/EventLogExpert-CombinedView.png)

### Tab strip

Expand Down
2 changes: 1 addition & 1 deletion scripts/run-tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.EXAMPLE
./scripts/run-tests.ps1
./scripts/run-tests.ps1 -Suite eventing
./scripts/run-tests.ps1 -Suite runtime,eventdbtool
./scripts/run-tests.ps1 -Suite runtime,elevationhelper
#>
[CmdletBinding()]
param(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("EventLogExpert.EventDbTool.IntegrationTests")]
[assembly: InternalsVisibleTo("EventLogExpert.EventDbTool.Tests")]
56 changes: 37 additions & 19 deletions src/EventLogExpert.Eventing/Interop/EvtVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,46 @@ namespace EventLogExpert.Eventing.Interop;
[StructLayout(LayoutKind.Explicit)]
internal readonly record struct EvtVariant
{
[FieldOffset(0)] internal readonly uint UInteger;
[FieldOffset(0)] internal readonly int Integer;
[FieldOffset(0)] internal readonly byte UInt8;
[FieldOffset(0)] internal readonly short Short;
[FieldOffset(0)] internal readonly ushort UShort;
[FieldOffset(0)] internal readonly uint Bool;
[FieldOffset(0)] internal readonly int BooleanVal;
[FieldOffset(0)] internal readonly sbyte SByteVal;
[FieldOffset(0)] internal readonly short Int16Val;
[FieldOffset(0)] internal readonly int Int32Val;
[FieldOffset(0)] internal readonly long Int64Val;
[FieldOffset(0)] internal readonly byte ByteVal;
[FieldOffset(0)] internal readonly byte SByte;
[FieldOffset(0)] internal readonly ulong ULong;
[FieldOffset(0)] internal readonly long Long;
[FieldOffset(0)] internal readonly float Single;
[FieldOffset(0)] internal readonly double Double;
[FieldOffset(0)] internal readonly ushort UInt16Val;
[FieldOffset(0)] internal readonly uint UInt32Val;
[FieldOffset(0)] internal readonly ulong UInt64Val;
[FieldOffset(0)] internal readonly float SingleVal;
[FieldOffset(0)] internal readonly double DoubleVal;
[FieldOffset(0)] internal readonly ulong FileTimeVal;
[FieldOffset(0)] internal readonly nint SysTimeVal;
[FieldOffset(0)] internal readonly nint GuidVal;
[FieldOffset(0)] internal readonly nint StringVal;
[FieldOffset(0)] internal readonly nint AnsiString;
[FieldOffset(0)] internal readonly nint AnsiStringVal;
[FieldOffset(0)] internal readonly nint BinaryVal;
[FieldOffset(0)] internal readonly nint SidVal;
[FieldOffset(0)] internal readonly nint Binary;
[FieldOffset(0)] internal readonly nint Reference;
[FieldOffset(0)] internal readonly nint Handle;
[FieldOffset(0)] internal readonly nint GuidReference;
[FieldOffset(0)] internal readonly ulong FileTime;
[FieldOffset(0)] internal readonly nint SystemTime;
[FieldOffset(0)] internal readonly nint SizeT;
[FieldOffset(0)] internal readonly nuint SizeTVal;
[FieldOffset(0)] internal readonly nint BooleanArr;
[FieldOffset(0)] internal readonly nint SByteArr;
[FieldOffset(0)] internal readonly nint Int16Arr;
[FieldOffset(0)] internal readonly nint Int32Arr;
[FieldOffset(0)] internal readonly nint Int64Arr;
[FieldOffset(0)] internal readonly nint ByteArr;
[FieldOffset(0)] internal readonly nint UInt16Arr;
[FieldOffset(0)] internal readonly nint UInt32Arr;
[FieldOffset(0)] internal readonly nint UInt64Arr;
[FieldOffset(0)] internal readonly nint SingleArr;
[FieldOffset(0)] internal readonly nint DoubleArr;
[FieldOffset(0)] internal readonly nint FileTimeArr;
[FieldOffset(0)] internal readonly nint SysTimeArr;
[FieldOffset(0)] internal readonly nint GuidArr;
[FieldOffset(0)] internal readonly nint StringArr;
[FieldOffset(0)] internal readonly nint AnsiStringArr;
[FieldOffset(0)] internal readonly nint SidArr;
[FieldOffset(0)] internal readonly nint SizeTArr;
[FieldOffset(0)] internal readonly nint EvtHandleVal;
[FieldOffset(0)] internal readonly nint XmlVal;
[FieldOffset(0)] internal readonly nint XmlValArr;
[FieldOffset(8)] internal readonly uint Count;
[FieldOffset(12)] internal readonly uint Type;
}
Loading
Loading