Skip to content

Shared Abstractions ​

Models and support contracts used across the interfaces in the other SDK pages.

ISearchResult ​

The read-only view of a result every plugin interface operates on — plugins never get a mutable result object, only this:

csharp
interface ISearchResult
{
    string Name { get; }
    string FullPath { get; }
    string ContextDirectory { get; }
    bool IsDir { get; }
    bool IsApplication { get; }
    FileMetadata Metadata { get; }
    bool[]? GetHighlightMask(string text, string query);
}

Metadata carries Size/Created/Modified/Accessed for every result the host's own file index produced — reading it is free (no disk I/O or IPC), unlike FileMetadataService.GetMetadataAsync (see Host Services), which is only worth calling for a path that isn't already one of your current results.

FileMetadata ​

csharp
readonly record struct FileMetadata(long Size, DateTime Created, DateTime Modified, DateTime Accessed);

Local time. default (every field zero/DateTime.MinValue) means "not available" — a result that isn't backed by the file index (e.g. one another plugin produced). Check Metadata.Modified != default to tell that apart from a real, legitimately zero-byte file, whose Size is genuinely 0 but whose timestamps are still real.

IPluginSearchWindow ​

The minimal window-control surface passed to ISearchResultAction.Execute and similar callbacks — deliberately small; plugins act on results through this, not by holding onto the real window:

csharp
interface IPluginSearchWindow
{
    void LocateInExplorerExternal(string path);
    void OpenFileOrFolderExternal(string path);
    void OpenFileOrFolderAsAdminExternal(string path);
    void HideWindow();
}

IConfigurable ​

Implement this alongside IPlugin to get a configuration UI generated automatically under Settings → Plugins → Configure — no custom WPF required for simple cases.

csharp
interface IConfigurable
{
    PluginConfigSchema GetConfigSchema();
}

PluginConfigSchema is a flat Fields: List<PluginConfigField>. Each PluginConfigField has a Key, optional GroupKey/LabelKey/DescriptionKey (translation keys, resolved through your own ITranslationProvider if you have one), a FieldType, a DefaultValue, and — depending on the type — Choices, nested SubFields, or RequireModifier (Hotkey fields only, rejects an unmodified single key).

Set RequireNonEmpty on a field (typically a Text trigger keyword) to fall back to DefaultValue instead of persisting an empty/whitespace value on save — otherwise a user clearing a keyword field would silently make whatever depends on it unreachable rather than reverting to a sane default.

ConfigFieldType covers: Boolean, Text, Integer, Choice, Array, Object, Group, StringList, Hotkey, FilePath, FolderPath. See CoreExtensions for a real schema using nested groups and StringList.

Registries ​

ActivePathCollectorRegistry, FileDialogAdapterRegistry, and InlineSearchAdapterRegistry are how the host collects every loaded implementation of the corresponding system adapter interfaces into one place at runtime. Plugin authors don't normally interact with these directly — implementing the interface is enough for the host to discover and register your plugin automatically.