Extract a per-user background host so indexing can later run outside the window.

Keep the GUI as the index writer for now; mutex, named pipe, and opt-in logon autostart prepare Explorer.Host.exe without two SQLite writers.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-24 17:10:49 +02:00
parent 9efb306979
commit 7c23bc2474
40 changed files with 1586 additions and 140 deletions

View File

@@ -427,3 +427,28 @@ public class FileRelationTests
Assert.Empty(await store.OperationProfiles.ListAsync());
}
}
public class IndexStoreLockTests
{
[Fact]
public async Task Second_writer_on_same_path_is_rejected()
{
var path = Path.Combine(Path.GetTempPath(), "ew-tests", Guid.NewGuid().ToString("N"), "index.db");
await using var first = new SqliteIndexStore(path, NullLogger<SqliteIndexStore>.Instance);
await first.OpenAsync();
var second = new SqliteIndexStore(path, NullLogger<SqliteIndexStore>.Instance);
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => second.OpenAsync());
Assert.Contains("already in use", ex.Message, StringComparison.OrdinalIgnoreCase);
await first.DisposeAsync();
await second.OpenAsync();
await second.DisposeAsync();
}
[Fact]
public void Mutex_name_is_stable_for_the_same_path()
{
var path = @"C:\Users\me\AppData\Local\ExplorerWorkbench\index.db";
Assert.Equal(IndexStoreLock.MutexNameFor(path), IndexStoreLock.MutexNameFor(path));
Assert.StartsWith(@"Local\ExplorerWorkbench-Index-", IndexStoreLock.MutexNameFor(path));
}
}