FindMyFiles

FindMyFiles Assembly

FindMyFiles

FindMyFiles

App Class

Application entry point and process-wide composition root. `OnLaunched` resolves the engine boundary (EngineClient) and stands up the single MainWindow. On fatal init failure it falls back to `FakeEngineClient` to avoid crashing silently.

public class App : Microsoft.UI.Xaml.Application, Microsoft.UI.Xaml.Markup.IXamlMetadataProvider

Inheritance System.ObjectMicrosoft.UI.Xaml.Application → App

Implements Microsoft.UI.Xaml.Markup.IXamlMetadataProvider

Constructors

App() Constructor

Initialize in order: apply language override → `InitializeComponent` → ExceptionPolicy.Install. The language override must run before `InitializeComponent` so `x:Uid`/`ResourceLoader` resolve to the correct language on the first XAML load.

public App();

Properties

App.DispatcherQueue Property

The UI thread's DispatcherQueue (cached in `OnLaunched`). Marshal UI work from background threads via TryEnqueue on this (UI rule: cache it on the UI thread before use).

public static Microsoft.UI.Dispatching.DispatcherQueue DispatcherQueue { get; }

Property Value

Microsoft.UI.Dispatching.DispatcherQueue

App.EngineClient Property

The engine boundary. `--fake-engine` swaps in deterministic data so UI tests and unelevated development never touch real volumes.

public static FindMyFiles.Engine.IEngineClient EngineClient { get; }

Property Value

IEngineClient

App.Window Property

The single top-level window. Created in `OnLaunched`; the origin for the HWND lookup via `WinRT.Interop` (WindowHandle).

public static Microsoft.UI.Xaml.Window Window { get; }

Property Value

Microsoft.UI.Xaml.Window

App.WindowHandle Property

The main window's Win32 HWND. Passed to init of WinRT APIs that take a parent window (file pickers, etc.) — the unpackaged WinUI 3 way.

public static nint WindowHandle { get; }

Property Value

nint

Methods

App.GetXamlType(string) Method

GetXamlType(String)

public Microsoft.UI.Xaml.Markup.IXamlType GetXamlType(string fullName);

Parameters

fullName System.String

Implements GetXamlType(string)

Returns

Microsoft.UI.Xaml.Markup.IXamlType

App.GetXamlType(Type) Method

GetXamlType(Type)

public Microsoft.UI.Xaml.Markup.IXamlType GetXamlType(System.Type type);

Parameters

type System.Type

Implements GetXamlType(Type)

Returns

Microsoft.UI.Xaml.Markup.IXamlType

App.GetXmlnsDefinitions() Method

GetXmlnsDefinitions()

public Microsoft.UI.Xaml.Markup.XmlnsDefinition[] GetXmlnsDefinitions();

Implements GetXmlnsDefinitions()

Returns

Microsoft.UI.Xaml.Markup.XmlnsDefinition[]

App.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

FindMyFiles

FindMyFiles.Controls

ResultsViewportManager Class

Imperative ListView companion for the results list: viewport placement after each published result, best-effort selection restore across seeded Resets, ScrollViewer discovery, and the selection-driven row actions (open / reveal / copy — all via ShellOps, which sheds elevation through explorer.exe).

UI thread only: every member touches the ListView, and the class is constructed and wired from the page constructor on the UI thread. The pure decision helpers (FindMyFiles.Controls.ResultsViewportManager.CanRestoreViewport(System.Nullable{System.Int32},System.Int32), FindMyFiles.Controls.ResultsViewportManager.FindSelectionIndex(System.Func{System.Int32,System.Object},System.Int32,System.Int32,System.Int32,System.UInt64), FindMyFiles.Controls.ResultsViewportManager.CopyablePaths(System.Collections.IEnumerable)) are static and unit-tested without a ListView.

public sealed class ResultsViewportManager

Inheritance System.Object → ResultsViewportManager

Constructors

ResultsViewportManager(ListView) Constructor

Wrap the results list and start tracking its selection so the last real (non-placeholder) row's engine identity (EntryRef) can be re-found and reselected after a position-preserving requery's Reset clears the ListView selection.

public ResultsViewportManager(Microsoft.UI.Xaml.Controls.ListView list);

Parameters

list Microsoft.UI.Xaml.Controls.ListView

The results ListView to wrap and track.

Methods

ResultsViewportManager.CopySelectedPaths() Method

Copy the full paths of all real selected rows to the clipboard, CRLF-separated; no-op when the selection holds no real rows.

public void CopySelectedPaths();

ResultsViewportManager.FocusTopRow() Method

Down from the search box: focus the list on its top row.

public void FocusTopRow();

ResultsViewportManager.OnResultsPublished(ResultsPublication) Method

Reset origins (typing, sort…) land at the top; position-preserving origins (index changed, stale…) restore the previous first visible row and, best effort, the selection. Explicit placement — the ListView's own behavior after a Reset is version-dependent.

public void OnResultsPublished(FindMyFiles.ViewModels.ResultsPublication pub);

Parameters

pub ResultsPublication

The freshly published result and its restore hints.

ResultsViewportManager.OpenSelected() Method

Open the selected row's file via the shell (no-op if nothing or a placeholder is selected).

public void OpenSelected();

ResultsViewportManager.OpenSelectedOrTop() Method

Open the selected row, or the top row when none is selected (Enter from the search box).

public void OpenSelectedOrTop();

ResultsViewportManager.RevealSelected() Method

Reveal the selected row's file in Explorer (selected in its folder); no-op for an empty or placeholder selection.

public void RevealSelected();

ResultsViewportManager.SelectedOrTopRow() Method

The selected row, falling back to the top row — what Enter from the search box opens when the user never moved into the list.

public FindMyFiles.ViewModels.ResultRow? SelectedOrTopRow();

Returns

ResultRow
The selected row, the top row, or null when empty.

ResultsViewportManager.SelectedRow() Method

The currently selected row, or null if nothing (or a non-row) is selected.

public FindMyFiles.ViewModels.ResultRow? SelectedRow();

Returns

ResultRow
The selected ResultRow, or null.

FindMyFiles

FindMyFiles.Controls Namespace

Classes
ResultsViewportManagerImperative ListView companion for the results list: viewport placement after each published result, best-effort selection restore across seeded Resets, ScrollViewer discovery, and the selection-driven row actions (open / reveal / copy — all via ShellOps, which sheds elevation through explorer.exe). UI thread only: every member touches the ListView, and the class is constructed and wired from the page constructor on the UI thread. The pure decision helpers (FindMyFiles.Controls.ResultsViewportManager.CanRestoreViewport(System.Nullable{System.Int32},System.Int32), FindMyFiles.Controls.ResultsViewportManager.FindSelectionIndex(System.Func{System.Int32,System.Object},System.Int32,System.Int32,System.Int32,System.UInt64), FindMyFiles.Controls.ResultsViewportManager.CopyablePaths(System.Collections.IEnumerable)) are static and unit-tested without a ListView.

FindMyFiles

FindMyFiles.Converters

UiConverters Class

Pure x:Bind function-binding converters — no IValueConverter plumbing, x:Bind calls these statically and stays typed end to end.

public static class UiConverters

Inheritance System.Object → UiConverters

Methods

UiConverters.BoolToVis(bool) Method

Maps true to Visible and false to Collapsed (negate on the bind side where inversion is needed).

public static Microsoft.UI.Xaml.Visibility BoolToVis(bool value);

Parameters

value System.Boolean

The bound boolean to map to a visibility.

Returns

Microsoft.UI.Xaml.Visibility
Visible when value is true, otherwise Collapsed.

UiConverters.ToInfoSeverity(NotifySeverity) Method

App severity → InfoBar severity (the InfoBar enum is the view's vocabulary; the app's is NotifySeverity).

public static Microsoft.UI.Xaml.Controls.InfoBarSeverity ToInfoSeverity(FindMyFiles.Services.NotifySeverity s);

Parameters

s NotifySeverity

The app-side severity to translate.

Returns

Microsoft.UI.Xaml.Controls.InfoBarSeverity
The matching Microsoft.UI.Xaml.Controls.InfoBarSeverity for the view.

UiConverters.VisibleIfNotEmpty(string) Method

Visible when the string is non-null and non-empty, otherwise Collapsed. Used to show an element only when a value exists (e.g. error text).

public static Microsoft.UI.Xaml.Visibility VisibleIfNotEmpty(string? value);

Parameters

value System.String

The bound string whose presence drives visibility.

Returns

Microsoft.UI.Xaml.Visibility
Visible when value is non-null and non-empty, otherwise Collapsed.

FindMyFiles

FindMyFiles.Converters Namespace

Classes
UiConvertersPure x:Bind function-binding converters — no IValueConverter plumbing, x:Bind calls these statically and stays typed end to end.

FindMyFiles

FindMyFiles.Engine

CountersData Class

Degradation counters of the stats JSON (snake_case keys — deserialize with SnakeCaseLower). Generated from the contract's counter-name registry; nonzero values surface in the F12 panel.

public sealed class CountersData

Inheritance System.Object → CountersData

FindMyFiles

FindMyFiles.Engine

EngineClientFactory Class

Engine transport selection, in priority order: CLI flags (--fake-engine / --engine=pipe|inproc / --pipe-name=…) > settings.json "engine" > auto. Auto probes the service pipe for 250ms (through Hello) and falls back to the in-proc FFI engine when no service answers.

public static class EngineClientFactory

Inheritance System.Object → EngineClientFactory

Methods

EngineClientFactory.Resolve(string[]) Method

Called once at startup; resolves and returns a single engine implementation by the priority above. When in-proc is unavailable (no service plus not elevated), degrades to the empty engine (CreateEmpty()) and steers the UI to the setup screen (no auto-runas).

public static FindMyFiles.Engine.IEngineClient Resolve(string[] args);

Parameters

args System.String[]

Process command-line args (reads `--fake-engine` / `--engine=` / `--pipe-name=`).

Returns

IEngineClient
The single chosen IEngineClient implementation instance.

FindMyFiles

FindMyFiles.Engine

EngineConnectionState Enum

Transport state of the engine boundary. In-proc clients are always InProc; the pipe client reports its supervisor state.

public enum EngineConnectionState

Fields

InProc 0

In-process engine (FFI): no transport, so always connected.

Connecting 1

The pipe client is establishing its first connection to the service.

Connected 2

The pipe client has a live connection to the service.

Reconnecting 3

The pipe connection dropped; the supervisor is re-establishing it.

FindMyFiles

FindMyFiles.Engine

EngineEventMarshaler Class

The single crossing point from engine threads to the UI thread. IEngineClient events fire on engine / pipe read-loop threads; this class subscribes to all four, marshals each through TryEnqueue(Action) and re-raises it as its own event on the UI thread. Consumers (ViewModels, the orchestrator) attach plain handlers and never marshal themselves — the per-subscriber inline `dispatcher.TryEnqueue` lambdas this replaces were the audit's "scattered crossing" finding. The upstream delegates are held in fields for the subscription lifetime (the GC-rooting rule for callback delegates, satisfied structurally).

public sealed class EngineEventMarshaler : System.IDisposable

Inheritance System.Object → EngineEventMarshaler

Implements System.IDisposable

Constructors

EngineEventMarshaler(IEngineClient, IDispatcher) Constructor

Subscribes to the four events of engine, marshals each payload to the UI thread via dispatcher, and re-raises it as this class's same-named event. The upstream delegates are held in fields (subscription lifetime = GC root) and detached in Dispose().

public EngineEventMarshaler(FindMyFiles.Engine.IEngineClient engine, FindMyFiles.Services.IDispatcher dispatcher);

Parameters

engine IEngineClient

The source engine client to subscribe to.

dispatcher IDispatcher

The UI-thread marshal target.

Methods

EngineEventMarshaler.Dispose() Method

Detaches all four upstream subscriptions (after this the marshaler re-raises no further events).

public void Dispose();

Implements Dispose()

Events

EngineEventMarshaler.ConnectionChanged Event

Re-raised on the UI thread from ConnectionChanged (same payload, same order).

public event Action<EngineConnectionState>? ConnectionChanged;

Event Type

System.Action<EngineConnectionState>

EngineEventMarshaler.EngineErrorOccurred Event

Re-raised on the UI thread from EngineErrorOccurred (same severity, same order).

public event Action<int>? EngineErrorOccurred;

Event Type

System.Action<System.Int32>

EngineEventMarshaler.IndexChanged Event

Re-raised on the UI thread from IndexChanged. Payload and the engine's relative firing order are preserved (TryEnqueue is FIFO).

public event Action<string>? IndexChanged;

Event Type

System.Action<System.String>

EngineEventMarshaler.VolumeUpdated Event

Re-raised on the UI thread from VolumeUpdated (same payload, same order).

public event Action<VolumeStatus>? VolumeUpdated;

Event Type

System.Action<VolumeStatus>

FindMyFiles

FindMyFiles.Engine

EngineException Class

The engine rejected an operation with a structured error code (the transport is alive but the engine returned a failure). The code maps to the `FMF_E_*` table in docs/ARCHITECTURE.md.

public sealed class EngineException : System.Exception

Inheritance System.ObjectSystem.Exception → EngineException

Constructors

EngineException(string, int) Constructor

The engine rejected an operation with a structured error code (the transport is alive but the engine returned a failure). The code maps to the `FMF_E_*` table in docs/ARCHITECTURE.md.

public EngineException(string message, int code);

Parameters

message System.String

The human-readable message returned by the engine.

code System.Int32

The numeric `FMF_E_*` code (held in Code).

Properties

EngineException.Code Property

The `FMF_E_*` code returned by the engine. Used for UI branching (e.g. `FMF_E_LOCKED` routes to the setup screen).

public int Code { get; }

Property Value

System.Int32

FindMyFiles

FindMyFiles.Engine

EngineStatsData Class

The whole observability snapshot behind the F12 perf panel — what GetStatsAsync(CancellationToken) returns (the UI subset of fmf-core's MetricsSnapshot).

public sealed class EngineStatsData

Inheritance System.Object → EngineStatsData

Properties

EngineStatsData.Counters Property

Degradation counters; nonzero values flag silent fallbacks.

public FindMyFiles.Engine.CountersData Counters { get; set; }

Property Value

CountersData

EngineStatsData.Indexes Property

Per-volume index accounting, one entry per indexed volume.

public System.Collections.Generic.List<FindMyFiles.Engine.IndexStatsData> Indexes { get; set; }

Property Value

System.Collections.Generic.List<IndexStatsData>

EngineStatsData.P50Us Property

Median query latency in µs across the histogram's lifetime.

public ulong P50Us { get; set; }

Property Value

System.UInt64

EngineStatsData.P99Us Property

99th-percentile query latency in µs — the figure measured against the ≤50 ms search gate.

public ulong P99Us { get; set; }

Property Value

System.UInt64

EngineStatsData.RecentErrors Property

WARN+ diagnostics and panics from the engine's ring, oldest first.

public System.Collections.Generic.List<FindMyFiles.Engine.ErrorEventData> RecentErrors { get; set; }

Property Value

System.Collections.Generic.List<ErrorEventData>

EngineStatsData.RecentQueries Property

Recent query traces, oldest first (a bounded ring on the engine side).

public System.Collections.Generic.List<FindMyFiles.Engine.QueryTraceData> RecentQueries { get; set; }

Property Value

System.Collections.Generic.List<QueryTraceData>

EngineStatsData.RecentUsn Property

Recently applied USN batches, oldest first.

public System.Collections.Generic.List<FindMyFiles.Engine.UsnTraceData> RecentUsn { get; set; }

Property Value

System.Collections.Generic.List<UsnTraceData>

EngineStatsData.Transport Property

Pipe transport metrics, or null for in-proc clients (Ffi/Fake) where there is no wire.

public FindMyFiles.Engine.TransportStatsData? Transport { get; set; }

Property Value

TransportStatsData

FindMyFiles

FindMyFiles.Engine

EngineUnavailableException Class

The engine transport is down (pipe disconnected, request timed out, service not running). Pending requests fail fast with this; the supervisor keeps reconnecting in the background.

public sealed class EngineUnavailableException : System.Exception

Inheritance System.ObjectSystem.Exception → EngineUnavailableException

Constructors

EngineUnavailableException(string) Constructor

The engine transport is down (pipe disconnected, request timed out, service not running). Pending requests fail fast with this; the supervisor keeps reconnecting in the background.

public EngineUnavailableException(string message);

Parameters

message System.String

Human-readable description of which transport failure occurred.

FindMyFiles

FindMyFiles.Engine

ErrorEventData Class

One entry from the engine's diagnostic ring (WARN+ events and panics; mirrors fmf-core's ErrorEvent). Pulled on demand after an EngineErrorOccurred signal and listed in the F12 panel.

public sealed class ErrorEventData

Inheritance System.Object → ErrorEventData

Properties

ErrorEventData.Area Property

Originating tracing target (module path) — the "where" of the event.

public string Area { get; set; }

Property Value

System.String

ErrorEventData.Message Property

Human-readable description of what happened.

public string Message { get; set; }

Property Value

System.String

ErrorEventData.Seq Property

Monotonic emit sequence — orders events and lets the UI detect ones it has already shown.

public ulong Seq { get; set; }

Property Value

System.UInt64

ErrorEventData.Severity Property

Level as a lowercase string: "warn", "error" or "panic" (the same 1/2/3 the FFI event carries numerically).

public string Severity { get; set; }

Property Value

System.String

ErrorEventData.UptimeMs Property

Engine uptime in ms when the event fired ("when").

public ulong UptimeMs { get; set; }

Property Value

System.UInt64

ErrorEventData.Volume Property

Drive label the event is attributed to, or null when it is not volume-scoped.

public string? Volume { get; set; }

Property Value

System.String

FindMyFiles

FindMyFiles.Engine

FakeEngineClient Class

Deterministic in-memory engine for UI tests and unelevated development (`--fake-engine`). 100k entries from a fixed seed; substring search only. Contract-conforming (EngineClientContractTests): query-syntax verdicts come from the shared golden fixture (contract/golden/invalid_queries.json, pinned by the real Rust parser — verdict drift is caught on the Rust side), cancellation is honored, and BumpEpoch() lets tests drive the Stale→requery recovery path without a real engine.

public sealed class FakeEngineClient : FindMyFiles.Engine.IEngineClient, System.IDisposable

Inheritance System.Object → FakeEngineClient

Implements IEngineClient, System.IDisposable

Constructors

FakeEngineClient(bool) Constructor

Builds the fake. The default (empty false) generates the deterministic 100k-row dataset that backs --fake-engine; CreateEmpty() passes empty true for the unelevated no-service stand-in.

public FakeEngineClient(bool empty=false);

Parameters

empty System.Boolean

When true, no rows are generated (the disconnected auto-fallback); when false, the seeded demo dataset is built.

Properties

FakeEngineClient.Connection Property

In-proc: no transport, no state transitions.

public FindMyFiles.Engine.EngineConnectionState Connection { get; }

Implements Connection

Property Value

EngineConnectionState

FakeEngineClient.IsEmpty Property

True for the unelevated auto-fallback instance (no rows) — the status badge says disconnected, not fake.

public bool IsEmpty { get; }

Property Value

System.Boolean

Methods

FakeEngineClient.BumpEpoch() Method

Test hook: structurally invalidate every result handed out so far — their next GetRangeAsync throws StaleResultException, exactly like a real index rebuild (UI Stale→requery recovery).

public void BumpEpoch();

FakeEngineClient.CreateEmpty() Method

Visibly empty stand-in for the unelevated no-service start — searching demo rows has no practical value (user verdict), so the auto-fallback shows zero results plus the setup notification instead. The data-bearing fake stays what --fake-engine is for.

public static FindMyFiles.Engine.FakeEngineClient CreateEmpty();

Returns

FakeEngineClient
A rowless fake that reports disconnected and yields no results.

FakeEngineClient.Dispose() Method

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose();

Implements Dispose()

FakeEngineClient.GetStatsAsync(CancellationToken) Method

Observability snapshot for the performance panel.

public System.Threading.Tasks.Task<FindMyFiles.Engine.EngineStatsData?> GetStatsAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatsAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<EngineStatsData>
The current engine stats, or null if unavailable.

FakeEngineClient.GetStatusAsync(CancellationToken) Method

Returns a snapshot of the current state (VolumeStatus) of every volume. Used for the initial display at startup and for the setup screen's decisions.

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.VolumeStatus>> GetStatusAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatusAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<VolumeStatus>>
A snapshot of the current status of every known volume.

Exceptions

EngineUnavailableException
service unreachable

FakeEngineClient.ListVolumesAsync(CancellationToken) Method

Returns the labels of the indexed volumes (those the engine currently recognizes).

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<string>> ListVolumesAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements ListVolumesAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<System.String>>
The labels of the volumes the engine currently knows about.

Exceptions

EngineUnavailableException
service unreachable

FakeEngineClient.SearchAsync(string, SearchOptions, CancellationToken) Method

Executes the query and returns a sort-settled result handle (Result) plus an optional timing trace. Pages are read lazily through the returned ISearchResult.

public System.Threading.Tasks.Task<FindMyFiles.Engine.SearchOutcome> SearchAsync(string query, FindMyFiles.Engine.SearchOptions options, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

query System.String

The query text to execute.

options SearchOptions

Search options (sort order, flags).

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements SearchAsync(string, SearchOptions, CancellationToken)

Returns

System.Threading.Tasks.Task<SearchOutcome>
The sort-ordered result handle plus an optional timing trace.

Exceptions

QuerySyntaxException
malformed query text

EngineUnavailableException
service unreachable

FakeEngineClient.StartIndexingAsync(IReadOnlyList<string>, CancellationToken) Method

Requests that indexing/re-indexing start for the given volumes (fire-and-trigger: progress arrives via VolumeUpdated / IndexChanged). MFT reads require elevation, so the work runs on the service side.

public System.Threading.Tasks.Task StartIndexingAsync(System.Collections.Generic.IReadOnlyList<string> volumes, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

volumes System.Collections.Generic.IReadOnlyList<System.String>

Labels of the volumes to (re)index.

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements StartIndexingAsync(IReadOnlyList<string>, CancellationToken)

Returns

System.Threading.Tasks.Task
A task that completes once the indexing request is accepted.

Exceptions

EngineUnavailableException
service unreachable

Events

FakeEngineClient.ConnectionChanged Event

Fires when the current Connection transitions. In-proc implementations never fire (always InProc). Fires from the pipe client's supervisor thread → marshal.

public event Action<EngineConnectionState>? ConnectionChanged;

Implements ConnectionChanged

Event Type

System.Action<EngineConnectionState>

FakeEngineClient.EngineErrorOccurred Event

The engine recorded a diagnostic (1=warn 2=error 3=panic). Details live in RecentErrors — pull on demand.

public event Action<int>? EngineErrorOccurred;

Implements EngineErrorOccurred

Event Type

System.Action<System.Int32>

FakeEngineClient.IndexChanged Event

New index content was published (USN apply or scan progress). The payload is the triggering volume label. The signal to re-evaluate the displayed query. Fires from an engine thread, so marshal to the UI thread (EngineEventMarshaler is the only crossing point).

public event Action<string>? IndexChanged;

Implements IndexChanged

Event Type

System.Action<System.String>

FakeEngineClient.VolumeUpdated Event

One volume's state transitioned (`Scanning`→`Ready` etc.). Emits the latest VolumeStatus. Fires from an engine thread → marshal.

public event Action<VolumeStatus>? VolumeUpdated;

Implements VolumeUpdated

Event Type

System.Action<VolumeStatus>

FindMyFiles

FindMyFiles.Engine

FfiEngineClient Class

In-proc engine client over fmf_engine.dll. Events arrive on engine threads; consumers marshal to the UI thread themselves.

public sealed class FfiEngineClient : FindMyFiles.Engine.IEngineClient, System.IDisposable

Inheritance System.Object → FfiEngineClient

Implements IEngineClient, System.IDisposable

Constructors

FfiEngineClient() Constructor

Creates the in-proc engine over the default machine index at %ProgramData%\find-my-files\index.

public FfiEngineClient();

Properties

FfiEngineClient.Connection Property

In-proc: no transport, no state transitions.

public FindMyFiles.Engine.EngineConnectionState Connection { get; }

Implements Connection

Property Value

EngineConnectionState

FfiEngineClient.IsScopeMode Property

True when this client runs in scope mode (ADR-0024: folder-walk over FindMyFiles.Engine.FfiEngineClient._scopeRoots) rather than whole-volume mode. Lets the ViewModel pick the scope-vs-privileged UI without reaching past IEngineClient.

public bool IsScopeMode { get; }

Property Value

System.Boolean

Methods

FfiEngineClient.CreateScope(IReadOnlyList<string>, IReadOnlyList<string>) Method

Creates a non-elevated **scope-mode** engine (ADR-0024) indexing only roots by folder-walk — no admin, no service. The index and the engine log both live under the portable data root (AppPaths): <exe>\data\{index,logs} by default, so scope mode pollutes nothing outside the app's own folder.

public static FindMyFiles.Engine.FfiEngineClient CreateScope(System.Collections.Generic.IReadOnlyList<string> roots, System.Collections.Generic.IReadOnlyList<string> excludes);

Parameters

roots System.Collections.Generic.IReadOnlyList<System.String>

Absolute folder roots to folder-walk and index.

excludes System.Collections.Generic.IReadOnlyList<System.String>

Absolute subfolders to prune from the walk (ADR-0025).

Returns

FfiEngineClient
A scope-mode client over the portable data root.

FfiEngineClient.Dispose() Method

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose();

Implements Dispose()

FfiEngineClient.GetStatsAsync(CancellationToken) Method

Observability snapshot for the performance panel.

public System.Threading.Tasks.Task<FindMyFiles.Engine.EngineStatsData?> GetStatsAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatsAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<EngineStatsData>
The current engine stats, or null if unavailable.

FfiEngineClient.GetStatusAsync(CancellationToken) Method

Returns a snapshot of the current state (VolumeStatus) of every volume. Used for the initial display at startup and for the setup screen's decisions.

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.VolumeStatus>> GetStatusAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatusAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<VolumeStatus>>
A snapshot of the current status of every known volume.

Exceptions

EngineUnavailableException
service unreachable

FfiEngineClient.ListVolumesAsync(CancellationToken) Method

Returns the labels of the indexed volumes (those the engine currently recognizes).

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<string>> ListVolumesAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements ListVolumesAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<System.String>>
The labels of the volumes the engine currently knows about.

Exceptions

EngineUnavailableException
service unreachable

FfiEngineClient.SearchAsync(string, SearchOptions, CancellationToken) Method

Executes the query and returns a sort-settled result handle (Result) plus an optional timing trace. Pages are read lazily through the returned ISearchResult.

public System.Threading.Tasks.Task<FindMyFiles.Engine.SearchOutcome> SearchAsync(string query, FindMyFiles.Engine.SearchOptions options, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

query System.String

The query text to execute.

options SearchOptions

Search options (sort order, flags).

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements SearchAsync(string, SearchOptions, CancellationToken)

Returns

System.Threading.Tasks.Task<SearchOutcome>
The sort-ordered result handle plus an optional timing trace.

Exceptions

QuerySyntaxException
malformed query text

EngineUnavailableException
service unreachable

FfiEngineClient.StartIndexingAsync(IReadOnlyList<string>, CancellationToken) Method

Requests that indexing/re-indexing start for the given volumes (fire-and-trigger: progress arrives via VolumeUpdated / IndexChanged). MFT reads require elevation, so the work runs on the service side.

public System.Threading.Tasks.Task StartIndexingAsync(System.Collections.Generic.IReadOnlyList<string> volumes, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

volumes System.Collections.Generic.IReadOnlyList<System.String>

Labels of the volumes to (re)index.

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements StartIndexingAsync(IReadOnlyList<string>, CancellationToken)

Returns

System.Threading.Tasks.Task
A task that completes once the indexing request is accepted.

Exceptions

EngineUnavailableException
service unreachable

Events

FfiEngineClient.ConnectionChanged Event

Fires when the current Connection transitions. In-proc implementations never fire (always InProc). Fires from the pipe client's supervisor thread → marshal.

public event Action<EngineConnectionState>? ConnectionChanged;

Implements ConnectionChanged

Event Type

System.Action<EngineConnectionState>

FfiEngineClient.EngineErrorOccurred Event

The engine recorded a diagnostic (1=warn 2=error 3=panic). Details live in RecentErrors — pull on demand.

public event Action<int>? EngineErrorOccurred;

Implements EngineErrorOccurred

Event Type

System.Action<System.Int32>

FfiEngineClient.IndexChanged Event

New index content was published (USN apply or scan progress). The payload is the triggering volume label. The signal to re-evaluate the displayed query. Fires from an engine thread, so marshal to the UI thread (EngineEventMarshaler is the only crossing point).

public event Action<string>? IndexChanged;

Implements IndexChanged

Event Type

System.Action<System.String>

FfiEngineClient.VolumeUpdated Event

One volume's state transitioned (`Scanning`→`Ready` etc.). Emits the latest VolumeStatus. Fires from an engine thread → marshal.

public event Action<VolumeStatus>? VolumeUpdated;

Implements VolumeUpdated

Event Type

System.Action<VolumeStatus>

FindMyFiles

FindMyFiles.Engine

FmfCase Enum

Case-matching mode (wire values of fmf-core's CaseMode).

public enum FmfCase

Fields

Smart 0

Case-insensitive unless the query contains an uppercase letter, in which case it becomes case-sensitive.

Insensitive 1

Always case-insensitive.

Sensitive 2

Always case-sensitive.

FindMyFiles

FindMyFiles.Engine

FmfSort Enum

Result sort key (wire values of fmf-core's SortKey).

public enum FmfSort

Fields

Name 0

Sort by file name.

Size 1

Sort by file size in bytes.

Mtime 2

Sort by modification time.

FindMyFiles

FindMyFiles.Engine

IEngineClient Interface

The single boundary the app uses to talk to the engine (docs/ARCHITECTURE.md). Implementations: PipeEngineClient (named pipe to fmf-service), FfiEngineClient (in-proc DLL, --engine=inproc) and FakeEngineClient (deterministic data for UI tests via --fake-engine). The shared observable behavior is executable: Tests/Contract/EngineClientContractTests runs the same suite against all implementations.

Cancellation is cooperative and fully plumbed (ADR-0018): a cancelled ct surfaces as System.OperationCanceledException (or a subclass) from every async member. Data shapes live in EngineTypes.cs.

public interface IEngineClient : System.IDisposable

Derived
FakeEngineClient
FfiEngineClient
PipeEngineClient

Implements System.IDisposable

Properties

IEngineClient.Connection Property

InProc for Ffi/Fake (fixed, never raises ConnectionChanged); the pipe client moves through Connecting/Connected/Reconnecting.

FindMyFiles.Engine.EngineConnectionState Connection { get; }

Property Value

EngineConnectionState

Methods

IEngineClient.GetStatsAsync(CancellationToken) Method

Observability snapshot for the performance panel.

System.Threading.Tasks.Task<FindMyFiles.Engine.EngineStatsData?> GetStatsAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task<EngineStatsData>
The current engine stats, or null if unavailable.

IEngineClient.GetStatusAsync(CancellationToken) Method

Returns a snapshot of the current state (VolumeStatus) of every volume. Used for the initial display at startup and for the setup screen's decisions.

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.VolumeStatus>> GetStatusAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<VolumeStatus>>
A snapshot of the current status of every known volume.

Exceptions

EngineUnavailableException
service unreachable

IEngineClient.ListVolumesAsync(CancellationToken) Method

Returns the labels of the indexed volumes (those the engine currently recognizes).

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<string>> ListVolumesAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<System.String>>
The labels of the volumes the engine currently knows about.

Exceptions

EngineUnavailableException
service unreachable

IEngineClient.SearchAsync(string, SearchOptions, CancellationToken) Method

Executes the query and returns a sort-settled result handle (Result) plus an optional timing trace. Pages are read lazily through the returned ISearchResult.

System.Threading.Tasks.Task<FindMyFiles.Engine.SearchOutcome> SearchAsync(string query, FindMyFiles.Engine.SearchOptions options, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

query System.String

The query text to execute.

options SearchOptions

Search options (sort order, flags).

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task<SearchOutcome>
The sort-ordered result handle plus an optional timing trace.

Exceptions

QuerySyntaxException
malformed query text

EngineUnavailableException
service unreachable

IEngineClient.StartIndexingAsync(IReadOnlyList<string>, CancellationToken) Method

Requests that indexing/re-indexing start for the given volumes (fire-and-trigger: progress arrives via VolumeUpdated / IndexChanged). MFT reads require elevation, so the work runs on the service side.

System.Threading.Tasks.Task StartIndexingAsync(System.Collections.Generic.IReadOnlyList<string> volumes, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

volumes System.Collections.Generic.IReadOnlyList<System.String>

Labels of the volumes to (re)index.

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task
A task that completes once the indexing request is accepted.

Exceptions

EngineUnavailableException
service unreachable

Events

IEngineClient.ConnectionChanged Event

Fires when the current Connection transitions. In-proc implementations never fire (always InProc). Fires from the pipe client's supervisor thread → marshal.

event Action<EngineConnectionState>? ConnectionChanged;

Event Type

System.Action<EngineConnectionState>

IEngineClient.EngineErrorOccurred Event

The engine recorded a diagnostic (1=warn 2=error 3=panic). Details live in RecentErrors — pull on demand.

event Action<int>? EngineErrorOccurred;

Event Type

System.Action<System.Int32>

IEngineClient.IndexChanged Event

New index content was published (USN apply or scan progress). The payload is the triggering volume label. The signal to re-evaluate the displayed query. Fires from an engine thread, so marshal to the UI thread (EngineEventMarshaler is the only crossing point).

event Action<string>? IndexChanged;

Event Type

System.Action<System.String>

IEngineClient.VolumeUpdated Event

One volume's state transitioned (`Scanning`→`Ready` etc.). Emits the latest VolumeStatus. Fires from an engine thread → marshal.

event Action<VolumeStatus>? VolumeUpdated;

Event Type

System.Action<VolumeStatus>

FindMyFiles

FindMyFiles.Engine

ISearchResult Interface

Materialized, sort-ordered result; pages are O(1) reads.

public interface ISearchResult : System.IDisposable

Implements System.IDisposable

Properties

ISearchResult.Count Property

The settled total match count (the upper bound on rows obtainable via GetRangeAsync(long, int, CancellationToken)). This determines the virtualized list's scroll range.

long Count { get; }

Property Value

System.Int64

Methods

ISearchResult.GetRangeAsync(long, int, CancellationToken) Method

Fetches up to count rows from offset in the result (page read of the visible window).

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.RowData>> GetRangeAsync(long offset, int count, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

offset System.Int64

0-based row offset from the start.

count System.Int32

Maximum number of rows to fetch.

ct System.Threading.CancellationToken

Cooperative cancellation token.

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<RowData>>
The RowData for the requested range (may be fewer than count near the end).

Exceptions

StaleResultException
The index was structurally rebuilt — re-run the query.

FindMyFiles

FindMyFiles.Engine

IndexStatsData Class

Memory accounting and generation state for one volume index (subset of fmf-core's IndexStats the UI surfaces). Feeds the bytes/entry gate in the F12 panel.

public sealed class IndexStatsData

Inheritance System.Object → IndexStatsData

Properties

IndexStatsData.BytesPerEntry Property

TotalBytes / Entries; the headline RAM-efficiency figure measured against the ≤110 B/file target.

public double BytesPerEntry { get; set; }

Property Value

System.Double

IndexStatsData.ContentGeneration Property

Bumps on every content change (USN apply, rescan). A stable value means an Unchanged re-query is possible; the structural generation (not exposed here) is what invalidates a result with StaleResultException.

public ulong ContentGeneration { get; set; }

Property Value

System.UInt64

IndexStatsData.Entries Property

Total rows including tombstones — the physical slot count.

public ulong Entries { get; set; }

Property Value

System.UInt64

IndexStatsData.LiveEntries Property

Rows that still resolve to a live file (the searchable population).

public ulong LiveEntries { get; set; }

Property Value

System.UInt64

IndexStatsData.Tombstones Property

Dead rows awaiting compaction (deleted entries not yet reclaimed); Entries - LiveEntries.

public ulong Tombstones { get; set; }

Property Value

System.UInt64

IndexStatsData.TotalBytes Property

Resident bytes of this index in the engine process (all columns + derived query caches) — the numerator of the bytes/entry gate.

public ulong TotalBytes { get; set; }

Property Value

System.UInt64

IndexStatsData.Volume Property

Drive label this index covers (e.g. "C:").

public string Volume { get; set; }

Property Value

System.String

FindMyFiles

FindMyFiles.Engine

PipeEngineClient Class

Engine client over the fmf-service named pipe (docs/ARCHITECTURE.md "Pipe protocol"). This class is the connection *supervisor* plus the request multiplexing table; the established connection itself (stream, read loop, serialized writer, epoch) is one FindMyFiles.Engine.PipeConnection object, replaced wholesale on every (re)connect. The supervisor loop: connect → server-is-SYSTEM check (default pipe name only; SECURITY.md Threat 4) → Hello (version check; a mismatch is fatal) → Subscribe → IndexStatus (synthesized VolumeUpdated + IndexChanged) → Connected. On disconnect every pending request fails fast with EngineUnavailableException, live results turn stale because their connection's epoch can never be current again, and reconnection retries forever with 250ms→5s backoff. Events fire on the read-loop thread — consumers marshal (see EngineEventMarshaler), same contract as the FFI client. No DispatcherQueue dependency.

public sealed class PipeEngineClient : FindMyFiles.Engine.IEngineClient, System.IDisposable

Inheritance System.Object → PipeEngineClient

Implements IEngineClient, System.IDisposable

Constructors

PipeEngineClient(string) Constructor

Connects to the fmf-service named pipe and starts the supervisor loop immediately. pipeName defaults to FindMyFiles.Engine.PipeProtocol.DefaultPipeName; only that default name has its server identity verified (SECURITY.md Threat 4) — a custom name (tests) skips the SYSTEM check.

public PipeEngineClient(string pipeName="fmf-engine-v2");

Parameters

pipeName System.String

Pipe to connect to, as either the short name or the full \\.\pipe\… path.

Properties

PipeEngineClient.Connection Property

InProc for Ffi/Fake (fixed, never raises ConnectionChanged); the pipe client moves through Connecting/Connected/Reconnecting.

public FindMyFiles.Engine.EngineConnectionState Connection { get; }

Implements Connection

Property Value

EngineConnectionState

Methods

PipeEngineClient.Dispose() Method

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose();

Implements Dispose()

PipeEngineClient.GetStatsAsync(CancellationToken) Method

Observability snapshot for the performance panel.

public System.Threading.Tasks.Task<FindMyFiles.Engine.EngineStatsData?> GetStatsAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatsAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<EngineStatsData>
The current engine stats, or null if unavailable.

PipeEngineClient.GetStatusAsync(CancellationToken) Method

Returns a snapshot of the current state (VolumeStatus) of every volume. Used for the initial display at startup and for the setup screen's decisions.

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.VolumeStatus>> GetStatusAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements GetStatusAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<VolumeStatus>>
A snapshot of the current status of every known volume.

Exceptions

EngineUnavailableException
service unreachable

PipeEngineClient.ListVolumesAsync(CancellationToken) Method

Returns the labels of the indexed volumes (those the engine currently recognizes).

public System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<string>> ListVolumesAsync(System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements ListVolumesAsync(CancellationToken)

Returns

System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<System.String>>
The labels of the volumes the engine currently knows about.

Exceptions

EngineUnavailableException
service unreachable

PipeEngineClient.Probe(string, TimeSpan) Method

Can a server be reached and Hello'd on this pipe within the timeout? Used by the factory's `auto` mode (250ms budget).

public static bool Probe(string pipeName, System.TimeSpan timeout);

Parameters

pipeName System.String

Pipe to probe, short name or full path.

timeout System.TimeSpan

Budget for connect plus the Hello round-trip.

Returns

System.Boolean
True if a protocol-compatible server answered within the timeout.

PipeEngineClient.SearchAsync(string, SearchOptions, CancellationToken) Method

Executes the query and returns a sort-settled result handle (Result) plus an optional timing trace. Pages are read lazily through the returned ISearchResult.

public System.Threading.Tasks.Task<FindMyFiles.Engine.SearchOutcome> SearchAsync(string query, FindMyFiles.Engine.SearchOptions options, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

query System.String

The query text to execute.

options SearchOptions

Search options (sort order, flags).

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements SearchAsync(string, SearchOptions, CancellationToken)

Returns

System.Threading.Tasks.Task<SearchOutcome>
The sort-ordered result handle plus an optional timing trace.

Exceptions

QuerySyntaxException
malformed query text

EngineUnavailableException
service unreachable

PipeEngineClient.StartIndexingAsync(IReadOnlyList<string>, CancellationToken) Method

Requests that indexing/re-indexing start for the given volumes (fire-and-trigger: progress arrives via VolumeUpdated / IndexChanged). MFT reads require elevation, so the work runs on the service side.

public System.Threading.Tasks.Task StartIndexingAsync(System.Collections.Generic.IReadOnlyList<string> volumes, System.Threading.CancellationToken ct=default(System.Threading.CancellationToken));

Parameters

volumes System.Collections.Generic.IReadOnlyList<System.String>

Labels of the volumes to (re)index.

ct System.Threading.CancellationToken

Cooperative cancellation token.

Implements StartIndexingAsync(IReadOnlyList<string>, CancellationToken)

Returns

System.Threading.Tasks.Task
A task that completes once the indexing request is accepted.

Exceptions

EngineUnavailableException
service unreachable

Events

PipeEngineClient.ConnectionChanged Event

Fires when the current Connection transitions. In-proc implementations never fire (always InProc). Fires from the pipe client's supervisor thread → marshal.

public event Action<EngineConnectionState>? ConnectionChanged;

Implements ConnectionChanged

Event Type

System.Action<EngineConnectionState>

PipeEngineClient.EngineErrorOccurred Event

The engine recorded a diagnostic (1=warn 2=error 3=panic). Details live in RecentErrors — pull on demand.

public event Action<int>? EngineErrorOccurred;

Implements EngineErrorOccurred

Event Type

System.Action<System.Int32>

PipeEngineClient.IndexChanged Event

New index content was published (USN apply or scan progress). The payload is the triggering volume label. The signal to re-evaluate the displayed query. Fires from an engine thread, so marshal to the UI thread (EngineEventMarshaler is the only crossing point).

public event Action<string>? IndexChanged;

Implements IndexChanged

Event Type

System.Action<System.String>

PipeEngineClient.VolumeUpdated Event

One volume's state transitioned (`Scanning`→`Ready` etc.). Emits the latest VolumeStatus. Fires from an engine thread → marshal.

public event Action<VolumeStatus>? VolumeUpdated;

Implements VolumeUpdated

Event Type

System.Action<VolumeStatus>

FindMyFiles

FindMyFiles.Engine

QuerySyntaxException Class

The query string is syntactically malformed and SearchAsync(string, SearchOptions, CancellationToken) failed to parse it.

public sealed class QuerySyntaxException : System.Exception

Inheritance System.ObjectSystem.Exception → QuerySyntaxException

Constructors

QuerySyntaxException(string) Constructor

The query string is syntactically malformed and SearchAsync(string, SearchOptions, CancellationToken) failed to parse it.

public QuerySyntaxException(string message);

Parameters

message System.String

The human-readable reason returned by the parser.

FindMyFiles

FindMyFiles.Engine

QueryTraceData Class

Stage breakdown of one query (mirrors fmf-core metrics.rs).

public sealed class QueryTraceData

Inheritance System.Object → QueryTraceData

Properties

QueryTraceData.Cache Property

Per-volume query-cache outcome: "miss", "refine" (all volumes narrowed the previous result) or "partial" (mixed).

public string Cache { get; set; }

Property Value

System.String

QueryTraceData.CompileUs Property

µs spent compiling the AST into the matcher.

public ulong CompileUs { get; set; }

Property Value

System.UInt64

QueryTraceData.Driver Property

Which execution strategy generated the candidates (shown in the perf panel): e.g. "full-scan", "pool-scan", "suffix", "perm-walk".

public string Driver { get; set; }

Property Value

System.String

QueryTraceData.EntriesScanned Property

Entries examined by the scan (the denominator of the match rate; far larger than Hits for a full scan).

public ulong EntriesScanned { get; set; }

Property Value

System.UInt64

QueryTraceData.ExcludedSkipped Property

Entries skipped by exclusion rules (hidden/system filtering, excluded paths) before matching.

public ulong ExcludedSkipped { get; set; }

Property Value

System.UInt64

QueryTraceData.Hits Property

Rows that matched — the resulting Count.

public ulong Hits { get; set; }

Property Value

System.UInt64

QueryTraceData.MaterializeUs Property

µs spent materializing matched rows into the result.

public ulong MaterializeUs { get; set; }

Property Value

System.UInt64

QueryTraceData.MemoUs Property

µs spent on the dir-path memo (path queries only; 0 when warm or not a path query).

public ulong MemoUs { get; set; }

Property Value

System.UInt64

QueryTraceData.MergeUs Property

µs spent on the multi-volume k-way merge (0 for one volume).

public ulong MergeUs { get; set; }

Property Value

System.UInt64

QueryTraceData.ParseUs Property

µs spent parsing the query text into its AST.

public ulong ParseUs { get; set; }

Property Value

System.UInt64

QueryTraceData.Query Property

The query text exactly as the engine parsed it.

public string Query { get; set; }

Property Value

System.String

QueryTraceData.ScanUs Property

µs spent scanning candidates across all volumes.

public ulong ScanUs { get; set; }

Property Value

System.UInt64

QueryTraceData.TotalUs Property

End-to-end µs for the whole query; the value fed into the p50/p99 histogram.

public ulong TotalUs { get; set; }

Property Value

System.UInt64

QueryTraceData.Unchanged Property

Engine-verified: same query as last time with identical id lists on every volume — the screen has nothing to change.

public bool Unchanged { get; set; }

Property Value

System.Boolean

QueryTraceData.Volumes Property

How many volume indexes participated in this query.

public uint Volumes { get; set; }

Property Value

System.UInt32

FindMyFiles

FindMyFiles.Engine

RegexScope Enum

Which haystack a whole-query regex runs against (wire values of fmf-core's RegexScope; the regex_mode bit1).

public enum RegexScope

Fields

Name 0

Match the file name.

Path 1

Match the full path.

FindMyFiles

FindMyFiles.Engine

RowData Class

One result row decoded from a page (the C# face of fmf-core's 48-byte FmfRow plus its WTF-8 name/path strings). Immutable; the UI's ResultRow view-model is filled from it.

public sealed record RowData : System.IEquatable<FindMyFiles.Engine.RowData>

Inheritance System.Object → RowData

Implements System.IEquatable<RowData>

Constructors

RowData(ulong, ulong, ulong, long, uint, string, string) Constructor

One result row decoded from a page (the C# face of fmf-core's 48-byte FmfRow plus its WTF-8 name/path strings). Immutable; the UI's ResultRow view-model is filled from it.

public RowData(ulong EntryRef, ulong Frn, ulong Size, long Mtime, uint Flags, string Name, string ParentPath);

Parameters

EntryRef System.UInt64

Engine-internal stable handle for the entry within its volume index (the identity used for refine/unchanged comparisons) — not the NTFS reference.

Frn System.UInt64

NTFS File Reference Number (record number in the low 48 bits, sequence in the high 16) — the identity to correlate with USN records and the filesystem.

Size System.UInt64

File size in bytes (0 for directories).

Mtime System.Int64

Last-modified time as a Windows FILETIME (100 ns ticks since 1601-01-01 UTC); 0 means unknown/unset and renders as an empty timestamp.

Flags System.UInt32

Bit field of NTFS attributes; bit 0 is the directory flag (see IsDirectory).

Name System.String

Leaf file or directory name.

ParentPath System.String

Containing directory path including its trailing separator (e.g. "C:\"), so FullPath is a plain concatenation.

Properties

RowData.EntryRef Property

Engine-internal stable handle for the entry within its volume index (the identity used for refine/unchanged comparisons) — not the NTFS reference.

public ulong EntryRef { get; init; }

Property Value

System.UInt64

RowData.Flags Property

Bit field of NTFS attributes; bit 0 is the directory flag (see IsDirectory).

public uint Flags { get; init; }

Property Value

System.UInt32

RowData.Frn Property

NTFS File Reference Number (record number in the low 48 bits, sequence in the high 16) — the identity to correlate with USN records and the filesystem.

public ulong Frn { get; init; }

Property Value

System.UInt64

RowData.FullPath Property

The full path, ParentPath (which already ends in a separator) concatenated with Name.

public string FullPath { get; }

Property Value

System.String

RowData.IsDirectory Property

True when this row is a directory (bit 0 of Flags).

public bool IsDirectory { get; }

Property Value

System.Boolean

RowData.Mtime Property

Last-modified time as a Windows FILETIME (100 ns ticks since 1601-01-01 UTC); 0 means unknown/unset and renders as an empty timestamp.

public long Mtime { get; init; }

Property Value

System.Int64

RowData.Name Property

Leaf file or directory name.

public string Name { get; init; }

Property Value

System.String

RowData.ParentPath Property

Containing directory path including its trailing separator (e.g. "C:\"), so FullPath is a plain concatenation.

public string ParentPath { get; init; }

Property Value

System.String

RowData.Size Property

File size in bytes (0 for directories).

public ulong Size { get; init; }

Property Value

System.UInt64

FindMyFiles

FindMyFiles.Engine

SearchOptions Class

The knobs that shape a search, passed to SearchAsync(string, SearchOptions, CancellationToken) (the C# face of fmf-core's FmfQueryOptions).

public sealed record SearchOptions : System.IEquatable<FindMyFiles.Engine.SearchOptions>

Inheritance System.Object → SearchOptions

Implements System.IEquatable<SearchOptions>

Constructors

SearchOptions(FmfSort, bool, FmfCase, bool, bool, RegexScope) Constructor

The knobs that shape a search, passed to SearchAsync(string, SearchOptions, CancellationToken) (the C# face of fmf-core's FmfQueryOptions).

public SearchOptions(FindMyFiles.Engine.FmfSort Sort, bool Descending, FindMyFiles.Engine.FmfCase Case, bool IncludeHiddenSystem=false, bool RegexMode=false, FindMyFiles.Engine.RegexScope Scope=FindMyFiles.Engine.RegexScope.Name);

Parameters

Sort FmfSort

Which key to order results by.

Descending System.Boolean

True for descending order; false for ascending.

Case FmfCase

How query case is matched against names.

IncludeHiddenSystem System.Boolean

When true, hidden/system entries are included; they are excluded by default.

RegexMode System.Boolean

When true, the whole query text is one regular expression (the regex: per-term syntax still works regardless).

Scope RegexScope

Which haystack the whole-query regex matches against (ignored unless RegexMode).

Fields

SearchOptions.Default Field

The app's default search: by Name, ascending, Smart case, hidden/system excluded, regex mode off.

public static readonly SearchOptions Default;

Field Value

SearchOptions

Properties

SearchOptions.Case Property

How query case is matched against names.

public FindMyFiles.Engine.FmfCase Case { get; init; }

Property Value

FmfCase

SearchOptions.Descending Property

True for descending order; false for ascending.

public bool Descending { get; init; }

Property Value

System.Boolean

SearchOptions.IncludeHiddenSystem Property

When true, hidden/system entries are included; they are excluded by default.

public bool IncludeHiddenSystem { get; init; }

Property Value

System.Boolean

SearchOptions.RegexMode Property

When true, the whole query text is one regular expression (the regex: per-term syntax still works regardless).

public bool RegexMode { get; init; }

Property Value

System.Boolean

SearchOptions.RegexModeBits Property

The packed FmfQueryOptions.regex_mode wire value: bit0 = whole-query regex on, bit1 = scope (0 name / 1 path).

public uint RegexModeBits { get; }

Property Value

System.UInt32

SearchOptions.Scope Property

Which haystack the whole-query regex matches against (ignored unless RegexMode).

public FindMyFiles.Engine.RegexScope Scope { get; init; }

Property Value

RegexScope

SearchOptions.Sort Property

Which key to order results by.

public FindMyFiles.Engine.FmfSort Sort { get; init; }

Property Value

FmfSort

FindMyFiles

FindMyFiles.Engine

SearchOutcome Class

What SearchAsync(string, SearchOptions, CancellationToken) returns: the materialized ISearchResult the UI pages through, paired with the per-query QueryTraceData the engine attached (null when tracing was unavailable, e.g. a serialization failure — the result is still valid).

public sealed record SearchOutcome : System.IEquatable<FindMyFiles.Engine.SearchOutcome>

Inheritance System.Object → SearchOutcome

Implements System.IEquatable<SearchOutcome>

Constructors

SearchOutcome(ISearchResult, QueryTraceData) Constructor

What SearchAsync(string, SearchOptions, CancellationToken) returns: the materialized ISearchResult the UI pages through, paired with the per-query QueryTraceData the engine attached (null when tracing was unavailable, e.g. a serialization failure — the result is still valid).

public SearchOutcome(FindMyFiles.Engine.ISearchResult Result, FindMyFiles.Engine.QueryTraceData? Trace);

Parameters

Result ISearchResult

The sort-ordered, O(1)-paged result set.

Trace QueryTraceData

Stage timings for the F12 perf panel, or null.

Properties

SearchOutcome.Result Property

The sort-ordered, O(1)-paged result set.

public FindMyFiles.Engine.ISearchResult Result { get; init; }

Property Value

ISearchResult

SearchOutcome.Trace Property

Stage timings for the F12 perf panel, or null.

public FindMyFiles.Engine.QueryTraceData? Trace { get; init; }

Property Value

QueryTraceData

FindMyFiles

FindMyFiles.Engine

StaleResultException Class

The index was structurally rebuilt and the row IDs of a held result handle are now invalid (thrown from GetRangeAsync(long, int, CancellationToken)). Recovery is to re-run the query.

public sealed class StaleResultException : System.Exception

Inheritance System.ObjectSystem.Exception → StaleResultException

Constructors

StaleResultException() Constructor

Initializes with the canned message.

public StaleResultException();

FindMyFiles

FindMyFiles.Engine

TransportStatsData Class

Client-side pipe transport metrics. Null for in-proc clients; the pipe client fills it on every GetStatsAsync(CancellationToken).

public sealed class TransportStatsData

Inheritance System.Object → TransportStatsData

Properties

TransportStatsData.AbiVersion Property

ABI version the server reported at handshake — must match the client's EngineContract.AbiVersion.

public uint AbiVersion { get; set; }

Property Value

System.UInt32

TransportStatsData.PageRttEwmaUs Property

EWMA of page-fetch round-trip latency in µs (the wire cost a page read adds on top of the engine's own time).

public double PageRttEwmaUs { get; set; }

Property Value

System.Double

TransportStatsData.Reconnects Property

How many times the supervisor has re-established the pipe since process start — a churn indicator.

public long Reconnects { get; set; }

Property Value

System.Int64

TransportStatsData.ServerPid Property

PID of the fmf-service process on the other end (from the Hello handshake); shown so users can find it in Task Manager.

public uint ServerPid { get; set; }

Property Value

System.UInt32

TransportStatsData.State Property

Current EngineConnectionState rendered as text (e.g. "Connected", "Reconnecting").

public string State { get; set; }

Property Value

System.String

FindMyFiles

FindMyFiles.Engine

UsnTraceData Class

One applied USN journal batch — how a burst of filesystem changes landed in the index (mirrors fmf-core's UsnTrace). Drives the change-reflection latency shown in the perf panel.

public sealed class UsnTraceData

Inheritance System.Object → UsnTraceData

Properties

UsnTraceData.ApplyUs Property

µs to apply the whole batch to the index.

public ulong ApplyUs { get; set; }

Property Value

System.UInt64

UsnTraceData.Deleted Property

Entries tombstoned (deletes/renames-away).

public ulong Deleted { get; set; }

Property Value

System.UInt64

UsnTraceData.Records Property

Raw USN records in the batch (before coalescing).

public ulong Records { get; set; }

Property Value

System.UInt64

UsnTraceData.StatFailures Property

Stat fetches that failed (the entry keeps its prior size/mtime); also counted in FindMyFiles.Engine.CountersData.StatFetchFailures.

public ulong StatFailures { get; set; }

Property Value

System.UInt64

UsnTraceData.StatUpdated Property

Entries whose size/mtime were refreshed via a stat fetch.

public ulong StatUpdated { get; set; }

Property Value

System.UInt64

UsnTraceData.Upserted Property

Entries created or updated in the index.

public ulong Upserted { get; set; }

Property Value

System.UInt64

UsnTraceData.Volume Property

Drive label the batch was applied to.

public string Volume { get; set; }

Property Value

System.String

FindMyFiles

FindMyFiles.Engine

VolumeState Enum

Lifecycle of a volume's index (wire values of fmf-core's VolumeState), reported via VolumeUpdated.

public enum VolumeState

Fields

Scanning 0

Initial scan in progress; results are incomplete.

Ready 1

Index is complete and searchable.

Rescanning 2

A rescan is rebuilding an already-ready index (e.g. after a USN gap); the prior result stays usable.

Failed 3

Indexing failed (access denied, unsupported filesystem); this volume contributes no results.

FindMyFiles

FindMyFiles.Engine

VolumeStatus Class

A volume's current index status — the payload of an VolumeUpdated event and of GetStatusAsync(CancellationToken).

public sealed record VolumeStatus : System.IEquatable<FindMyFiles.Engine.VolumeStatus>

Inheritance System.Object → VolumeStatus

Implements System.IEquatable<VolumeStatus>

Constructors

VolumeStatus(string, VolumeState, ulong) Constructor

A volume's current index status — the payload of an VolumeUpdated event and of GetStatusAsync(CancellationToken).

public VolumeStatus(string Label, FindMyFiles.Engine.VolumeState State, ulong Entries);

Parameters

Label System.String

Drive label (e.g. "C:").

State VolumeState

Where the index is in its lifecycle.

Entries System.UInt64

Indexed entry count so far (grows while Scanning).

Properties

VolumeStatus.Entries Property

Indexed entry count so far (grows while Scanning).

public ulong Entries { get; init; }

Property Value

System.UInt64

VolumeStatus.Label Property

Drive label (e.g. "C:").

public string Label { get; init; }

Property Value

System.String

VolumeStatus.State Property

Where the index is in its lifecycle.

public FindMyFiles.Engine.VolumeState State { get; init; }

Property Value

VolumeState

FindMyFiles

FindMyFiles.Engine Namespace

Classes
CountersDataDegradation counters of the stats JSON (snake_case keys — deserialize with SnakeCaseLower). Generated from the contract's counter-name registry; nonzero values surface in the F12 panel.
EngineClientFactoryEngine transport selection, in priority order: CLI flags (--fake-engine / --engine=pipe|inproc / --pipe-name=…) > settings.json "engine" > auto. Auto probes the service pipe for 250ms (through Hello) and falls back to the in-proc FFI engine when no service answers.
EngineEventMarshalerThe single crossing point from engine threads to the UI thread. IEngineClient events fire on engine / pipe read-loop threads; this class subscribes to all four, marshals each through TryEnqueue(Action) and re-raises it as its own event on the UI thread. Consumers (ViewModels, the orchestrator) attach plain handlers and never marshal themselves — the per-subscriber inline `dispatcher.TryEnqueue` lambdas this replaces were the audit's "scattered crossing" finding. The upstream delegates are held in fields for the subscription lifetime (the GC-rooting rule for callback delegates, satisfied structurally).
EngineExceptionThe engine rejected an operation with a structured error code (the transport is alive but the engine returned a failure). The code maps to the `FMF_E_*` table in docs/ARCHITECTURE.md.
EngineStatsDataThe whole observability snapshot behind the F12 perf panel — what GetStatsAsync(CancellationToken) returns (the UI subset of fmf-core's MetricsSnapshot).
EngineUnavailableExceptionThe engine transport is down (pipe disconnected, request timed out, service not running). Pending requests fail fast with this; the supervisor keeps reconnecting in the background.
ErrorEventDataOne entry from the engine's diagnostic ring (WARN+ events and panics; mirrors fmf-core's ErrorEvent). Pulled on demand after an EngineErrorOccurred signal and listed in the F12 panel.
FakeEngineClientDeterministic in-memory engine for UI tests and unelevated development (`--fake-engine`). 100k entries from a fixed seed; substring search only. Contract-conforming (EngineClientContractTests): query-syntax verdicts come from the shared golden fixture (contract/golden/invalid_queries.json, pinned by the real Rust parser — verdict drift is caught on the Rust side), cancellation is honored, and BumpEpoch() lets tests drive the Stale→requery recovery path without a real engine.
FfiEngineClientIn-proc engine client over fmf_engine.dll. Events arrive on engine threads; consumers marshal to the UI thread themselves.
IndexStatsDataMemory accounting and generation state for one volume index (subset of fmf-core's IndexStats the UI surfaces). Feeds the bytes/entry gate in the F12 panel.
PipeEngineClientEngine client over the fmf-service named pipe (docs/ARCHITECTURE.md "Pipe protocol"). This class is the connection *supervisor* plus the request multiplexing table; the established connection itself (stream, read loop, serialized writer, epoch) is one FindMyFiles.Engine.PipeConnection object, replaced wholesale on every (re)connect. The supervisor loop: connect → server-is-SYSTEM check (default pipe name only; SECURITY.md Threat 4) → Hello (version check; a mismatch is fatal) → Subscribe → IndexStatus (synthesized VolumeUpdated + IndexChanged) → Connected. On disconnect every pending request fails fast with EngineUnavailableException, live results turn stale because their connection's epoch can never be current again, and reconnection retries forever with 250ms→5s backoff. Events fire on the read-loop thread — consumers marshal (see EngineEventMarshaler), same contract as the FFI client. No DispatcherQueue dependency.
QuerySyntaxExceptionThe query string is syntactically malformed and SearchAsync(string, SearchOptions, CancellationToken) failed to parse it.
QueryTraceDataStage breakdown of one query (mirrors fmf-core metrics.rs).
RowDataOne result row decoded from a page (the C# face of fmf-core's 48-byte FmfRow plus its WTF-8 name/path strings). Immutable; the UI's ResultRow view-model is filled from it.
SearchOptionsThe knobs that shape a search, passed to SearchAsync(string, SearchOptions, CancellationToken) (the C# face of fmf-core's FmfQueryOptions).
SearchOutcomeWhat SearchAsync(string, SearchOptions, CancellationToken) returns: the materialized ISearchResult the UI pages through, paired with the per-query QueryTraceData the engine attached (null when tracing was unavailable, e.g. a serialization failure — the result is still valid).
StaleResultExceptionThe index was structurally rebuilt and the row IDs of a held result handle are now invalid (thrown from GetRangeAsync(long, int, CancellationToken)). Recovery is to re-run the query.
TransportStatsDataClient-side pipe transport metrics. Null for in-proc clients; the pipe client fills it on every GetStatsAsync(CancellationToken).
UsnTraceDataOne applied USN journal batch — how a burst of filesystem changes landed in the index (mirrors fmf-core's UsnTrace). Drives the change-reflection latency shown in the perf panel.
VolumeStatusA volume's current index status — the payload of an VolumeUpdated event and of GetStatusAsync(CancellationToken).
Interfaces
IEngineClientThe single boundary the app uses to talk to the engine (docs/ARCHITECTURE.md). Implementations: PipeEngineClient (named pipe to fmf-service), FfiEngineClient (in-proc DLL, --engine=inproc) and FakeEngineClient (deterministic data for UI tests via --fake-engine). The shared observable behavior is executable: Tests/Contract/EngineClientContractTests runs the same suite against all implementations. Cancellation is cooperative and fully plumbed (ADR-0018): a cancelled ct surfaces as System.OperationCanceledException (or a subclass) from every async member. Data shapes live in EngineTypes.cs.
ISearchResultMaterialized, sort-ordered result; pages are O(1) reads.
Enums
EngineConnectionStateTransport state of the engine boundary. In-proc clients are always InProc; the pipe client reports its supervisor state.
FmfCaseCase-matching mode (wire values of fmf-core's CaseMode).
FmfSortResult sort key (wire values of fmf-core's SortKey).
RegexScopeWhich haystack a whole-query regex runs against (wire values of fmf-core's RegexScope; the regex_mode bit1).
VolumeStateLifecycle of a volume's index (wire values of fmf-core's VolumeState), reported via VolumeUpdated.

FindMyFiles

FindMyFiles.FindMyFiles_XamlTypeInfo

XamlMetaDataProvider Class

Main class for providing metadata for the app or library

public sealed class XamlMetaDataProvider : Microsoft.UI.Xaml.Markup.IXamlMetadataProvider

Inheritance System.Object → XamlMetaDataProvider

Implements Microsoft.UI.Xaml.Markup.IXamlMetadataProvider

Methods

XamlMetaDataProvider.GetXamlType(string) Method

GetXamlType(String)

public Microsoft.UI.Xaml.Markup.IXamlType GetXamlType(string fullName);

Parameters

fullName System.String

Implements GetXamlType(string)

Returns

Microsoft.UI.Xaml.Markup.IXamlType

XamlMetaDataProvider.GetXamlType(Type) Method

GetXamlType(Type)

public Microsoft.UI.Xaml.Markup.IXamlType GetXamlType(System.Type type);

Parameters

type System.Type

Implements GetXamlType(Type)

Returns

Microsoft.UI.Xaml.Markup.IXamlType

XamlMetaDataProvider.GetXmlnsDefinitions() Method

GetXmlnsDefinitions()

public Microsoft.UI.Xaml.Markup.XmlnsDefinition[] GetXmlnsDefinitions();

Implements GetXmlnsDefinitions()

Returns

Microsoft.UI.Xaml.Markup.XmlnsDefinition[]

FindMyFiles

FindMyFiles.FindMyFiles_XamlTypeInfo Namespace

Classes
XamlMetaDataProviderMain class for providing metadata for the app or library

FindMyFiles

FindMyFiles.Highlighting

CompiledHighlighter Class

A query compiled into the positive text needles worth highlighting. Pure (no WinUI), so it is unit-testable and reusable across rows. Built once per query by Compile(string) and queried per displayed string by Ranges(string, HighlightField).

Highlighting deliberately mirrors only the *simple, certain* slice of the engine's match semantics (fmf-core query/): plain substrings, anchored lit*/*lit/*lit* wildcards, and smart-case folding (engine/crates/fmf-core/src/wtf8.rs). Anything the UI cannot reproduce exactly — user regex, general wildcards, negation, path wildcards — is left un-highlighted rather than guessed at: a row the engine returned is never hidden, only its emphasis is skipped (don't crash / don't go silent). This guarantees the UI never lights up a position the engine did not actually match.

public sealed class CompiledHighlighter : FindMyFiles.Highlighting.IHighlighter

Inheritance System.Object → CompiledHighlighter

Implements IHighlighter

Fields

CompiledHighlighter.Empty Field

A highlighter with no terms — every Ranges(string, HighlightField) call returns empty. Used for empty/filter-only queries.

public static readonly CompiledHighlighter Empty;

Field Value

CompiledHighlighter

Properties

CompiledHighlighter.IsEmpty Property

True when nothing will ever be highlighted — the caller can skip per-row work entirely.

public bool IsEmpty { get; }

Implements IsEmpty

Property Value

System.Boolean

Methods

CompiledHighlighter.Ranges(string, HighlightField) Method

The ranges of text matched by the terms targeting field, sorted by start and with overlapping/adjacent runs merged. Indices/lengths are UTF-16 units of text itself, ready to slice. Empty when nothing matches (or the query has no terms for this field).

public System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange> Ranges(string text, FindMyFiles.Highlighting.HighlightField field);

Parameters

text System.String

The displayed string (a name, or a full path).

field HighlightField

Which term family to apply.

Implements Ranges(string, HighlightField)

Returns

System.Collections.Generic.IReadOnlyList<HighlightRange>
The sorted, merged highlight ranges; empty when nothing matches.

FindMyFiles

FindMyFiles.Highlighting

HighlightField Enum

Which displayed string a highlight term is matched against — the file name leaf, or the full path (parent + name).

public enum HighlightField

Fields

Name 0

The file/folder name (leaf).

Path 1

The full path — a term that contained \ or used path:.

FindMyFiles

FindMyFiles.Highlighting

HighlightRange Struct

A half-open run of UTF-16 code units to emphasize, in the coordinate space of the string handed to Ranges(string, HighlightField).

public readonly record struct HighlightRange : System.IEquatable<FindMyFiles.Highlighting.HighlightRange>

Implements System.IEquatable<HighlightRange>

Constructors

HighlightRange(int, int) Constructor

A half-open run of UTF-16 code units to emphasize, in the coordinate space of the string handed to Ranges(string, HighlightField).

public HighlightRange(int Start, int Length);

Parameters

Start System.Int32

Zero-based UTF-16 index of the first highlighted unit.

Length System.Int32

Number of UTF-16 units highlighted (always ≥ 1).

Properties

HighlightRange.Length Property

Number of UTF-16 units highlighted (always ≥ 1).

public int Length { get; init; }

Property Value

System.Int32

HighlightRange.Start Property

Zero-based UTF-16 index of the first highlighted unit.

public int Start { get; init; }

Property Value

System.Int32

FindMyFiles

FindMyFiles.Highlighting

HighlightSegment Struct

One piece of a string for highlighted rendering.

public readonly record struct HighlightSegment : System.IEquatable<FindMyFiles.Highlighting.HighlightSegment>

Implements System.IEquatable<HighlightSegment>

Constructors

HighlightSegment(string, bool) Constructor

One piece of a string for highlighted rendering.

public HighlightSegment(string Text, bool Highlighted);

Parameters

Text System.String

The piece's text.

Highlighted System.Boolean

True when this piece should be emphasized.

Properties

HighlightSegment.Highlighted Property

True when this piece should be emphasized.

public bool Highlighted { get; init; }

Property Value

System.Boolean

HighlightSegment.Text Property

The piece's text.

public string Text { get; init; }

Property Value

System.String

FindMyFiles

FindMyFiles.Highlighting

HighlightSegmenter Class

Splits a string into consecutive highlighted/plain segments from a set of merged ranges — the pure, unit-tested core of the highlight renderer, kept free of WinUI so it runs headless. Ranges are clamped to the string, so a stale or out-of-bounds range can never throw.

public static class HighlightSegmenter

Inheritance System.Object → HighlightSegmenter

Methods

HighlightSegmenter.Split(string, IReadOnlyList<HighlightRange>) Method

Cut text at the boundaries of ranges (assumed sorted and non-overlapping — as produced by Ranges(string, HighlightField)), tagging each piece as highlighted or not. Empty ranges yield the whole string as one plain segment; zero-length or out-of-range entries are skipped/clamped.

public static System.Collections.Generic.List<FindMyFiles.Highlighting.HighlightSegment> Split(string text, System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange> ranges);

Parameters

text System.String

The full string being rendered.

ranges System.Collections.Generic.IReadOnlyList<HighlightRange>

The spans to emphasize.

Returns

System.Collections.Generic.List<HighlightSegment>
The string split into consecutive plain and highlighted pieces, in order.

FindMyFiles

FindMyFiles.Highlighting

HighlightText Class

Attached behavior that renders SourceProperty into a TextBlock's Inlines, emphasizing the spans named by RangesProperty with bold + accent foreground. Lets the result list's name/path cells show match highlights without giving up their TextBlock styles, x:Phase, or virtualization: the same cell instance is reused across rows, and FindMyFiles.Highlighting.HighlightText.Rebuild(Microsoft.UI.Xaml.Controls.TextBlock,System.String,System.Collections.Generic.IReadOnlyList{FindMyFiles.Highlighting.HighlightRange}) clears and refills it on every change so a reused container never shows the previous row's text.

public static class HighlightText

Inheritance System.Object → HighlightText

Fields

HighlightText.RangesProperty Field

Ranges of SourceProperty to emphasize (UTF-16 coordinates, sorted and merged by the highlighter).

public static readonly DependencyProperty RangesProperty;

Field Value

Microsoft.UI.Xaml.DependencyProperty

HighlightText.SourceProperty Field

The full text to display (set with RangesProperty; either change rebuilds the inlines).

public static readonly DependencyProperty SourceProperty;

Field Value

Microsoft.UI.Xaml.DependencyProperty

Methods

HighlightText.GetRanges(DependencyObject) Method

Get the highlight ranges from element.

public static System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange>? GetRanges(Microsoft.UI.Xaml.DependencyObject element);

Parameters

element Microsoft.UI.Xaml.DependencyObject

The element to read the highlight ranges from.

Returns

System.Collections.Generic.IReadOnlyList<HighlightRange>
The highlight ranges, or null if none are set.

HighlightText.GetSource(DependencyObject) Method

Get the display text from element.

public static string? GetSource(Microsoft.UI.Xaml.DependencyObject element);

Parameters

element Microsoft.UI.Xaml.DependencyObject

The element to read the display text from.

Returns

System.String
The display text, or null if none is set.

HighlightText.SetRanges(DependencyObject, IReadOnlyList<HighlightRange>) Method

Set the highlight ranges on element.

public static void SetRanges(Microsoft.UI.Xaml.DependencyObject element, System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange>? value);

Parameters

element Microsoft.UI.Xaml.DependencyObject

The element to set the highlight ranges on.

value System.Collections.Generic.IReadOnlyList<HighlightRange>

The ranges to emphasize.

HighlightText.SetSource(DependencyObject, string) Method

Set the display text on element.

public static void SetSource(Microsoft.UI.Xaml.DependencyObject element, string? value);

Parameters

element Microsoft.UI.Xaml.DependencyObject

The element to set the display text on.

value System.String

The text to display.

FindMyFiles

FindMyFiles.Highlighting

IHighlighter Interface

A compiled query that can emphasize the slices of a displayed string it matched. Implemented by the substring/wildcard CompiledHighlighter and the whole-query RegexHighlighter; the results list and rows depend only on this seam.

public interface IHighlighter

Derived
CompiledHighlighter
RegexHighlighter

Properties

IHighlighter.IsEmpty Property

True when nothing will ever be highlighted — the caller can skip per-row work entirely.

bool IsEmpty { get; }

Property Value

System.Boolean

Methods

IHighlighter.Ranges(string, HighlightField) Method

The ranges of text to emphasize for field (UTF-16 units of text), sorted and merged; empty when nothing matches.

System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange> Ranges(string text, FindMyFiles.Highlighting.HighlightField field);

Parameters

text System.String

The displayed string (a name, or a full path).

field HighlightField

Which displayed string the ranges target.

Returns

System.Collections.Generic.IReadOnlyList<HighlightRange>
The sorted, merged highlight ranges; empty when nothing matches.

FindMyFiles

FindMyFiles.Highlighting

MatchHighlighter Class

Compiles query text into a CompiledHighlighter. Mirrors the engine tokenizer/compiler (engine/crates/fmf-core/src/query/ast.rs and compile.rs) for the subset that can be highlighted exactly, and drops the rest (see CompiledHighlighter).

public static class MatchHighlighter

Inheritance System.Object → MatchHighlighter

Methods

MatchHighlighter.Compile(string) Method

Compile query (the user's raw text, before any focused-mode rewrite) into a highlighter. Case handling is smart-case, matching the product default (MainViewModel uses FmfCase.Smart). An empty/whitespace or filter-only query yields Empty.

public static FindMyFiles.Highlighting.CompiledHighlighter Compile(string query);

Parameters

query System.String

Raw user query text.

Returns

CompiledHighlighter
A highlighter for the query, or Empty when nothing is highlightable.

MatchHighlighter.CompileRegex(string, RegexScope) Method

Compile a whole-query regex highlighter (regex mode, ADR-0023): the entire query is one pattern, emphasized in the name or full path per scope. Smart-case (insensitive unless the pattern carries an uppercase-ish scalar), matching the product default. A pattern .NET cannot compile yields Empty — the engine reports the syntax error; the highlighter just stays dark rather than guess.

public static FindMyFiles.Highlighting.IHighlighter CompileRegex(string query, FindMyFiles.Engine.RegexScope scope);

Parameters

query System.String

Raw user query text, treated as one regex pattern.

scope RegexScope

Which haystack the pattern runs against (name or full path).

Returns

IHighlighter
A regex highlighter, or Empty when the pattern cannot compile.

FindMyFiles

FindMyFiles.Highlighting

RegexHighlighter Class

Highlights a whole-query regex (regex mode) by re-matching the displayed string. Emphasizes the name field for a name-scope pattern and the path field for a path-scope one — the same field the engine matched, so ResultRow's parent/name split applies unchanged. A match-timeout (or any mismatch with the engine's rust regex) simply yields no ranges: a row the engine returned is never hidden, only its emphasis is skipped.

public sealed class RegexHighlighter : FindMyFiles.Highlighting.IHighlighter

Inheritance System.Object → RegexHighlighter

Implements IHighlighter

Constructors

RegexHighlighter(Regex, RegexScope) Constructor

Highlights a whole-query regex (regex mode) by re-matching the displayed string. Emphasizes the name field for a name-scope pattern and the path field for a path-scope one — the same field the engine matched, so ResultRow's parent/name split applies unchanged. A match-timeout (or any mismatch with the engine's rust regex) simply yields no ranges: a row the engine returned is never hidden, only its emphasis is skipped.

public RegexHighlighter(System.Text.RegularExpressions.Regex re, FindMyFiles.Engine.RegexScope scope);

Parameters

re System.Text.RegularExpressions.Regex

scope RegexScope

Properties

RegexHighlighter.IsEmpty Property

True when nothing will ever be highlighted — the caller can skip per-row work entirely.

public bool IsEmpty { get; }

Implements IsEmpty

Property Value

System.Boolean

Methods

RegexHighlighter.Ranges(string, HighlightField) Method

The ranges of text to emphasize for field (UTF-16 units of text), sorted and merged; empty when nothing matches.

public System.Collections.Generic.IReadOnlyList<FindMyFiles.Highlighting.HighlightRange> Ranges(string text, FindMyFiles.Highlighting.HighlightField field);

Parameters

text System.String

The displayed string (a name, or a full path).

field HighlightField

Which displayed string the ranges target.

Implements Ranges(string, HighlightField)

Returns

System.Collections.Generic.IReadOnlyList<HighlightRange>
The sorted, merged highlight ranges; empty when nothing matches.

FindMyFiles

FindMyFiles.Highlighting Namespace

Classes
CompiledHighlighterA query compiled into the positive text needles worth highlighting. Pure (no WinUI), so it is unit-testable and reusable across rows. Built once per query by Compile(string) and queried per displayed string by Ranges(string, HighlightField). Highlighting deliberately mirrors only the *simple, certain* slice of the engine's match semantics (fmf-core query/): plain substrings, anchored lit*/*lit/*lit* wildcards, and smart-case folding (engine/crates/fmf-core/src/wtf8.rs). Anything the UI cannot reproduce exactly — user regex, general wildcards, negation, path wildcards — is left un-highlighted rather than guessed at: a row the engine returned is never hidden, only its emphasis is skipped (don't crash / don't go silent). This guarantees the UI never lights up a position the engine did not actually match.
HighlightSegmenterSplits a string into consecutive highlighted/plain segments from a set of merged ranges — the pure, unit-tested core of the highlight renderer, kept free of WinUI so it runs headless. Ranges are clamped to the string, so a stale or out-of-bounds range can never throw.
HighlightTextAttached behavior that renders SourceProperty into a TextBlock's Inlines, emphasizing the spans named by RangesProperty with bold + accent foreground. Lets the result list's name/path cells show match highlights without giving up their TextBlock styles, x:Phase, or virtualization: the same cell instance is reused across rows, and FindMyFiles.Highlighting.HighlightText.Rebuild(Microsoft.UI.Xaml.Controls.TextBlock,System.String,System.Collections.Generic.IReadOnlyList{FindMyFiles.Highlighting.HighlightRange}) clears and refills it on every change so a reused container never shows the previous row's text.
MatchHighlighterCompiles query text into a CompiledHighlighter. Mirrors the engine tokenizer/compiler (engine/crates/fmf-core/src/query/ast.rs and compile.rs) for the subset that can be highlighted exactly, and drops the rest (see CompiledHighlighter).
RegexHighlighterHighlights a whole-query regex (regex mode) by re-matching the displayed string. Emphasizes the name field for a name-scope pattern and the path field for a path-scope one — the same field the engine matched, so ResultRow's parent/name split applies unchanged. A match-timeout (or any mismatch with the engine's rust regex) simply yields no ranges: a row the engine returned is never hidden, only its emphasis is skipped.
Structs
HighlightRangeA half-open run of UTF-16 code units to emphasize, in the coordinate space of the string handed to Ranges(string, HighlightField).
HighlightSegmentOne piece of a string for highlighted rendering.
Interfaces
IHighlighterA compiled query that can emphasize the slices of a displayed string it matched. Implemented by the substring/wildcard CompiledHighlighter and the whole-query RegexHighlighter; the results list and rows depend only on this seam.
Enums
HighlightFieldWhich displayed string a highlight term is matched against — the file name leaf, or the full path (parent + name).

FindMyFiles

FindMyFiles

MainPage Class

Wiring only: builds the ViewModel graph and connects view events to it. Imperative ListView work (viewport/selection restore, row actions) lives in ResultsViewportManager; the F12 panel chrome in PerfPanel; converters in UiConverters.

public sealed class MainPage : Microsoft.UI.Xaml.Controls.Page, Microsoft.UI.Xaml.Markup.IComponentConnector

Inheritance System.ObjectMicrosoft.UI.Xaml.DependencyObjectMicrosoft.UI.Xaml.UIElementMicrosoft.UI.Xaml.FrameworkElementMicrosoft.UI.Xaml.Controls.ControlMicrosoft.UI.Xaml.Controls.UserControlMicrosoft.UI.Xaml.Controls.Page → MainPage

Implements Microsoft.UI.Xaml.Markup.IComponentConnector

Constructors

MainPage() Constructor

Builds the ViewModel graph and wires view events (IME composition, drag & drop, keyboard, sort headers) to the ViewModel and ResultsViewportManager. Localized tooltips/automation names are set in code here, and the language radio reflects persisted settings. Finally initializes the empty/results visual state and starts `StartAsync`.

public MainPage();

Properties

MainPage.ViewModel Property

Root of the page's ViewModel graph. The sole `x:Bind` source; it ties together the search, results, notification and diagnostics-panel sub-ViewModels.

public FindMyFiles.ViewModels.MainViewModel ViewModel { get; }

Property Value

MainViewModel

Methods

MainPage.Connect(int, object) Method

Connect()

public void Connect(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements Connect(int, object)

MainPage.GetBindingConnector(int, object) Method

GetBindingConnector(int connectionId, object target)

public Microsoft.UI.Xaml.Markup.IComponentConnector GetBindingConnector(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements GetBindingConnector(int, object)

Returns

Microsoft.UI.Xaml.Markup.IComponentConnector

MainPage.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

FindMyFiles

FindMyFiles

MainWindow Class

The application window: hosts the root Frame; app UI lives in MainPage.

public sealed class MainWindow : Microsoft.UI.Xaml.Window, Microsoft.UI.Xaml.Markup.IComponentConnector

Inheritance System.ObjectMicrosoft.UI.Xaml.Window → MainWindow

Implements Microsoft.UI.Xaml.Markup.IComponentConnector

Constructors

MainWindow() Constructor

Extends the title bar into the content, sets the window icon, and navigates the root Frame to MainPage.

public MainWindow();

Methods

MainWindow.Connect(int, object) Method

Connect()

public void Connect(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements Connect(int, object)

MainWindow.GetBindingConnector(int, object) Method

GetBindingConnector(int connectionId, object target)

public Microsoft.UI.Xaml.Markup.IComponentConnector GetBindingConnector(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements GetBindingConnector(int, object)

Returns

Microsoft.UI.Xaml.Markup.IComponentConnector

MainWindow.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

FindMyFiles

FindMyFiles

Program Class

Program class

public static class Program

Inheritance System.Object → Program

FindMyFiles

FindMyFiles.Services

AppNotification Class

One entry in the InfoBar stack. Immutable, identity-stamped, and carries an optional action button so a notification can offer its own remedy (e.g. "restart the app" after a service install).

public sealed record AppNotification : System.IEquatable<FindMyFiles.Services.AppNotification>

Inheritance System.Object → AppNotification

Implements System.IEquatable<AppNotification>

Constructors

AppNotification(NotifySeverity, string, string, string, Action) Constructor

One entry in the InfoBar stack. Immutable, identity-stamped, and carries an optional action button so a notification can offer its own remedy (e.g. "restart the app" after a service install).

public AppNotification(FindMyFiles.Services.NotifySeverity Severity, string Message, string? Detail=null, string? ActionLabel=null, System.Action? Action=null);

Parameters

Severity NotifySeverity

Visual style + log level + auto-dismiss policy.

Message System.String

The headline shown in the InfoBar.

Detail System.String

Optional secondary line (often an exception message).

ActionLabel System.String

Caption for the action button; null hides it.

Action System.Action

Invoked when the action button is pressed; see Invoke().

Properties

AppNotification.Action Property

Invoked when the action button is pressed; see Invoke().

public System.Action? Action { get; init; }

Property Value

System.Action

AppNotification.ActionLabel Property

Caption for the action button; null hides it.

public string? ActionLabel { get; init; }

Property Value

System.String

AppNotification.Detail Property

Optional secondary line (often an exception message).

public string? Detail { get; init; }

Property Value

System.String

AppNotification.Id Property

Stable per-notification identity (a hex GUID) so the InfoBar list can track and remove this exact entry.

public string Id { get; }

Property Value

System.String

AppNotification.Message Property

The headline shown in the InfoBar.

public string Message { get; init; }

Property Value

System.String

AppNotification.Severity Property

Visual style + log level + auto-dismiss policy.

public FindMyFiles.Services.NotifySeverity Severity { get; init; }

Property Value

NotifySeverity

Methods

AppNotification.Invoke() Method

x:Bind target for the InfoBar action button (no-op when the notification carries no action).

public void Invoke();

FindMyFiles

FindMyFiles.Services

AppPaths Class

Resolves where the app keeps its state — <b>portable by default</b> (ADR-0024). On first access it picks one data root, once, in this order:

  1. --data-dir=<path> when given (tests, scratch, power users);
  2. <exe>\data when it can be created and written — the default, so a copied/unzipped build keeps everything in its own folder and touches neither the user profile nor the registry ("just drop it / just delete it");
  3. the per-user profile (%APPDATA% / %LOCALAPPDATA%) only when the app folder is read-only (e.g. installed under Program Files).

The machine-scope service index (%ProgramData%) and the admin in-proc index are intentionally <i>not</i> redirected — that path is an install by nature, the opposite of portable.

Resolution is silent: it must not call FileLog, because FileLog's directory comes from here (a cycle otherwise).

public static class AppPaths

Inheritance System.Object → AppPaths

Properties

AppPaths.IsPortable Property

True when state lives next to the exe (or --data-dir), not in the user profile.

public static bool IsPortable { get; }

Property Value

System.Boolean

AppPaths.LogDir Property

App + scope-engine log directory — portable <data>\logs, else %APPDATA%\find-my-files\logs.

public static string LogDir { get; }

Property Value

System.String

AppPaths.PortableRoot Property

The portable data root, or null when falling back to the per-user profile. Surfaced for the setup screen / diagnostics ("running portable from …").

public static string? PortableRoot { get; }

Property Value

System.String

AppPaths.ScopeIndexDir Property

Scope-mode (ADR-0024) index directory — portable <data>\index, else %LOCALAPPDATA%\find-my-files\index.

public static string ScopeIndexDir { get; }

Property Value

System.String

AppPaths.SettingsFile Property

User-scope settings file — portable <data>\settings.json, else %APPDATA%\find-my-files\settings.json.

public static string SettingsFile { get; }

Property Value

System.String

FindMyFiles

FindMyFiles.Services

AppSettings Class

User-scope settings at %APPDATA%\find-my-files\settings.json — UI-owned, deliberately separate from the machine-scope service.json the service owns. A corrupt file degrades to defaults: warn, quarantine as .bad, and the next save starts clean.

public sealed class AppSettings

Inheritance System.Object → AppSettings

Properties

AppSettings.Engine Property

Engine transport: "auto" (pipe probe → FFI fallback), "pipe", or "inproc". CLI flags override this.

public string Engine { get; set; }

Property Value

System.String

AppSettings.FocusedExcludePaths Property

Noise directories excluded in focused mode, each appended as a quoted !path:"…" term. Plain substring match against the full path (engine semantics) — no wildcards needed.

public string[] FocusedExcludePaths { get; set; }

Property Value

System.String[]

AppSettings.FocusedExtensions Property

Extension whitelist applied in focused mode as a single OR-semantics ext:a;b;… term: documents, images, audio, video, archives and launchables — what a person actually goes looking for.

public string[] FocusedExtensions { get; set; }

Property Value

System.String[]

AppSettings.FocusedSearch Property

Focused-search mode (ADR-0019): rewrite queries in the UI with the two lists below before they reach the engine. On by default — the casual user wants a handful of hits, not 10,000; the toolbar toggle flips it per session and persists here.

public bool FocusedSearch { get; set; }

Property Value

System.Boolean

AppSettings.Language Property

UI language: "auto" (follow the OS), "ja", "en", or "zh-Hans". Applied via PrimaryLanguageOverride in the App ctor; the gear menu's switcher persists it here and relaunches to take effect.

public string Language { get; set; }

Property Value

System.String

AppSettings.RegexMode Property

Regex mode (ADR-0023): treat the whole query as one regex. Off by default; the gear-menu toggle flips it and persists here.

public bool RegexMode { get; set; }

Property Value

System.Boolean

AppSettings.RegexScope Property

Which haystack the whole-query regex matches — "name" or "path". Kept independent of RegexMode so the choice survives toggling regex off and back on. Unknown values fall back to "name".

public string RegexScope { get; set; }

Property Value

System.String

AppSettings.ScopeExcludes Property

Absolute subfolder paths pruned from the scope walk (ADR-0025). Each must lie under one of ScopeRoots; the walk skips the matching subtree so it is never indexed. Empty = index everything under the roots.

public string[] ScopeExcludes { get; set; }

Property Value

System.String[]

AppSettings.ScopeRoots Property

Absolute paths of the root folders to index in non-elevated scope mode (ADR-0024). Empty = unconfigured, and the setup screen mainly pushes the admin path (all drives, fastest). One or more entries resolve to EngineChoice.WalkInProc on the next launch, so folder-walk search works on a corporate PC where neither the service nor admin rights are available.

public string[] ScopeRoots { get; set; }

Property Value

System.String[]

AppSettings.SettingsPath Property

Absolute path to the user-scope settings file. Portable by default (<exe>\data\settings.json); falls back to %APPDATA%\find-my-files\settings.json when the app folder is read-only. See AppPaths.

public static string SettingsPath { get; }

Property Value

System.String

Methods

AppSettings.Load() Method

Load settings from SettingsPath, falling back to defaults (and quarantining the file) if it is missing or corrupt.

public static FindMyFiles.Services.AppSettings Load();

Returns

AppSettings
The loaded settings, or a fresh default instance.

AppSettings.Save() Method

Persist the current settings to SettingsPath (snake_case JSON, indented). Best-effort: a write failure is logged, not thrown.

public void Save();

FindMyFiles

FindMyFiles.Services

DispatcherQueueDispatcher Class

Production IDispatcher: a thin wrapper over the UI thread's cached Microsoft.UI.Dispatching.DispatcherQueue (CLAUDE.md UI rules — cache on the UI thread, TryEnqueue from background threads).

public sealed class DispatcherQueueDispatcher : FindMyFiles.Services.IDispatcher

Inheritance System.Object → DispatcherQueueDispatcher

Implements IDispatcher

Constructors

DispatcherQueueDispatcher(DispatcherQueue) Constructor

Production IDispatcher: a thin wrapper over the UI thread's cached Microsoft.UI.Dispatching.DispatcherQueue (CLAUDE.md UI rules — cache on the UI thread, TryEnqueue from background threads).

public DispatcherQueueDispatcher(Microsoft.UI.Dispatching.DispatcherQueue queue);

Parameters

queue Microsoft.UI.Dispatching.DispatcherQueue

The UI thread's Microsoft.UI.Dispatching.DispatcherQueue, captured once on that thread at construction.

Properties

DispatcherQueueDispatcher.HasThreadAccess Property

True when the caller is already on the UI thread.

public bool HasThreadAccess { get; }

Implements HasThreadAccess

Property Value

System.Boolean

Methods

DispatcherQueueDispatcher.CreateOneShotTimer(TimeSpan, Action) Method

One-shot timer: fires tick once per Start(). Start() while pending restarts the interval (debounce semantics).

public FindMyFiles.Services.IDispatcherTimer CreateOneShotTimer(System.TimeSpan interval, System.Action tick);

Parameters

interval System.TimeSpan

Delay between Start() and the tick.

tick System.Action

Callback fired on the UI thread when the interval elapses.

Implements CreateOneShotTimer(TimeSpan, Action)

Returns

IDispatcherTimer
A restartable timer handle bound to this dispatcher.

DispatcherQueueDispatcher.TryEnqueue(Action) Method

Queue action to run on the UI thread. Returns false if the queue is shutting down and the work was not accepted.

public bool TryEnqueue(System.Action action);

Parameters

action System.Action

Work to marshal onto the UI thread.

Implements TryEnqueue(Action)

Returns

System.Boolean
True if enqueued; false if the dispatcher is no longer accepting work.

FindMyFiles

FindMyFiles.Services

EngineServiceState Enum

SCM registration/run state of the fmf-engine service, as seen by the unelevated UI via QueryState() — drives whether the app offers to install, start, or nothing at all.

public enum EngineServiceState

Fields

NotInstalled 0

No FindMyFiles.Engine.EngineContract.ServiceName entry in the SCM (or the SCM is unreachable) — the UI offers a one-time install.

Stopped 1

Registered but not running — the UI offers to start it.

Running 2

Running (or on its way up: START/CONTINUE_PENDING) — no offer needed; the pipe transport can connect.

FindMyFiles

FindMyFiles.Services

ExceptionPolicy Class

The single home for the process-wide exception funnels (don't crash / don't hang / don't go silent). Three sources, three suppression rules:

1. XAML Microsoft.UI.Xaml.Application.UnhandledException — suppressed (Handled = true) and surfaced as an error InfoBar for the first FindMyFiles.Services.ExceptionPolicy.XamlStormBudget occurrences. Beyond that the process is in an exception storm: a crash marker is written and the exception is left unhandled so the process dies honestly. 2. System.AppDomain.UnhandledException — never suppressible by contract: log + crash marker, then the runtime terminates. 3. System.Threading.Tasks.TaskScheduler.UnobservedTaskException — always observed (the task is already dead; tearing the process down helps nobody) and surfaced as an error InfoBar.

Log routing: every path writes to FileLog (%APPDATA%\find-my-files\logs\app.log); user-visible surfaces go through Notifier, which mirrors to the same log. Crash markers are written by the fatal paths (1-storm and 2) and read back + cleared by ReportPreviousCrash() on the next launch, so no crash is ever silent.

public sealed class ExceptionPolicy

Inheritance System.Object → ExceptionPolicy

Methods

ExceptionPolicy.Install(Application) Method

Wire all three funnels. Call once, from the App constructor.

public static void Install(Microsoft.UI.Xaml.Application app);

Parameters

app Microsoft.UI.Xaml.Application

The WinUI application whose exception events are hooked.

ExceptionPolicy.ReportPreviousCrash() Method

Surface the previous run's crash marker (if any) as a warning InfoBar; reading clears the marker.

public static void ReportPreviousCrash();

FindMyFiles

FindMyFiles.Services

FileLog Class

Zero-dependency file logger for the app process. Covers everything on the C# side; the log directory is resolved by AppPaths (portable <exe>\data\logs by default, else %APPDATA%\find-my-files\logs) — the same dir the scope engine logs into. Thread-safe, single rotation generation.

public static class FileLog

Inheritance System.Object → FileLog

Properties

FileLog.CrashMarkerPath Property

Absolute path to the crash marker dropped on a fatal exit and read back on the next launch (see WriteCrashMarker(string) / TakeCrashMarker()).

public static string CrashMarkerPath { get; }

Property Value

System.String

FileLog.LogPath Property

Absolute path to the active log file (…\logs\app.log under the resolved data root) — surfaced for the diagnostics "open log folder" affordance.

public static string LogPath { get; }

Property Value

System.String

Methods

FileLog.Error(string, string, Exception) Method

Log an error under area, optionally appending the full ex for the stack trace.

public static void Error(string area, string message, System.Exception? ex=null);

Parameters

area System.String

Subsystem tag.

message System.String

The message text.

ex System.Exception

Optional exception to append verbatim.

FileLog.Info(string, string) Method

Log an informational line under area (the subsystem tag shown in brackets).

public static void Info(string area, string message);

Parameters

area System.String

Subsystem tag, e.g. "notify" or "settings".

message System.String

The message text.

FileLog.Tail(int) Method

Last `lines` of the log — for the diagnostics clipboard dump.

public static string Tail(int lines);

Parameters

lines System.Int32

How many trailing lines to return.

Returns

System.String
The joined tail, or a placeholder if missing/unreadable.

FileLog.TakeCrashMarker() Method

Returns and clears the crash marker from the previous run.

public static string? TakeCrashMarker();

Returns

System.String
The marker contents, or null if absent or unreadable.

FileLog.Warn(string, string, Exception) Method

Log a warning under area, optionally appending the full ex for the stack trace.

public static void Warn(string area, string message, System.Exception? ex=null);

Parameters

area System.String

Subsystem tag.

message System.String

The message text.

ex System.Exception

Optional exception to append verbatim.

FileLog.WriteCrashMarker(string) Method

Drop a crash marker (timestamp + detail) so the next launch can detect an abnormal exit and offer to report it. Best-effort; failures are swallowed.

public static void WriteCrashMarker(string detail);

Parameters

detail System.String

Crash context to record alongside the timestamp.

FindMyFiles

FindMyFiles.Services

IDispatcher Interface

UI-thread dispatch boundary. The single seam that lets the search pipeline and the virtualized list run under unit tests without a real DispatcherQueue — two implementations by necessity: DispatcherQueueDispatcher (production) and a manual fake in the test project.

public interface IDispatcher

Derived
DispatcherQueueDispatcher

Properties

IDispatcher.HasThreadAccess Property

True when the caller is already on the UI thread.

bool HasThreadAccess { get; }

Property Value

System.Boolean

Methods

IDispatcher.CreateOneShotTimer(TimeSpan, Action) Method

One-shot timer: fires tick once per Start(). Start() while pending restarts the interval (debounce semantics).

FindMyFiles.Services.IDispatcherTimer CreateOneShotTimer(System.TimeSpan interval, System.Action tick);

Parameters

interval System.TimeSpan

Delay between Start() and the tick.

tick System.Action

Callback fired on the UI thread when the interval elapses.

Returns

IDispatcherTimer
A restartable timer handle bound to this dispatcher.

IDispatcher.TryEnqueue(Action) Method

Queue action to run on the UI thread. Returns false if the queue is shutting down and the work was not accepted.

bool TryEnqueue(System.Action action);

Parameters

action System.Action

Work to marshal onto the UI thread.

Returns

System.Boolean
True if enqueued; false if the dispatcher is no longer accepting work.

FindMyFiles

FindMyFiles.Services

IDispatcherTimer Interface

The one-shot timer handle returned by CreateOneShotTimer(TimeSpan, Action) — fires on the UI thread and is restartable for debounce.

public interface IDispatcherTimer

Methods

IDispatcherTimer.Start() Method

Arm the timer. Calling while a tick is still pending restarts the interval (debounce semantics).

void Start();

IDispatcherTimer.Stop() Method

Cancel a pending tick, if any. Idempotent.

void Stop();

FindMyFiles

FindMyFiles.Services

Loc Class

Localized-string facade over the Windows App SDK ResourceLoader (PRI built from Strings/<lang>/Resources.resw). Code keys are flat identifiers (Area_Thing, e.g. Status_Preparing); XAML strings come from x:Uid instead. The Override seam lets unit tests resolve keys without a PRI in the test host.

public static class Loc

Inheritance System.Object → Loc

Properties

Loc.Override Property

Test seam: when set, resolves keys instead of the ResourceLoader.

public static System.Func<string,string>? Override { get; set; }

Property Value

System.Func<System.String,System.String>

Methods

Loc.Get(string) Method

Resolve a key to the current UI language. A missing key falls back to the key itself so the gap is visible, never an empty UI.

public static string Get(string key);

Parameters

key System.String

Flat resource identifier (e.g. Status_Preparing).

Returns

System.String
The localized string, or the key itself when unresolved.

Loc.Get(string, object[]) Method

Resolve a key whose value is a composite format string (placeholders {0}, {1}, …) and fill it.

public static string Get(string key, params object[] args);

Parameters

key System.String

Flat resource identifier whose value is a format string.

args System.Object[]

Values substituted into the {0}, {1}, … placeholders.

Returns

System.String
The localized string with the arguments formatted in.

FindMyFiles

FindMyFiles.Services

Notifier Class

Process-wide notification funnel. Anything (global handlers, background tasks, the engine callback) can post from any thread; the ViewModel subscribes and marshals to the UI InfoBar stack. Posts are also mirrored to the file log so nothing the user saw is missing from a bug report.

public static class Notifier

Inheritance System.Object → Notifier

Methods

Notifier.Attach(Action<AppNotification>) Method

Drain posts that arrived before the UI was ready.

public static void Attach(System.Action<FindMyFiles.Services.AppNotification> handler);

Parameters

handler System.Action<AppNotification>

Subscriber invoked for each notification, including the replayed pre-subscription backlog.

Notifier.Post(NotifySeverity, string, string, string, Action) Method

Post a notification from any thread. Mirrors it to the file log at the level matching severity (so nothing the user saw is missing from a bug report), then hands it to the subscriber — or queues it until one attaches.

public static void Post(FindMyFiles.Services.NotifySeverity severity, string message, string? detail=null, string? actionLabel=null, System.Action? action=null);

Parameters

severity NotifySeverity

Style/level and auto-dismiss policy.

message System.String

Headline text.

detail System.String

Optional secondary line (e.g. exception message).

actionLabel System.String

Caption for an optional action button.

action System.Action

Callback for the action button, if any.

Events

Notifier.Posted Event

Raised on the posting thread for each notification once a subscriber exists. Subscribe via Attach(Action<AppNotification>) (which also replays the pre-subscription backlog) rather than touching this directly; the ViewModel handler marshals to the UI thread.

public static event Action<AppNotification>? Posted;

Event Type

System.Action<AppNotification>

FindMyFiles

FindMyFiles.Services

NotifySeverity Enum

Severity of an AppNotification — selects the InfoBar style and the file-log level, and decides whether the entry auto-dismisses (Info) or stays until the user closes it.

public enum NotifySeverity

Fields

Info 0

Transient confirmation — logged at INFO; dissolves on its own.

Warning 1

A degraded path the user should know about — logged at WARN; stays until dismissed.

Error 2

A failure — logged at ERROR; stays until dismissed.

FindMyFiles

FindMyFiles.Services

ScopeFolderPicker Class

Folder picker for scope mode (ADR-0024). Unpackaged WinUI 3 requires a picker to be associated with the app window's HWND before it is shown — it throws otherwise — so this always initializes with WindowHandle.

public static class ScopeFolderPicker

Inheritance System.Object → ScopeFolderPicker

Methods

ScopeFolderPicker.PickAsync() Method

Show the folder picker and return the chosen absolute path (null when the user cancels). Windows.Storage.Pickers.FolderPicker has no multi-select, so the caller invokes this once per folder. Must be called on the UI thread.

public static System.Threading.Tasks.Task<string?> PickAsync();

Returns

System.Threading.Tasks.Task<System.String>
The selected folder path, or null on cancel.

FindMyFiles

FindMyFiles.Services

ScopePaths Class

Pure path helpers for scope mode (ADR-0024/-0025). The engine treats scope roots as independent and would double-walk a nested pair, so the UI normalizes the chosen set; excludes must sit under a root to mean anything. No I/O — unit-tested directly.

public static class ScopePaths

Inheritance System.Object → ScopePaths

Methods

ScopePaths.IsUnderAnyRoot(string, IEnumerable<string>) Method

True when path sits strictly under one of roots — the guard for adding a scope exclude, which must be inside the indexed set to prune anything (ADR-0025). Excluding a whole root (equal path) is rejected: drop the root instead.

public static bool IsUnderAnyRoot(string path, System.Collections.Generic.IEnumerable<string> roots);

Parameters

path System.String

The candidate exclude path.

roots System.Collections.Generic.IEnumerable<System.String>

The selected scope roots.

Returns

System.Boolean
True when the path is a proper descendant of some root.

ScopePaths.Normalize(IEnumerable<string>) Method

Drop any root nested under another selected root (and exact case-insensitive duplicates), so e.g. {C:\A, C:\A\B} collapses to {C:\A}. The surviving roots keep their original strings (no trailing-separator rewriting — C:\ must stay C:\) and their first-seen order.

public static System.Collections.Generic.List<string> Normalize(System.Collections.Generic.IEnumerable<string> roots);

Parameters

roots System.Collections.Generic.IEnumerable<System.String>

The chosen roots, in selection order.

Returns

System.Collections.Generic.List<System.String>
The covering roots with nested/duplicate entries removed.

FindMyFiles

FindMyFiles.Services

ServiceActionOutcome Enum

Verdict of one elevated lifecycle action (RunElevated(string, string)). Output is unreadable under ShellExecute, so the exit code is the only signal; a declined UAC prompt is distinguished from a genuine failure so the UI can say so.

public enum ServiceActionOutcome

Fields

Ok 0

The elevated action exited 0 — the verb succeeded.

Failed 1

The action ran but exited non-zero (or could not be launched/timed out) — a genuine failure to surface to the user.

Cancelled 2

The user dismissed the UAC prompt (ERROR_CANCELLED 1223) — not a failure, so the UI says "cancelled" rather than "error".

FindMyFiles

FindMyFiles.Services

ServiceActionResult Struct

Result of one RunElevated(string, string) call: the classified Outcome plus the raw process ExitCode (-1 when the process never produced one).

public readonly record struct ServiceActionResult : System.IEquatable<FindMyFiles.Services.ServiceActionResult>

Implements System.IEquatable<ServiceActionResult>

Constructors

ServiceActionResult(ServiceActionOutcome, int) Constructor

Result of one RunElevated(string, string) call: the classified Outcome plus the raw process ExitCode (-1 when the process never produced one).

public ServiceActionResult(FindMyFiles.Services.ServiceActionOutcome Outcome, int ExitCode);

Parameters

Outcome ServiceActionOutcome

Success / failure / user-cancelled classification.

ExitCode System.Int32

fmf-service.exe exit code, or -1 if it could not be launched, timed out, or the UAC prompt was declined.

Properties

ServiceActionResult.ExitCode Property

fmf-service.exe exit code, or -1 if it could not be launched, timed out, or the UAC prompt was declined.

public int ExitCode { get; init; }

Property Value

System.Int32

ServiceActionResult.Outcome Property

Success / failure / user-cancelled classification.

public FindMyFiles.Services.ServiceActionOutcome Outcome { get; init; }

Property Value

ServiceActionOutcome

FindMyFiles

FindMyFiles.Services

ServiceProvisioner Class

The shared "make file search usable" steps, behind both the setup screen's one-click button and the management dialog's register action: register the fmf-engine service elevated, then wait for its pipe to start serving and relaunch so this (unelevated, empty-fake) instance comes back connected. The engine transport is chosen once at startup, so a relaunch is how a freshly registered service takes effect.

Instance-based so the elevated setup, the pipe probe, the relaunch and the inter-probe delay are injectable boundaries (ADR-0022) — production code uses Real, which wires the real statics; tests drive fakes.

public sealed class ServiceProvisioner

Inheritance System.Object → ServiceProvisioner

Properties

ServiceProvisioner.Real Property

The production provisioner: the real elevated setup, the real pipe probe, Relaunch(), and System.Threading.Tasks.Task.Delay(System.TimeSpan). Callers default to this.

public static FindMyFiles.Services.ServiceProvisioner Real { get; }

Property Value

ServiceProvisioner

Methods

ServiceProvisioner.RegisterAsync() Method

install (idempotent) + restart in one elevated step (the fmf-service `setup` verb), forwarding the daily user's SID so OTS elevation doesn't lock them out (docs/SECURITY.md threat 1). Blocking work runs off the UI thread.

public System.Threading.Tasks.Task<FindMyFiles.Services.ServiceActionOutcome> RegisterAsync();

Returns

System.Threading.Tasks.Task<ServiceActionOutcome>
The outcome of the elevated setup step (success, declined, or failed).

ServiceProvisioner.WaitForServiceThenRelaunchAsync() Method

After register/start the service's pipe needs a moment to start serving — poll until it answers (≈8s budget), then relaunch this app so the fresh instance connects. Returns false if the pipe never came up in time (the caller then offers a manual retry). On success this process exits and never returns.

public System.Threading.Tasks.Task<bool> WaitForServiceThenRelaunchAsync();

Returns

System.Threading.Tasks.Task<System.Boolean>
True once the pipe answered and a relaunch was triggered; false if it never came up in time.

FindMyFiles

FindMyFiles.Services

ServiceSetup Class

In-app service setup — the GUI half ADR-0016 left to a terminal: detects the fmf-engine SCM registration (read-only, works unelevated) and drives fmf-service.exe install/start so the one-time elevation never needs PowerShell. Mutations are strictly user-initiated (the notification button); install is idempotent on the service side.

public static class ServiceSetup

Inheritance System.Object → ServiceSetup

Methods

ServiceSetup.CurrentUserSid() Method

The current user's SID string, forwarded to `fmf-service install --owner-sid` so OTS elevation (a *different* admin account) does not lock this user out of the pipe (threat 1). Null when unavailable — install then authorizes only the elevated account.

public static string? CurrentUserSid();

Returns

System.String
The current user's SID string, or null when it cannot be read.

ServiceSetup.IsProcessElevated() Method

True when *this* process is already running with an Administrator token — the in-proc engine path needs it, and when set the in-app install/start verbs can skip their own UAC prompt.

public static bool IsProcessElevated();

Returns

System.Boolean
True when the current process token is in the Administrators role.

ServiceSetup.IsValidSid(string) Method

A well-formed SID string (S-1-… of digits and hyphens) — guards the value going onto the fmf-service command line against argument injection before it is interpolated.

public static bool IsValidSid(string? s);

Parameters

s System.String

Candidate SID string to validate.

Returns

System.Boolean
True when the value is a well-formed SID safe to pass on the command line.

ServiceSetup.LocateServiceExe(string) Method

fmf-service.exe next to the app (the dist bundle) or in the dev tree (build\engine\release, walking up from the bin dir).

public static string? LocateServiceExe(string baseDir);

Parameters

baseDir System.String

Directory to start the search from (typically the app's bin dir).

Returns

System.String
Full path to fmf-service.exe, or null when it cannot be found.

ServiceSetup.QueryServiceProcessId() Method

PID of the running fmf-engine service process, or 0 when it is not installed/running. The client-side fake-server check (threat 4) compares this to the pipe's server PID — an unelevated client can read it (unlike a SYSTEM process's token), and a squatter never matches because registering the service needs admin.

public static uint QueryServiceProcessId();

Returns

System.UInt32
The running service's process id, or 0 when not installed/running.

ServiceSetup.QueryState() Method

Read-only SCM query for FindMyFiles.Engine.EngineContract.ServiceName.

public static FindMyFiles.Services.EngineServiceState QueryState();

Returns

EngineServiceState
The service's install/run state for the offer logic.

ServiceSetup.RunElevated(string, string) Method

Run one fmf-service lifecycle verb elevated via a per-action UAC prompt (Verb=runas) — the in-app service manager, where the app itself stays asInvoker. Output can't be captured under ShellExecute, so the verdict is the exit code; a declined prompt (ERROR_CANCELLED 1223) is reported distinctly. args is built from fixed verbs plus SID-validated flags, never raw user text. Blocking — call off the UI thread.

public static FindMyFiles.Services.ServiceActionResult RunElevated(string exe, string args);

Parameters

exe System.String

Path to fmf-service.exe to launch elevated.

args System.String

Service verb plus SID-validated flags to pass on the command line.

Returns

ServiceActionResult
The classified outcome and raw exit code of the elevated action.

FindMyFiles

FindMyFiles.Services

ShellOps Class

Shell-facing operations, centralized so every failure path notifies the user instead of crashing. Targets launch via explorer.exe to shed the process's elevation (CLAUDE.md UI rules).

public static class ShellOps

Inheritance System.Object → ShellOps

Methods

ShellOps.CopyText(string, string) Method

Put text on the clipboard. A failure is logged and surfaced as a warning notification (clipboard access can be transiently denied by other apps).

public static void CopyText(string text, string what);

Parameters

text System.String

The content to copy.

what System.String

Short label for what is being copied, used in the failure log/notification (e.g. "path", "diagnostics").

ShellOps.Open(string) Method

Open a file or folder with its default handler via explorer.exe, shedding the app's elevation. Failures notify the user (with a Win32-specific hint) rather than throwing.

public static void Open(string fullPath);

Parameters

fullPath System.String

Absolute path to open; treated as data, never as a command line (see FindMyFiles.Services.ShellOps.BuildOpenStartInfo(System.String)).

ShellOps.Relaunch() Method

Relaunch this app (unelevated — no runas) and exit, used right after an in-app service registration so the fresh instance picks up the now-running service over the pipe (the engine transport is chosen once, at startup). Strictly user-initiated (the "restart app" button). A failed launch notifies and leaves the current instance running.

public static void Relaunch();

ShellOps.Reveal(string) Method

Reveal a file in Explorer with it selected, via the shell API (SHParseDisplayName + SHOpenFolderAndSelectItems) — never explorer.exe /select,<path>, whose switch parser needs a literal quoted path it does not escape, so a '"' in an MFT-sourced name could inject switches. Runs on a dedicated STA thread with COM initialised: on the WinUI UI thread (an ASTA) SHOpenFolderAndSelectItems returns S_OK but opens nothing. Failures notify off-thread (Notifier/ FileLog are thread-safe; the ViewModel marshals the InfoBar to the UI).

public static void Reveal(string fullPath);

Parameters

fullPath System.String

Absolute path to reveal and select.

FindMyFiles

FindMyFiles.Services

TaskExtensions Class

Extensions for safely launching fire-and-forget System.Threading.Tasks.Tasks (CLAUDE.md rule: never _ = SomeAsync()).

public static class TaskExtensions

Inheritance System.Object → TaskExtensions

Methods

TaskExtensions.Forget(this Task, string) Method

The only sanctioned way to fire-and-forget (CLAUDE.md rule): unexpected exceptions land in the log and the notification bar instead of being silently dropped by an abandoned Task.

public static void Forget(this System.Threading.Tasks.Task task, string area);

Parameters

task System.Threading.Tasks.Task

The task to observe to completion.

area System.String

Subsystem tag for the log/notification if it faults.

FindMyFiles

FindMyFiles.Services Namespace

Classes
AppNotificationOne entry in the InfoBar stack. Immutable, identity-stamped, and carries an optional action button so a notification can offer its own remedy (e.g. "restart the app" after a service install).
AppPathsResolves where the app keeps its state — <b>portable by default</b> (ADR-0024). On first access it picks one data root, once, in this order: ... The machine-scope service index (%ProgramData%) and the admin in-proc index are intentionally <i>not</i> redirected — that path is an install by nature, the opposite of portable. Resolution is silent: it must not call FileLog, because FileLog's directory comes from here (a cycle otherwise).
AppSettingsUser-scope settings at %APPDATA%\find-my-files\settings.json — UI-owned, deliberately separate from the machine-scope service.json the service owns. A corrupt file degrades to defaults: warn, quarantine as .bad, and the next save starts clean.
DispatcherQueueDispatcherProduction IDispatcher: a thin wrapper over the UI thread's cached Microsoft.UI.Dispatching.DispatcherQueue (CLAUDE.md UI rules — cache on the UI thread, TryEnqueue from background threads).
ExceptionPolicyThe single home for the process-wide exception funnels (don't crash / don't hang / don't go silent). Three sources, three suppression rules: 1. XAML Microsoft.UI.Xaml.Application.UnhandledException — suppressed (Handled = true) and surfaced as an error InfoBar for the first FindMyFiles.Services.ExceptionPolicy.XamlStormBudget occurrences. Beyond that the process is in an exception storm: a crash marker is written and the exception is left unhandled so the process dies honestly. 2. System.AppDomain.UnhandledException — never suppressible by contract: log + crash marker, then the runtime terminates. 3. System.Threading.Tasks.TaskScheduler.UnobservedTaskException — always observed (the task is already dead; tearing the process down helps nobody) and surfaced as an error InfoBar. Log routing: every path writes to FileLog (%APPDATA%\find-my-files\logs\app.log); user-visible surfaces go through Notifier, which mirrors to the same log. Crash markers are written by the fatal paths (1-storm and 2) and read back + cleared by ReportPreviousCrash() on the next launch, so no crash is ever silent.
FileLogZero-dependency file logger for the app process. Covers everything on the C# side; the log directory is resolved by AppPaths (portable <exe>\data\logs by default, else %APPDATA%\find-my-files\logs) — the same dir the scope engine logs into. Thread-safe, single rotation generation.
LocLocalized-string facade over the Windows App SDK ResourceLoader (PRI built from Strings/<lang>/Resources.resw). Code keys are flat identifiers (Area_Thing, e.g. Status_Preparing); XAML strings come from x:Uid instead. The Override seam lets unit tests resolve keys without a PRI in the test host.
NotifierProcess-wide notification funnel. Anything (global handlers, background tasks, the engine callback) can post from any thread; the ViewModel subscribes and marshals to the UI InfoBar stack. Posts are also mirrored to the file log so nothing the user saw is missing from a bug report.
ScopeFolderPickerFolder picker for scope mode (ADR-0024). Unpackaged WinUI 3 requires a picker to be associated with the app window's HWND before it is shown — it throws otherwise — so this always initializes with WindowHandle.
ScopePathsPure path helpers for scope mode (ADR-0024/-0025). The engine treats scope roots as independent and would double-walk a nested pair, so the UI normalizes the chosen set; excludes must sit under a root to mean anything. No I/O — unit-tested directly.
ServiceProvisionerThe shared "make file search usable" steps, behind both the setup screen's one-click button and the management dialog's register action: register the fmf-engine service elevated, then wait for its pipe to start serving and relaunch so this (unelevated, empty-fake) instance comes back connected. The engine transport is chosen once at startup, so a relaunch is how a freshly registered service takes effect. Instance-based so the elevated setup, the pipe probe, the relaunch and the inter-probe delay are injectable boundaries (ADR-0022) — production code uses Real, which wires the real statics; tests drive fakes.
ServiceSetupIn-app service setup — the GUI half ADR-0016 left to a terminal: detects the fmf-engine SCM registration (read-only, works unelevated) and drives fmf-service.exe install/start so the one-time elevation never needs PowerShell. Mutations are strictly user-initiated (the notification button); install is idempotent on the service side.
ShellOpsShell-facing operations, centralized so every failure path notifies the user instead of crashing. Targets launch via explorer.exe to shed the process's elevation (CLAUDE.md UI rules).
TaskExtensionsExtensions for safely launching fire-and-forget System.Threading.Tasks.Tasks (CLAUDE.md rule: never _ = SomeAsync()).
Structs
ServiceActionResultResult of one RunElevated(string, string) call: the classified Outcome plus the raw process ExitCode (-1 when the process never produced one).
Interfaces
IDispatcherUI-thread dispatch boundary. The single seam that lets the search pipeline and the virtualized list run under unit tests without a real DispatcherQueue — two implementations by necessity: DispatcherQueueDispatcher (production) and a manual fake in the test project.
IDispatcherTimerThe one-shot timer handle returned by CreateOneShotTimer(TimeSpan, Action) — fires on the UI thread and is restartable for debounce.
Enums
EngineServiceStateSCM registration/run state of the fmf-engine service, as seen by the unelevated UI via QueryState() — drives whether the app offers to install, start, or nothing at all.
NotifySeveritySeverity of an AppNotification — selects the InfoBar style and the file-log level, and decides whether the entry auto-dismisses (Info) or stays until the user closes it.
ServiceActionOutcomeVerdict of one elevated lifecycle action (RunElevated(string, string)). Output is unreadable under ShellExecute, so the exit code is the only signal; a declined UAC prompt is distinguished from a genuine failure so the UI can say so.

FindMyFiles

FindMyFiles.ViewModels

FocusedQueryRewriter Class

Focused search: a pure query rewrite in the UI layer — the engine is never touched (ADR-0019). Every top-level OR group of the user's query gets the configured noise-path exclusions (!path:"…") and the extension whitelist (one ext:a;b;… term) appended, except where the user already expressed intent: a group mentioning ext:/regex: keeps its own type filter, a group mentioning path: or containing \ keeps its own location.

public static class FocusedQueryRewriter

Inheritance System.Object → FocusedQueryRewriter

Methods

FocusedQueryRewriter.Compose(string, IReadOnlyList<string>, IReadOnlyList<string>) Method

Rewrites userQuery for focused mode. An empty/whitespace query is returned unchanged — the "no query, no results" rule stays the orchestrator's, and a rewrite must never turn an empty query into a non-empty one.

public static string Compose(string userQuery, System.Collections.Generic.IReadOnlyList<string> excludePaths, System.Collections.Generic.IReadOnlyList<string> extensions);

Parameters

userQuery System.String

The user's raw query text.

excludePaths System.Collections.Generic.IReadOnlyList<System.String>

Noise paths appended as !path:"…" exclusions.

extensions System.Collections.Generic.IReadOnlyList<System.String>

The extension whitelist appended as one ext: term.

Returns

System.String
The rewritten query, or the input unchanged when empty or already constrained.

FindMyFiles

FindMyFiles.ViewModels

MainViewModel Class

Provides a mechanism for releasing unmanaged resources.

public sealed class MainViewModel : CommunityToolkit.Mvvm.ComponentModel.ObservableObject, System.IDisposable

Inheritance System.ObjectCommunityToolkit.Mvvm.ComponentModel.ObservableObject → MainViewModel

Implements System.IDisposable

Constructors

MainViewModel(IEngineClient, IDispatcher, AppSettings, Func<Task<string>>, Action, Func<bool>, ServiceProvisioner) Constructor

Builds the focused components, restores focused-search settings, and subscribes the engine events (volume updates, errors, connection changes). Call StartAsync() afterwards to begin indexing.

public MainViewModel(FindMyFiles.Engine.IEngineClient engine, FindMyFiles.Services.IDispatcher dispatcher, FindMyFiles.Services.AppSettings? settings=null, System.Func<System.Threading.Tasks.Task<string?>>? folderPicker=null, System.Action? relaunch=null, System.Func<bool>? isScopeMode=null, FindMyFiles.Services.ServiceProvisioner? provisioner=null);

Parameters

engine IEngineClient

The engine client (Fake / Ffi / Pipe) this page drives.

dispatcher IDispatcher

UI dispatcher used to marshal engine callbacks and back timers.

settings AppSettings

App settings to read/persist; loaded from disk when null.

folderPicker System.Func<System.Threading.Tasks.Task<System.String>>

Scope-folder picker; defaults to the real PickAsync() (tests inject a fake).

relaunch System.Action

Unelevated relaunch action; defaults to the real Relaunch() (tests inject a no-op).

isScopeMode System.Func<System.Boolean>

Reports whether the engine is a scope-mode walk; defaults to inspecting the real FfiEngineClient (tests inject a constant to drive the mode-dependent UI).

provisioner ServiceProvisioner

The register→wait→relaunch steps behind the setup screen's one-click button; defaults to Real (tests inject fakes so EnableSearchAsync() runs without UAC).

Properties

MainViewModel.CanStartScope Property

The "start scope search" button is enabled only once at least one folder has been chosen.

public bool CanStartScope { get; }

Property Value

System.Boolean

MainViewModel.DataLocationText Property

The portable-data-root footnote (only shown when IsPortable).

public string DataLocationText { get; }

Property Value

System.String

MainViewModel.IsDisconnected Property

True when the engine is the empty fake (unelevated, no service) — the page shows the setup screen instead of a search box that can only return zero rows. Fixed for this instance's lifetime (the transport is chosen once; registering relaunches), so x:Bind OneTime is enough.

public bool IsDisconnected { get; }

Property Value

System.Boolean

MainViewModel.IsPortable Property

True when app state lives next to the exe rather than the user profile (AppPaths) — drives the setup screen's "nothing leaves this folder" footnote. Fixed at startup, so x:Bind OneTime.

public bool IsPortable { get; }

Property Value

System.Boolean

MainViewModel.IsPrivilegedMode Property

True once indexing in the elevated whole-volume mode (service or in-proc). Gates the gear menu's "manage service" item — the complement of IsScopeMode while ready, both false while disconnected. Fixed at startup, so x:Bind OneTime.

public bool IsPrivilegedMode { get; }

Property Value

System.Boolean

MainViewModel.IsReady Property

Inverse of IsDisconnected — true when the search UI (box + result list) should be shown instead of the setup screen.

public bool IsReady { get; }

Property Value

System.Boolean

MainViewModel.IsScopeMode Property

True once indexing in **scope mode** (ADR-0024: a user-chosen set of folders, not all drives). Gates the gear menu's "change search folders" item. Fixed at startup (the transport is chosen once), so x:Bind OneTime is enough.

public bool IsScopeMode { get; }

Property Value

System.Boolean

MainViewModel.ModeText Property

The current index mode for the status submenu's info row (selected folders vs all drives). Fixed at startup, so x:Bind OneTime.

public string ModeText { get; }

Property Value

System.String

MainViewModel.Notifications Property

The InfoBar stack — failures and transient notices are pushed here.

public FindMyFiles.ViewModels.NotificationCenter Notifications { get; }

Property Value

NotificationCenter

MainViewModel.Perf Property

State behind the F12 performance panel (last trace, stats, latency history).

public FindMyFiles.ViewModels.PerfPanelViewModel Perf { get; }

Property Value

PerfPanelViewModel

MainViewModel.Results Property

How results land in the virtualized list (publish / refresh in place / empty) — the seam the orchestrator hands outcomes to.

public FindMyFiles.ViewModels.ResultsPresenter Results { get; }

Property Value

ResultsPresenter

MainViewModel.ScopeCoverageNote Property

A note naming the folders already inside a larger selected one, so the user sees the bigger set subsumes them (they merge on apply). Empty when the selection has no nesting. Recomputed on every ScopeFolders change.

public string ScopeCoverageNote { get; }

Property Value

System.String

MainViewModel.ScopeExcludes Property

Subfolders to prune from the walk (ADR-0025), shown in the scope manager dialog. Each must sit under a ScopeFolders root; seeded from settings, persisted by ApplyScopeChange().

public System.Collections.ObjectModel.ObservableCollection<string> ScopeExcludes { get; }

Property Value

System.Collections.ObjectModel.ObservableCollection<System.String>

MainViewModel.ScopeFolders Property

Folders the user has chosen to fold-walk in scope mode, edited in the scope dialog. Seeded from settings; ApplyScopeChange() persists them as ScopeRoots and relaunches.

public System.Collections.ObjectModel.ObservableCollection<string> ScopeFolders { get; }

Property Value

System.Collections.ObjectModel.ObservableCollection<System.String>

MainViewModel.Search Property

Decides when and what to search (debounce, generation, requery triggers); the page forwards box edits and toggles to it.

public FindMyFiles.ViewModels.SearchOrchestrator Search { get; }

Property Value

SearchOrchestrator

MainViewModel.SearchPlaceholder Property

The search box hint — regex/scope-aware, so the box itself signals that regex mode is on (the toggle lives in the gear menu).

public string SearchPlaceholder { get; }

Property Value

System.String

MainViewModel.SetupNotBusy Property

Inverse of FindMyFiles.ViewModels.MainViewModel.SetupBusy — gates the setup button's enabled state.

public bool SetupNotBusy { get; }

Property Value

System.Boolean

Methods

MainViewModel.ApplyScopeChange() Method

Apply the current ScopeFolders as the scope: drop roots nested under another (Normalize(IEnumerable<string>)), and if the set actually changed, persist it as ScopeRoots and relaunch (unelevated) into a fresh WalkInProc that folder-walks the new set (ADR-0024). The engine has no live root-swap (index_start_scope no-ops on an existing scope slot), so a relaunch is the only way to re-walk. No-op when empty or unchanged, so re-opening the manager and closing it without edits never restarts.

public void ApplyScopeChange();

MainViewModel.Dispose() Method

Unsubscribe the engine-event marshaler — the one owned disposable — so its handlers stop holding this view model rooted.

public void Dispose();

Implements Dispose()

MainViewModel.EnableSearchAsync() Method

Setup screen's one-click action: register the service elevated, then (on success) wait for its pipe and relaunch — so a first-time user goes from the setup screen to a working search box in one click. The app stays unelevated; only fmf-service is elevated (per-action UAC).

public System.Threading.Tasks.Task EnableSearchAsync();

Returns

System.Threading.Tasks.Task
A task that completes when registration finishes, or before relaunch on success.

MainViewModel.PickScopeExcludeAsync() Method

Manager dialog (scope mode): pick a subfolder to prune from the walk (ADR-0025). Rejected with a notice when it is not inside one of the chosen ScopeFolders roots (an exclude outside the indexed set prunes nothing). Case-insensitive dedupe.

public System.Threading.Tasks.Task PickScopeExcludeAsync();

Returns

System.Threading.Tasks.Task
A task that completes once the picked folder (if valid) is added.

MainViewModel.PickScopeFoldersAsync() Method

Setup screen (no-admin path): open the folder picker and add the chosen folder to ScopeFolders (case-insensitive dedupe). The picker is single-select, so this adds one folder per click.

public System.Threading.Tasks.Task PickScopeFoldersAsync();

Returns

System.Threading.Tasks.Task
A task that completes once the picked folder (if any) has been added.

MainViewModel.RemoveScopeExclude(string) Method

Drop one excluded subfolder (the per-row × button).

public void RemoveScopeExclude(string path);

Parameters

path System.String

The exclude path to remove.

MainViewModel.RemoveScopeFolder(string) Method

Drop one folder from the scope list (the per-row × button).

public void RemoveScopeFolder(string path);

Parameters

path System.String

The folder path to remove.

MainViewModel.SetSort(FmfSort) Method

Column-header click: re-clicking the active FindMyFiles.ViewModels.MainViewModel.Sort column toggles FindMyFiles.ViewModels.MainViewModel.SortDescending, a new column switches to it ascending. Either way requeries with Sort.

public void SetSort(FindMyFiles.Engine.FmfSort key);

Parameters

key FmfSort

The sort column the clicked header maps to.

MainViewModel.StartAsync() Method

Startup sequence, in order: status text → StartIndexing → initial requery. Runs on the UI thread; the engine calls are awaited so a pipe transport never blocks it.

public System.Threading.Tasks.Task StartAsync();

Returns

System.Threading.Tasks.Task
A task that completes once startup indexing and the initial requery are kicked off.

FindMyFiles

FindMyFiles.ViewModels

NotificationCenter Class

The InfoBar notification stack: capped at three, Info entries dissolve after five seconds. Every error path in the app funnels through here via Notifier. UI thread only (the Notifier subscription marshals).

public sealed class NotificationCenter

Inheritance System.Object → NotificationCenter

Constructors

NotificationCenter(IDispatcher) Constructor

Create the stack bound to dispatcher, used to marshal posts onto the UI thread and to drive the Info auto-dismiss timer.

public NotificationCenter(FindMyFiles.Services.IDispatcher dispatcher);

Parameters

dispatcher IDispatcher

UI-thread dispatch boundary.

Properties

NotificationCenter.Items Property

The live InfoBar stack (oldest first, capped at three), x:Bind'd by the view. Mutated on the UI thread only.

public System.Collections.ObjectModel.ObservableCollection<FindMyFiles.Services.AppNotification> Items { get; }

Property Value

System.Collections.ObjectModel.ObservableCollection<AppNotification>

Methods

NotificationCenter.AttachToNotifier() Method

Drain the process-wide funnel into this stack.

public void AttachToNotifier();

NotificationCenter.Push(AppNotification) Method

Append n to the stack, evicting the oldest entries to stay within the three-item cap; Info entries also schedule their own five-second removal. UI thread only.

public void Push(FindMyFiles.Services.AppNotification n);

Parameters

n AppNotification

The notification to show.

NotificationCenter.Remove(AppNotification) Method

Remove n from the stack — the InfoBar close button's target. No-op if it is already gone. UI thread only.

public void Remove(FindMyFiles.Services.AppNotification n);

Parameters

n AppNotification

The notification to dismiss.

FindMyFiles

FindMyFiles.ViewModels

PerfPanelViewModel Class

Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

public sealed class PerfPanelViewModel : CommunityToolkit.Mvvm.ComponentModel.ObservableObject

Inheritance System.ObjectCommunityToolkit.Mvvm.ComponentModel.ObservableObject → PerfPanelViewModel

Constructors

PerfPanelViewModel(IEngineClient) Constructor

Binds the panel to engine — the source of both the stats snapshot and the transport label.

public PerfPanelViewModel(FindMyFiles.Engine.IEngineClient engine);

Parameters

engine IEngineClient

Engine client supplying stats and the transport label.

Properties

PerfPanelViewModel.EngineMode Property

Engine transport label for the F12 panel — moved off the gear menu, where its internal terms (fake / in-proc) confused end users; F12 is diagnostic, so the precise vocabulary stays here.

public string EngineMode { get; }

Property Value

System.String

PerfPanelViewModel.RecentTotalsUs Property

Latencies of the most recent queries (µs, oldest first).

public System.Collections.Generic.IReadOnlyList<ulong> RecentTotalsUs { get; }

Property Value

System.Collections.Generic.IReadOnlyList<System.UInt64>

Methods

PerfPanelViewModel.RecordTrace(QueryTraceData) Method

Record one completed query (trace may be null).

public void RecordTrace(FindMyFiles.Engine.QueryTraceData? trace);

Parameters

trace QueryTraceData

Stage breakdown of the query, or null when none was emitted.

PerfPanelViewModel.RefreshStatsAsync() Method

Pull a fresh FindMyFiles.ViewModels.PerfPanelViewModel.Stats snapshot from the engine and raise PerfDataChanged. Awaitable so a pipe round-trip doesn't block the caller.

public System.Threading.Tasks.Task RefreshStatsAsync();

Returns

System.Threading.Tasks.Task
A System.Threading.Tasks.Task that completes once the snapshot is refreshed.

PerfPanelViewModel.Toggle() Method

Flip the panel's visibility (the F12 shortcut / debug menu).

public void Toggle();

Events

PerfPanelViewModel.PerfDataChanged Event

Raised on the UI thread whenever trace/stats data moved.

public event Action? PerfDataChanged;

Event Type

System.Action

FindMyFiles

FindMyFiles.ViewModels

RequeryOrigin Enum

Why a requery ran. Reset origins land the user at the top of the list; position-preserving origins restore the previous viewport (docs/ARCHITECTURE.md "two requery families").

public enum RequeryOrigin

Fields

Initial 0

First query of the session — reset (top of list).

Typing 1

The user edited the search box — reset.

Clear 2

The search box was cleared — reset.

Sort 3

The sort column/direction changed — reset.

Filter 4

A result filter changed — reset.

IndexChanged 5

The on-disk index changed (USN-driven refresh) — preserves the viewport.

VolumeReady 6

A volume finished indexing and joined the results — preserves the viewport.

Stale 7

The held result went stale and was re-issued — preserves the viewport.

FindMyFiles

FindMyFiles.ViewModels

RequeryOriginExtensions Class

Helpers over RequeryOrigin.

public static class RequeryOriginExtensions

Inheritance System.Object → RequeryOriginExtensions

Methods

RequeryOriginExtensions.PreservesPosition(this RequeryOrigin) Method

True for origins that restore the previous viewport instead of scrolling to the top (IndexChanged, VolumeReady, Stale) — the background refreshes the user did not initiate.

public static bool PreservesPosition(this FindMyFiles.ViewModels.RequeryOrigin origin);

Parameters

origin RequeryOrigin

The requery origin to classify.

Returns

System.Boolean
True when the origin preserves the viewport; false when it resets to the top.

FindMyFiles

FindMyFiles.ViewModels

ResultRow Class

Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

public sealed class ResultRow : CommunityToolkit.Mvvm.ComponentModel.ObservableObject

Inheritance System.ObjectCommunityToolkit.Mvvm.ComponentModel.ObservableObject → ResultRow

Properties

ResultRow.EntryRef Property

Engine row identity — lets the view re-find a selected row after a position-preserving requery (best effort).

public ulong EntryRef { get; }

Property Value

System.UInt64

ResultRow.FullPath Property

Absolute path (ParentPath + Name) — what open/copy act on. Empty until Fill(RowData, IHighlighter).

public string FullPath { get; }

Property Value

System.String

ResultRow.Index Property

Absolute position of this row in the full result set — the virtualized list's stable key, set once at placeholder creation and never changed (the same instance is refilled when its page lands).

public long Index { get; init; }

Property Value

System.Int64

ResultRow.IsPlaceholder Property

True while this is an unfilled placeholder (its page hasn't arrived); the row template shows a skeleton until Fill(RowData, IHighlighter).

public bool IsPlaceholder { get; }

Property Value

System.Boolean

Methods

ResultRow.CreatePlaceholder(long) Method

Make an empty row for index — the virtualized list's only constructor, called for every slot before any data is fetched.

public static FindMyFiles.ViewModels.ResultRow CreatePlaceholder(long index);

Parameters

index System.Int64

Absolute position of the row in the full result set.

Returns

ResultRow
A new placeholder row keyed to index.

ResultRow.Fill(RowData, IHighlighter) Method

Populate this placeholder from an engine RowData page hit: copies identity (EntryRef, FullPath), formats size/date for display, picks the type glyph, and clears IsPlaceholder. In place — the bound instance is reused.

public void Fill(FindMyFiles.Engine.RowData data, FindMyFiles.Highlighting.IHighlighter? highlighter=null);

Parameters

data RowData

The engine page hit supplying this row's identity and fields.

highlighter IHighlighter

Active-query highlighter, or null when no query is set.

FindMyFiles

FindMyFiles.ViewModels

ResultsPresenter Class

Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

public sealed class ResultsPresenter : CommunityToolkit.Mvvm.ComponentModel.ObservableObject

Inheritance System.ObjectCommunityToolkit.Mvvm.ComponentModel.ObservableObject → ResultsPresenter

Constructors

ResultsPresenter(IDispatcher) Constructor

Create the presenter and its lifetime-single VirtualResultList, both bound to dispatcher (the UI thread that publishes and fetches run on).

public ResultsPresenter(FindMyFiles.Services.IDispatcher dispatcher);

Parameters

dispatcher IDispatcher

UI-thread dispatcher that publishes and page fetches run on.

Properties

ResultsPresenter.ResultsSource Property

Lifetime-single ItemsSource — bind with x:Bind OneTime.

public FindMyFiles.Virtualization.VirtualResultList ResultsSource { get; }

Property Value

VirtualResultList

Methods

ResultsPresenter.PresentEmpty() Method

Empty search box → empty screen, idempotently.

public void PresentEmpty();

ResultsPresenter.PresentEngineFailure() Method

Engine failure: the notification carries the details.

public void PresentEngineFailure();

ResultsPresenter.PresentQueryError(string) Method

Show a query problem without touching the published results.

public void PresentQueryError(string message);

Parameters

message System.String

The query-error message to display in the status bar.

ResultsPresenter.PublishAsync(ISearchResult, QueryTraceData, RequeryOrigin, IHighlighter, Func<bool>) Method

Prefetch the viewport pages of result, then publish it. Runs on the UI thread; the page reads themselves are async, so the thread is never blocked and newer keystrokes keep flowing. When isCurrent turns false mid-flight the result is disposed unpublished — the screen keeps showing the previous result.

public System.Threading.Tasks.Task PublishAsync(FindMyFiles.Engine.ISearchResult result, FindMyFiles.Engine.QueryTraceData? trace, FindMyFiles.ViewModels.RequeryOrigin origin, FindMyFiles.Highlighting.IHighlighter highlighter, System.Func<bool> isCurrent);

Parameters

result ISearchResult

The new search result to prefetch and publish.

trace QueryTraceData

Optional query trace used to format the count text; null when no timing is available.

origin RequeryOrigin

Why the requery ran — decides reset vs. position restore.

highlighter IHighlighter

Match highlighter applied to the published rows.

isCurrent System.Func<System.Boolean>

Predicate that returns false once a newer query has superseded this one.

Returns

System.Threading.Tasks.Task
A System.Threading.Tasks.Task representing the asynchronous publish.

Exceptions

StaleResultException
The index was structurally rebuilt while prefetching — the caller decides whether to retry.

ResultsPresenter.RefreshInPlaceAsync(ISearchResult, QueryTraceData, RequeryOrigin, IHighlighter, Func<bool>) Method

Same-results refresh (Unchanged): swap the new handle in without a Reset, so an idle USN requery repaints nothing — only cells whose values actually changed in place (sizes/mtimes of files being written) update. The count text stays untouched on purpose: a churning ms display reads as flicker. Falls back to a full publish if the counts somehow disagree.

public System.Threading.Tasks.Task RefreshInPlaceAsync(FindMyFiles.Engine.ISearchResult result, FindMyFiles.Engine.QueryTraceData? trace, FindMyFiles.ViewModels.RequeryOrigin origin, FindMyFiles.Highlighting.IHighlighter highlighter, System.Func<bool> isCurrent);

Parameters

result ISearchResult

The refreshed search result handle to swap in.

trace QueryTraceData

Optional query trace forwarded to the publish fallback; null when no timing is available.

origin RequeryOrigin

Why the requery ran — forwarded to the publish fallback.

highlighter IHighlighter

Match highlighter applied to the refreshed rows.

isCurrent System.Func<System.Boolean>

Predicate that returns false once a newer query has superseded this one.

Returns

System.Threading.Tasks.Task
A System.Threading.Tasks.Task representing the asynchronous refresh.

Events

ResultsPresenter.ResultsPublished Event

Raised on the UI thread right after each seeded Reset.

public event Action<ResultsPublication>? ResultsPublished;

Event Type

System.Action<ResultsPublication>

FindMyFiles

FindMyFiles.ViewModels

ResultsPublication Struct

Describes one published result set so the view can place the viewport: reset origins scroll to the top, position-preserving origins scroll to RestoreIndex. The seeded index window is where a previously selected row may be re-found.

public readonly record struct ResultsPublication : System.IEquatable<FindMyFiles.ViewModels.ResultsPublication>

Implements System.IEquatable<ResultsPublication>

Constructors

ResultsPublication(RequeryOrigin, Nullable<int>, int, int) Constructor

Describes one published result set so the view can place the viewport: reset origins scroll to the top, position-preserving origins scroll to RestoreIndex. The seeded index window is where a previously selected row may be re-found.

public ResultsPublication(FindMyFiles.ViewModels.RequeryOrigin Origin, System.Nullable<int> RestoreIndex, int FirstSeededIndex, int LastSeededIndex);

Parameters

Origin RequeryOrigin

Why the requery ran — decides reset vs. position restore.

RestoreIndex System.Nullable<System.Int32>

First visible row index to scroll back to for a position-preserving origin; null for reset origins (scroll to top).

FirstSeededIndex System.Int32

First row index that was prefetched and is thus realizable without a fetch — lower bound of the selection re-find window.

LastSeededIndex System.Int32

Last prefetched row index — upper bound of the selection re-find window.

Properties

ResultsPublication.FirstSeededIndex Property

First row index that was prefetched and is thus realizable without a fetch — lower bound of the selection re-find window.

public int FirstSeededIndex { get; init; }

Property Value

System.Int32

ResultsPublication.LastSeededIndex Property

Last prefetched row index — upper bound of the selection re-find window.

public int LastSeededIndex { get; init; }

Property Value

System.Int32

ResultsPublication.Origin Property

Why the requery ran — decides reset vs. position restore.

public FindMyFiles.ViewModels.RequeryOrigin Origin { get; init; }

Property Value

RequeryOrigin

ResultsPublication.RestoreIndex Property

First visible row index to scroll back to for a position-preserving origin; null for reset origins (scroll to top).

public System.Nullable<int> RestoreIndex { get; init; }

Property Value

System.Nullable<System.Int32>

FindMyFiles

FindMyFiles.ViewModels

SearchOrchestrator Class

When and what to search: 50ms debounce on typing (clearing is instant), a generation counter that discards superseded responses, requery triggers (index changes, stale results) and exception classification. Results are handed to the ResultsPresenter; failures surface through SearchFailed so the ViewModel owns the user-facing wording. All entry points run on the UI thread.

public sealed class SearchOrchestrator

Inheritance System.Object → SearchOrchestrator

Constructors

SearchOrchestrator(IEngineClient, EngineEventMarshaler, IDispatcher, ResultsPresenter, Func<SearchRequest>) Constructor

Wires the orchestrator to its collaborators and subscribes the auto-requery triggers (stale results, index changes).

public SearchOrchestrator(FindMyFiles.Engine.IEngineClient engine, FindMyFiles.Engine.EngineEventMarshaler engineEvents, FindMyFiles.Services.IDispatcher dispatcher, FindMyFiles.ViewModels.ResultsPresenter presenter, System.Func<FindMyFiles.ViewModels.SearchRequest> request);

Parameters

engine IEngineClient

Engine the queries are issued against.

engineEvents EngineEventMarshaler

UI-thread-marshaled engine events; its IndexChanged drives an automatic requery.

dispatcher IDispatcher

UI dispatcher — used to create the debounce timer.

presenter ResultsPresenter

Sink that publishes results and stale signals.

request System.Func<SearchRequest>

Pull of the current UI state at query time (the ViewModel stays the source of truth).

Properties

SearchOrchestrator.FocusedExcludePaths Property

Noise paths excluded in focused mode (settings-owned).

public System.Collections.Generic.IReadOnlyList<string> FocusedExcludePaths { get; set; }

Property Value

System.Collections.Generic.IReadOnlyList<System.String>

SearchOrchestrator.FocusedExtensions Property

Extension whitelist for focused mode (settings-owned).

public System.Collections.Generic.IReadOnlyList<string> FocusedExtensions { get; set; }

Property Value

System.Collections.Generic.IReadOnlyList<System.String>

SearchOrchestrator.FocusedSearch Property

Focused search: when on, the user's query is rewritten with the two lists below (FocusedQueryRewriter) right before it reaches the engine. Defaults to off here — product wiring (MainViewModel) pushes the persisted settings in; a toggle flip is a filter change, so the owner requeries with Filter (top reset).

public bool FocusedSearch { get; set; }

Property Value

System.Boolean

Methods

SearchOrchestrator.NotifyCompositionEnded(string) Method

IME composition committed (or cancelled) — search the final text through the normal debounce.

public void NotifyCompositionEnded(string value);

Parameters

value System.String

The committed search box text after composition.

SearchOrchestrator.NotifyCompositionStarted() Method

IME composition began: hold queries so half-composed text (romaji fragments, candidate strings) never hits the engine.

public void NotifyCompositionStarted();

SearchOrchestrator.NotifyTextChanged(string) Method

Search box text changed: debounce a normal edit (50ms), requery immediately on a clear (so emptying feels instant), and ignore edits while an IME composition is in flight.

public void NotifyTextChanged(string value);

Parameters

value System.String

The current search box text after the edit.

SearchOrchestrator.Requery(RequeryOrigin) Method

Fire-and-forget a query for the current UI state, bumping the generation so any in-flight older response is discarded. origin records why (and lets the presenter decide whether to preserve scroll/selection).

public void Requery(FindMyFiles.ViewModels.RequeryOrigin origin);

Parameters

origin RequeryOrigin

Why the requery was triggered.

Events

SearchOrchestrator.SearchFailed Event

Engine or unexpected failure (never query syntax — that goes to the presenter as count text).

public event Action<Exception>? SearchFailed;

Event Type

System.Action<System.Exception>

SearchOrchestrator.TraceCaptured Event

Stage trace of the last completed query (null when the engine produced none) — perf-panel food.

public event Action<QueryTraceData?>? TraceCaptured;

Event Type

System.Action<QueryTraceData>

FindMyFiles

FindMyFiles.ViewModels

SearchRequest Struct

Snapshot of what to search — the ViewModel stays the single source of truth for the UI state; the orchestrator only pulls it.

public readonly record struct SearchRequest : System.IEquatable<FindMyFiles.ViewModels.SearchRequest>

Implements System.IEquatable<SearchRequest>

Constructors

SearchRequest(string, SearchOptions) Constructor

Snapshot of what to search — the ViewModel stays the single source of truth for the UI state; the orchestrator only pulls it.

public SearchRequest(string Query, FindMyFiles.Engine.SearchOptions Options);

Parameters

Query System.String

Raw user query text (before any focused-mode rewrite).

Options SearchOptions

Sort, case and hidden/system flags for this search.

Properties

SearchRequest.Options Property

Sort, case and hidden/system flags for this search.

public FindMyFiles.Engine.SearchOptions Options { get; init; }

Property Value

SearchOptions

SearchRequest.Query Property

Raw user query text (before any focused-mode rewrite).

public string Query { get; init; }

Property Value

System.String

FindMyFiles

FindMyFiles.ViewModels

ServiceManagerViewModel Class

Supports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.

public sealed class ServiceManagerViewModel : CommunityToolkit.Mvvm.ComponentModel.ObservableObject

Inheritance System.ObjectCommunityToolkit.Mvvm.ComponentModel.ObservableObject → ServiceManagerViewModel

Constructors

ServiceManagerViewModel(ServiceProvisioner) Constructor

Locates fmf-service.exe once (bundle or dev tree); the dialog should call Refresh() on open to fill the state line.

public ServiceManagerViewModel(FindMyFiles.Services.ServiceProvisioner? provisioner=null);

Parameters

provisioner ServiceProvisioner

The post-register wait+relaunch steps; defaults to Real (tests inject a fake).

Properties

ServiceManagerViewModel.HasResult Property

Whether the result InfoBar has anything to show (FindMyFiles.ViewModels.ServiceManagerViewModel.ResultText non-empty).

public bool HasResult { get; }

Property Value

System.Boolean

ServiceManagerViewModel.NotBusy Property

Buttons stay enabled only while idle — an in-flight UAC action greys the whole row (visibility is still driven by the Is*/Can* flags).

public bool NotBusy { get; }

Property Value

System.Boolean

Methods

ServiceManagerViewModel.Refresh() Method

Re-read the SCM state and recompute which actions apply. Cheap read-only P/Invoke (no elevation) — safe on the UI thread.

public void Refresh();

ServiceManagerViewModel.RegisterAsync() Method

install (idempotent) + restart in one elevated step (the fmf-service `setup` verb). The daily user's SID is forwarded so OTS elevation — a *different* admin account at the UAC prompt — does not lock this user out of the pipe (docs/SECURITY.md threat 1). The app is unelevated here, so CurrentUserSid is exactly that daily user.

public System.Threading.Tasks.Task RegisterAsync();

Returns

System.Threading.Tasks.Task
A task that completes when the elevated setup verb finishes.

ServiceManagerViewModel.RestartApp() Method

Plain (unelevated) relaunch so the fresh instance connects to the now-running service over the pipe.

public void RestartApp();

ServiceManagerViewModel.RestartAsync() Method

Restart the running service (one elevated restart verb).

public System.Threading.Tasks.Task RestartAsync();

Returns

System.Threading.Tasks.Task
A task that completes when the elevated restart verb finishes.

ServiceManagerViewModel.StartAsync() Method

Start the stopped service (one elevated start verb).

public System.Threading.Tasks.Task StartAsync();

Returns

System.Threading.Tasks.Task
A task that completes when the elevated start verb finishes.

ServiceManagerViewModel.StopAsync() Method

Stop the running service (one elevated stop verb).

public System.Threading.Tasks.Task StopAsync();

Returns

System.Threading.Tasks.Task
A task that completes when the elevated stop verb finishes.

ServiceManagerViewModel.UninstallAsync() Method

Uninstall the service (one elevated uninstall verb), adding --purge-data when FindMyFiles.ViewModels.ServiceManagerViewModel.PurgeData is set.

public System.Threading.Tasks.Task UninstallAsync();

Returns

System.Threading.Tasks.Task
A task that completes when the elevated uninstall verb finishes.

FindMyFiles

FindMyFiles.ViewModels

StatusFormatter Class

All user-facing status wording in one place — keys resolve through Loc (Strings/<lang>/Resources.resw).

public static class StatusFormatter

Inheritance System.Object → StatusFormatter

Methods

StatusFormatter.Count(QueryTraceData, long) Method

Result-count line: the hits count plus the elapsed query time (ms) when a trace is present (TotalUs → ms), the bare count otherwise.

public static string Count(FindMyFiles.Engine.QueryTraceData? trace, long hits);

Parameters

trace QueryTraceData

Latest query trace, or null when timing is unavailable.

hits System.Int64

Number of matching results.

Returns

System.String
Localized count line, with elapsed time when a trace is present.

StatusFormatter.EngineMode(IEngineClient) Method

Status-bar transport badge: which engine the app talks to right now (client type + live connection state).

public static string EngineMode(FindMyFiles.Engine.IEngineClient engine);

Parameters

engine IEngineClient

Engine client whose type and connection state to describe.

Returns

System.String
Localized transport badge for the active engine.

StatusFormatter.Overall(IReadOnlyList<VolumeStatus>, IReadOnlyList<string>) Method

Startup/refresh snapshot of the overall index state — reflects whatever the engine reports right now, so an already-Ready volume never shows "indexing…". requested is the list we asked to index, used only for messaging when the engine hasn't surfaced any status yet.

public static string Overall(System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.VolumeStatus> volumes, System.Collections.Generic.IReadOnlyList<string> requested);

Parameters

volumes System.Collections.Generic.IReadOnlyList<VolumeStatus>

Per-volume status the engine reports right now.

requested System.Collections.Generic.IReadOnlyList<System.String>

Volumes we asked to index, used only for early messaging.

Returns

System.String
Localized overall index-state line.

StatusFormatter.QueryError(string) Method

Status line for a rejected query — the engine's syntax-error message behind a localized prefix.

public static string QueryError(string message);

Parameters

message System.String

Engine syntax-error message for the rejected query.

Returns

System.String
Localized error line with the engine message behind a prefix.

StatusFormatter.Volume(VolumeStatus, string) Method

Status-bar line for a volume state change; falls back to the current text for states that carry no message.

public static string Volume(FindMyFiles.Engine.VolumeStatus s, string current);

Parameters

s VolumeStatus

Volume status that changed.

current System.String

Existing status text, returned for states with no message.

Returns

System.String
Localized line for the new volume state, or current.

FindMyFiles

FindMyFiles.ViewModels Namespace

Classes
FocusedQueryRewriterFocused search: a pure query rewrite in the UI layer — the engine is never touched (ADR-0019). Every top-level OR group of the user's query gets the configured noise-path exclusions (!path:"…") and the extension whitelist (one ext:a;b;… term) appended, except where the user already expressed intent: a group mentioning ext:/regex: keeps its own type filter, a group mentioning path: or containing \ keeps its own location.
MainViewModelProvides a mechanism for releasing unmanaged resources.
NotificationCenterThe InfoBar notification stack: capped at three, Info entries dissolve after five seconds. Every error path in the app funnels through here via Notifier. UI thread only (the Notifier subscription marshals).
PerfPanelViewModelSupports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.
RequeryOriginExtensionsHelpers over RequeryOrigin.
ResultRowSupports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.
ResultsPresenterSupports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.
SearchOrchestratorWhen and what to search: 50ms debounce on typing (clearing is instant), a generation counter that discards superseded responses, requery triggers (index changes, stale results) and exception classification. Results are handed to the ResultsPresenter; failures surface through SearchFailed so the ViewModel owns the user-facing wording. All entry points run on the UI thread.
ServiceManagerViewModelSupports all classes in the .NET Framework class hierarchy and provides low-level services to derived classes. This is the ultimate base class of all classes in the .NET Framework; it is the root of the type hierarchy.
StatusFormatterAll user-facing status wording in one place — keys resolve through Loc (Strings/<lang>/Resources.resw).
Structs
ResultsPublicationDescribes one published result set so the view can place the viewport: reset origins scroll to the top, position-preserving origins scroll to RestoreIndex. The seeded index window is where a previously selected row may be re-found.
SearchRequestSnapshot of what to search — the ViewModel stays the single source of truth for the UI state; the orchestrator only pulls it.
Enums
RequeryOriginWhy a requery ran. Reset origins land the user at the top of the list; position-preserving origins restore the previous viewport (docs/ARCHITECTURE.md "two requery families").

FindMyFiles

FindMyFiles.Views

PerfPanel Class

The F12 performance panel: stage bar (proportional theme-brush segments), latency sparkline, volume/USN/error text blocks and the one-click diagnostics dump. Rendered imperatively from PerfDataChanged — it is diagnostic chrome, not app data. The host supplies ViewModel via x:Bind; the 1 Hz stats poll runs only while the panel is open. UI thread only.

public sealed class PerfPanel : Microsoft.UI.Xaml.Controls.UserControl, Microsoft.UI.Xaml.Markup.IComponentConnector

Inheritance System.ObjectMicrosoft.UI.Xaml.DependencyObjectMicrosoft.UI.Xaml.UIElementMicrosoft.UI.Xaml.FrameworkElementMicrosoft.UI.Xaml.Controls.ControlMicrosoft.UI.Xaml.Controls.UserControl → PerfPanel

Implements Microsoft.UI.Xaml.Markup.IComponentConnector

Constructors

PerfPanel() Constructor

Builds the 1 Hz stats poll timer (runs only while `ViewModel.IsOpen` is true). The timer is not started here; it is started/stopped on open/close.

public PerfPanel();

Fields

PerfPanel.ViewModelProperty Field

Backing DependencyProperty for ViewModel. On value swap, re-routes `PerfDataChanged`/`PropertyChanged` subscriptions from old to new.

public static readonly DependencyProperty ViewModelProperty;

Field Value

Microsoft.UI.Xaml.DependencyProperty

Properties

PerfPanel.ViewModel Property

Diagnostic ViewModel supplied by the host via `x:Bind`. Source of trace/stats update notifications; drives the 1 Hz stats poll only while the panel is open.

public FindMyFiles.ViewModels.PerfPanelViewModel? ViewModel { get; set; }

Property Value

PerfPanelViewModel

Methods

PerfPanel.Connect(int, object) Method

Connect()

public void Connect(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements Connect(int, object)

PerfPanel.GetBindingConnector(int, object) Method

GetBindingConnector(int connectionId, object target)

public Microsoft.UI.Xaml.Markup.IComponentConnector GetBindingConnector(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements GetBindingConnector(int, object)

Returns

Microsoft.UI.Xaml.Markup.IComponentConnector

PerfPanel.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

FindMyFiles

FindMyFiles.Views

ScopeManagerDialog Class

Wiring only: the scope-folder dialog (ADR-0024). Two contexts share it — the setup screen's "no admin?" link (first-run onboarding, folders only) and the gear menu's "Change search folders…" (re-selection, folders + excludes). State and the persist/relaunch live on the shared MainViewModel; the buttons drive its actions through the sanctioned Forget(this Task, string) funnel (CLAUDE.md convention). The mirror of ServiceManagerDialog for the non-elevated path.

public sealed class ScopeManagerDialog : Microsoft.UI.Xaml.Controls.ContentDialog, Microsoft.UI.Xaml.Markup.IComponentConnector

Inheritance System.ObjectMicrosoft.UI.Xaml.DependencyObjectMicrosoft.UI.Xaml.UIElementMicrosoft.UI.Xaml.FrameworkElementMicrosoft.UI.Xaml.Controls.ControlMicrosoft.UI.Xaml.Controls.ContentControlMicrosoft.UI.Xaml.Controls.ContentDialog → ScopeManagerDialog

Implements Microsoft.UI.Xaml.Markup.IComponentConnector

Properties

ScopeManagerDialog.ShowExcludes Property

Whether the excludes section shows. False in the setup (first-run) context — excludes come later, once indexing has started, via the gear's "change search folders"; true for re-selection.

public bool ShowExcludes { get; }

Property Value

System.Boolean

ScopeManagerDialog.VM Property

The page's ViewModel, shared so the dialog edits the same ScopeFolders the setup screen seeds.

public FindMyFiles.ViewModels.MainViewModel VM { get; }

Property Value

MainViewModel

Methods

ScopeManagerDialog.Connect(int, object) Method

Connect()

public void Connect(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements Connect(int, object)

ScopeManagerDialog.GetBindingConnector(int, object) Method

GetBindingConnector(int connectionId, object target)

public Microsoft.UI.Xaml.Markup.IComponentConnector GetBindingConnector(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements GetBindingConnector(int, object)

Returns

Microsoft.UI.Xaml.Markup.IComponentConnector

ScopeManagerDialog.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

ScopeManagerDialog.OpenAsync(MainViewModel, bool) Method

The single entry point (setup link / gear menu). Resolves a XamlRoot from the main window and guards against a second instance (ContentDialog allows only one open at a time). Named OpenAsync, not ShowAsync, to avoid hiding the inherited Microsoft.UI.Xaml.Controls.ContentDialog.ShowAsync.

public static System.Threading.Tasks.Task OpenAsync(FindMyFiles.ViewModels.MainViewModel vm, bool setup=false);

Parameters

vm MainViewModel

The page ViewModel to edit.

setup System.Boolean

True for the first-run setup context (folders only, onboarding wording); false for re-selection (folders + excludes).

Returns

System.Threading.Tasks.Task
A System.Threading.Tasks.Task that completes when the dialog closes.

FindMyFiles

FindMyFiles.Views

ServiceManagerDialog Class

Wiring only: the gear menu's "Manage service…" dialog. State and the elevated mutations live in ServiceManagerViewModel; the buttons fire-and-forget its async actions through the sanctioned Forget(this Task, string) funnel (CLAUDE.md convention).

public sealed class ServiceManagerDialog : Microsoft.UI.Xaml.Controls.ContentDialog, Microsoft.UI.Xaml.Markup.IComponentConnector

Inheritance System.ObjectMicrosoft.UI.Xaml.DependencyObjectMicrosoft.UI.Xaml.UIElementMicrosoft.UI.Xaml.FrameworkElementMicrosoft.UI.Xaml.Controls.ControlMicrosoft.UI.Xaml.Controls.ContentControlMicrosoft.UI.Xaml.Controls.ContentDialog → ServiceManagerDialog

Implements Microsoft.UI.Xaml.Markup.IComponentConnector

Constructors

ServiceManagerDialog() Constructor

Creates the ViewModel and runs the initial state `Refresh`. The only public entry point is OpenAsync(); direct constructor calls are not expected.

public ServiceManagerDialog();

Properties

ServiceManagerDialog.VM Property

ViewModel for service state and elevation-requiring operations (register/uninstall/start/stop/restart). Each button fires this instance's async actions via `Forget`.

public FindMyFiles.ViewModels.ServiceManagerViewModel VM { get; }

Property Value

ServiceManagerViewModel

Methods

ServiceManagerDialog.Connect(int, object) Method

Connect()

public void Connect(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements Connect(int, object)

ServiceManagerDialog.GetBindingConnector(int, object) Method

GetBindingConnector(int connectionId, object target)

public Microsoft.UI.Xaml.Markup.IComponentConnector GetBindingConnector(int connectionId, object target);

Parameters

connectionId System.Int32

target System.Object

Implements GetBindingConnector(int, object)

Returns

Microsoft.UI.Xaml.Markup.IComponentConnector

ServiceManagerDialog.InitializeComponent() Method

InitializeComponent()

public void InitializeComponent();

ServiceManagerDialog.OpenAsync() Method

The single entry point that opens the manager (the gear menu). Resolves a XamlRoot from the main window and guards against a second instance (ContentDialog allows only one open at a time). Named OpenAsync, not ShowAsync, to avoid hiding the inherited Microsoft.UI.Xaml.Controls.ContentDialog.ShowAsync.

public static System.Threading.Tasks.Task OpenAsync();

Returns

System.Threading.Tasks.Task
A System.Threading.Tasks.Task that completes when the dialog closes.

FindMyFiles

FindMyFiles.Views Namespace

Classes
PerfPanelThe F12 performance panel: stage bar (proportional theme-brush segments), latency sparkline, volume/USN/error text blocks and the one-click diagnostics dump. Rendered imperatively from PerfDataChanged — it is diagnostic chrome, not app data. The host supplies ViewModel via x:Bind; the 1 Hz stats poll runs only while the panel is open. UI thread only.
ScopeManagerDialogWiring only: the scope-folder dialog (ADR-0024). Two contexts share it — the setup screen's "no admin?" link (first-run onboarding, folders only) and the gear menu's "Change search folders…" (re-selection, folders + excludes). State and the persist/relaunch live on the shared MainViewModel; the buttons drive its actions through the sanctioned Forget(this Task, string) funnel (CLAUDE.md convention). The mirror of ServiceManagerDialog for the non-elevated path.
ServiceManagerDialogWiring only: the gear menu's "Manage service…" dialog. State and the elevated mutations live in ServiceManagerViewModel; the buttons fire-and-forget its async actions through the sanctioned Forget(this Task, string) funnel (CLAUDE.md convention).

FindMyFiles

FindMyFiles.Virtualization

PageSeed Struct

A page of already-fetched rows handed to Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter), so the viewport is filled the instant a new result is published — never a placeholder flash.

public readonly record struct PageSeed : System.IEquatable<FindMyFiles.Virtualization.PageSeed>

Implements System.IEquatable<PageSeed>

Constructors

PageSeed(long, IReadOnlyList<RowData>) Constructor

A page of already-fetched rows handed to Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter), so the viewport is filled the instant a new result is published — never a placeholder flash.

public PageSeed(long Page, System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.RowData> Rows);

Parameters

Page System.Int64

Page index (row index ÷ FindMyFiles.Virtualization.VirtualResultList.PageSize) these rows belong to.

Rows System.Collections.Generic.IReadOnlyList<RowData>

The page's rows in slot order, as fetched from the engine.

Properties

PageSeed.Page Property

Page index (row index ÷ FindMyFiles.Virtualization.VirtualResultList.PageSize) these rows belong to.

public long Page { get; init; }

Property Value

System.Int64

PageSeed.Rows Property

The page's rows in slot order, as fetched from the engine.

public System.Collections.Generic.IReadOnlyList<FindMyFiles.Engine.RowData> Rows { get; init; }

Property Value

System.Collections.Generic.IReadOnlyList<RowData>

FindMyFiles

FindMyFiles.Virtualization

VirtualResultList Class

Random-access data virtualization for ListView: non-generic IList + INotifyCollectionChanged + IItemsRangeInfo (the only combination that works — microsoft-ui-xaml#1809, ADR-0015). The indexer hands out stable placeholder instances and never fetches; RangesChanged drives 64-row page fetches on a background task, and arriving data fills those same instances in place.

The instance lives as long as the page: new query results arrive through Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter) (seeded pages + one Reset), never by swapping the ItemsSource (ADR-0015). An epoch counter makes fetches started against a previous result fall on the floor.

Membership invariant — the WinRT IList adapter trusts these answers blindly: **never vouch for membership falsely.** A false "absent" merely re-realizes a container; a false "present" sends the ListView to GetAt(staleIndex) and dies deep inside XAML (ADR-0015). A row is a member iff its index is inside Count AND the current page cache holds that exact instance in that slot; rows from previous results, evicted pages or transient enumeration answer absent. Mutating entry points enforce the UI thread (always, not just in Debug).

public sealed class VirtualResultList : System.Collections.IList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, Microsoft.UI.Xaml.Data.IItemsRangeInfo, System.IDisposable

Inheritance System.Object → VirtualResultList

Implements System.Collections.IList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, Microsoft.UI.Xaml.Data.IItemsRangeInfo, System.IDisposable

Constructors

VirtualResultList(IDispatcher) Constructor

Bind the list to dispatcher, the UI-thread gate every mutation is checked against (FindMyFiles.Virtualization.VirtualResultList.EnsureUiThread(System.String)) and the queue background fetch completions marshal back through.

public VirtualResultList(FindMyFiles.Services.IDispatcher dispatcher);

Parameters

dispatcher IDispatcher

The UI-thread dispatcher mutations are gated on and fetch completions are marshaled back through.

Properties

VirtualResultList.Count Property

Row count of the published result, clamped to System.Int32.MaxValue — the fixed size the ListView virtualizes against. Out-of-range indexers throw rather than fetch.

public int Count { get; }

Implements Count

Property Value

System.Int32

VirtualResultList.IsFixedSize Property

Gets a value indicating whether the System.Collections.IList has a fixed size.

public bool IsFixedSize { get; }

Implements IsFixedSize

Property Value

System.Boolean

VirtualResultList.IsReadOnly Property

Gets a value indicating whether the System.Collections.IList is read-only.

public bool IsReadOnly { get; }

Implements IsReadOnly

Property Value

System.Boolean

VirtualResultList.IsSynchronized Property

Gets a value indicating whether access to the System.Collections.ICollection is synchronized (thread safe).

public bool IsSynchronized { get; }

Implements IsSynchronized

Property Value

System.Boolean

VirtualResultList.LastVisibleRange Property

Visible (first, last) indexes from the most recent RangesChanged — what position-preserving requeries prefetch before publishing.

public System.Nullable<(int First,int Last)> LastVisibleRange { get; }

Property Value

System.Nullable<<System.Int32,System.Int32>>

VirtualResultList.SyncRoot Property

Gets an object that can be used to synchronize access to the System.Collections.ICollection.

public object SyncRoot { get; }

Implements SyncRoot

Property Value

System.Object

VirtualResultList.this[int] Property

Hands out the stable ResultRow instance for index (creating the placeholder page on demand) — it never fetches, so realization stays cheap; arriving data fills these same instances in place. The setter is unsupported (read-only list).

public object? this[int index] { get; set; }

Parameters

index System.Int32

Zero-based row index; must be inside Count or it throws (an out-of-range slot is never fabricated into the LRU — ADR-0015).

Implements this[int]

Property Value

System.Object

Exceptions

System.ArgumentOutOfRangeException
index is negative or ≥ Count.

System.NotSupportedException
On set.

Methods

VirtualResultList.Add(object) Method

Adds an item to the System.Collections.IList.

public int Add(object? value);

Parameters

value System.Object

The object to add to the System.Collections.IList.

Implements Add(object)

Returns

System.Int32
The position into which the new element was inserted, or -1 to indicate that the item was not inserted into the collection.

Exceptions

System.NotSupportedException
The System.Collections.IList is read-only.
-or-
The System.Collections.IList has a fixed size.

VirtualResultList.Clear() Method

Removes all items from the System.Collections.IList.

public void Clear();

Implements Clear()

Exceptions

System.NotSupportedException
The System.Collections.IList is read-only.

VirtualResultList.Contains(object) Method

True only for a row whose slot still holds that exact instance. After a Reset the ListView re-locates its selected/focused item through Contains/IndexOf; vouching for a row of a previous result would send XAML to GetAt(staleIndex) and crash (ADR-0015), so membership is never faked.

public bool Contains(object? value);

Parameters

value System.Object

The candidate item to test for membership.

Implements Contains(object)

Returns

System.Boolean
True only when the current cache holds that exact instance in its slot.

VirtualResultList.CopyTo(Array, int) Method

Read surface stays landmine-free: copy what is cached, hand out transient placeholders for the rest (never cached — see GetEnumerator()).

public void CopyTo(System.Array array, int index);

Parameters

array System.Array

Destination array the rows are copied into.

index System.Int32

Start offset in array to copy from.

Implements CopyTo(Array, int)

VirtualResultList.Dispose() Method

Tear the list down at page end: cancel in-flight fetches, dispose the fetch token source, and dispose the owned result. Idempotent in effect — the _disposed guard makes any late fetch continuation bail before it touches the now-freed source.

public void Dispose();

Implements Dispose()

VirtualResultList.GetEnumerator() Method

Enumeration must not disturb the virtualization state: walking a million-row result through the cache would evict every realized viewport page (placeholder flash + refetch). Cached slots yield their live instances; everything else yields transient placeholders, which by the membership invariant safely answer "absent".

public System.Collections.IEnumerator GetEnumerator();

Implements GetEnumerator()

Returns

System.Collections.IEnumerator
An enumerator yielding cached instances and transient placeholders.

VirtualResultList.IndexOf(object) Method

Index of value, or -1, under the same membership invariant as Contains(object): a ResultRow matches only when its Index is inside Count AND the current page cache holds that exact instance in that slot. Rows from previous results or evicted pages answer absent.

public int IndexOf(object? value);

Parameters

value System.Object

The candidate item to locate.

Implements IndexOf(object)

Returns

System.Int32
The row's index, or -1 when it is not a current cached member.

VirtualResultList.Insert(int, object) Method

Inserts an item to the System.Collections.IList at the specified index.

public void Insert(int index, object? value);

Parameters

index System.Int32

The zero-based index at which value should be inserted.

value System.Object

The object to insert into the System.Collections.IList.

Implements Insert(int, object)

Exceptions

System.ArgumentOutOfRangeException
index is not a valid index in the System.Collections.IList.

System.NotSupportedException
The System.Collections.IList is read-only.
-or-
The System.Collections.IList has a fixed size.

System.NullReferenceException
value is null reference in the System.Collections.IList.

VirtualResultList.RangesChanged(ItemIndexRange, IReadOnlyList<ItemIndexRange>) Method

ListView callback whenever the realized viewport moves; records the range and kicks page fetches. Delegates to the WinRT-free FindMyFiles.Virtualization.VirtualResultList.NotifyVisibleRange(System.Int32,System.Int32) seam; trackedItems (the pinned/selected items) is unused — only the visible window drives prefetch.

public void RangesChanged(Microsoft.UI.Xaml.Data.ItemIndexRange visibleRange, System.Collections.Generic.IReadOnlyList<Microsoft.UI.Xaml.Data.ItemIndexRange> trackedItems);

Parameters

visibleRange Microsoft.UI.Xaml.Data.ItemIndexRange

First/last realized item indexes.

trackedItems System.Collections.Generic.IReadOnlyList<Microsoft.UI.Xaml.Data.ItemIndexRange>

Items the host asked to keep tracked; ignored.

Implements RangesChanged(ItemIndexRange, IReadOnlyList<ItemIndexRange>)

VirtualResultList.Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter) Method

Atomically replace the backing result: bump the epoch (in-flight fetches for the old result are cancelled, and their completions drop their data either way), drop the page cache, apply the pre-fetched seeds, then raise one Reset.

Contract: UI thread only (a cross-thread CollectionChanged crashes XAML); seeds must be pages of result within its count; ownership of result transfers to this list (it is disposed by the next Reassign/RefreshInPlace or by Dispose()).

public void Reassign(FindMyFiles.Engine.ISearchResult? result, System.Collections.Generic.IReadOnlyList<FindMyFiles.Virtualization.PageSeed> seeds, FindMyFiles.Highlighting.IHighlighter? highlighter=null);

Parameters

result ISearchResult

The new backing result whose ownership transfers to this list; null clears the list to empty.

seeds System.Collections.Generic.IReadOnlyList<PageSeed>

Pre-fetched pages of result used to fill the viewport before the Reset is raised.

highlighter IHighlighter

Compiled highlighter for the active query; null falls back to Empty.

VirtualResultList.RefreshInPlace(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter) Method

Swap to a result the engine verified to contain the same rows (Unchanged) without raising Reset: realized rows keep their instances and re-fill from the seeds (the MVVM setters only notify on actual value changes, so an idle USN requery repaints nothing). Cached pages are marked unloaded so later scrolling re-fetches from the new handle, and the visible range is re-ensured immediately for pages the seeds missed.

Contract: UI thread only; the engine must have verified result holds the same rows as the published one — same Count required, a mismatch falls back to a full seeded Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter) (Reset) rather than lying about membership; seeds must be pages of result; ownership of result transfers to this list. In-flight fetches of the previous epoch are cancelled here too.

public void RefreshInPlace(FindMyFiles.Engine.ISearchResult result, System.Collections.Generic.IReadOnlyList<FindMyFiles.Virtualization.PageSeed> seeds, FindMyFiles.Highlighting.IHighlighter? highlighter=null);

Parameters

result ISearchResult

The verified-identical result to swap in; ownership transfers to this list. A Count mismatch falls back to Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter).

seeds System.Collections.Generic.IReadOnlyList<PageSeed>

Pre-fetched pages of result that re-fill realized rows in place without a Reset.

highlighter IHighlighter

Compiled highlighter for the active query; null falls back to Empty.

VirtualResultList.Remove(object) Method

Removes the first occurrence of a specific object from the System.Collections.IList.

public void Remove(object? value);

Parameters

value System.Object

The object to remove from the System.Collections.IList.

Implements Remove(object)

Exceptions

System.NotSupportedException
The System.Collections.IList is read-only.
-or-
The System.Collections.IList has a fixed size.

VirtualResultList.RemoveAt(int) Method

Removes the System.Collections.IList item at the specified index.

public void RemoveAt(int index);

Parameters

index System.Int32

The zero-based index of the item to remove.

Implements RemoveAt(int)

Exceptions

System.ArgumentOutOfRangeException
index is not a valid index in the System.Collections.IList.

System.NotSupportedException
The System.Collections.IList is read-only.
-or-
The System.Collections.IList has a fixed size.

Events

VirtualResultList.BecameStale Event

Raised on the UI thread when a fetch reported staleness.

public event Action? BecameStale;

Event Type

System.Action

VirtualResultList.CollectionChanged Event

Raised (Reset) on the UI thread by Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter).

public event NotifyCollectionChangedEventHandler? CollectionChanged;

Implements CollectionChanged

Event Type

System.Collections.Specialized.NotifyCollectionChangedEventHandler

FindMyFiles

FindMyFiles.Virtualization Namespace

Classes
VirtualResultListRandom-access data virtualization for ListView: non-generic IList + INotifyCollectionChanged + IItemsRangeInfo (the only combination that works — microsoft-ui-xaml#1809, ADR-0015). The indexer hands out stable placeholder instances and never fetches; RangesChanged drives 64-row page fetches on a background task, and arriving data fills those same instances in place. The instance lives as long as the page: new query results arrive through Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter) (seeded pages + one Reset), never by swapping the ItemsSource (ADR-0015). An epoch counter makes fetches started against a previous result fall on the floor. Membership invariant — the WinRT IList adapter trusts these answers blindly: **never vouch for membership falsely.** A false "absent" merely re-realizes a container; a false "present" sends the ListView to GetAt(staleIndex) and dies deep inside XAML (ADR-0015). A row is a member iff its index is inside Count AND the current page cache holds that exact instance in that slot; rows from previous results, evicted pages or transient enumeration answer absent. Mutating entry points enforce the UI thread (always, not just in Debug).
Structs
PageSeedA page of already-fetched rows handed to Reassign(ISearchResult, IReadOnlyList<PageSeed>, IHighlighter), so the viewport is filled the instant a new result is published — never a placeholder flash.

FindMyFiles

FindMyFiles Namespace

Classes
AppApplication entry point and process-wide composition root. `OnLaunched` resolves the engine boundary (EngineClient) and stands up the single MainWindow. On fatal init failure it falls back to `FakeEngineClient` to avoid crashing silently.
MainPageWiring only: builds the ViewModel graph and connects view events to it. Imperative ListView work (viewport/selection restore, row actions) lives in ResultsViewportManager; the F12 panel chrome in PerfPanel; converters in UiConverters.
MainWindowThe application window: hosts the root Frame; app UI lives in MainPage.
ProgramProgram class