CaseKeeper Wiki
Installing, configuring, securing and supporting CaseKeeper — and everything a developer needs to build, understand and release it.
Reminder: CaseKeeper is a filing and organising tool. It does not give legal advice, and nothing it produces replaces advice from a solicitor, barrister or advice service.
Administrators
System requirements
| Component | Requirement |
|---|---|
| Windows | 64-bit Windows 10 version 1809 (build 17763) or newer, or Windows 11 |
| Architecture | x64 only |
| Disk | ≈ 250 MB for the program, plus the documents you import |
| Runtime | None — .NET 8 is bundled (self-contained) |
| Windows features | Uses the built-in Windows OCR (Windows.Media.Ocr) and PDF renderer (Windows.Data.Pdf). OCR needs an installed OCR language pack (English is present on English installs). |
Installing & silent deploy
The installer (CaseKeeper-Setup-v0.2.1.exe) is built with Inno Setup. By default it installs per-machine to C:\Program Files\DarkCipher0x Systems\CaseKeeper; users without admin rights can choose a per-user install from the elevation dialog.
# Silent per-machine install (run elevated) CaseKeeper-Setup-v0.2.1.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART # With a log file and a desktop shortcut CaseKeeper-Setup-v0.2.1.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /TASKS="desktopicon" /LOG="%TEMP%\CaseKeeper-install.log" # Custom install folder CaseKeeper-Setup-v0.2.1.exe /VERYSILENT /SUPPRESSMSGBOXES /DIR="D:\Apps\CaseKeeper" # Per-user install, no admin rights needed CaseKeeper-Setup-v0.2.1.exe /VERYSILENT /SUPPRESSMSGBOXES /CURRENTUSER
| Switch | Effect |
|---|---|
/SILENT · /VERYSILENT | Progress only · no UI at all |
/SUPPRESSMSGBOXES | Auto-answers message boxes |
/NORESTART | Never restart (CaseKeeper doesn't need one) |
/DIR="…" | Install folder |
/TASKS="desktopicon" | Create a desktop shortcut |
/CURRENTUSER · /ALLUSERS | Force per-user or per-machine |
/LOG="file" | Write a setup log |
The app doesn't auto-launch after a silent install (skipifsilent). If CaseKeeper is running during an upgrade, setup closes it automatically.
Upgrades & uninstall
- Run a newer installer over the old one — it recognises the existing install by AppId and upgrades in place.
- Upgrades never touch user data. Documents, notes, timeline, complaints and settings live outside the program folder.
# Silent uninstall (per-machine)
"%ProgramFiles%\DarkCipher0x Systems\CaseKeeper\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART
%LOCALAPPDATA%\CaseKeeper (or the custom library folder) and %APPDATA%\CaseKeeper — after confirming they have a backup.Data locations
| Path | Contents |
|---|---|
%LOCALAPPDATA%\CaseKeeper | Default library root |
…\casekeeper.db | SQLite database with FTS5 search index (SQLCipher-encrypted when password protection is on) |
…\Files\ | Copies of imported documents (AES-256-GCM encrypted when protected) |
…\Exports\ | Generated bundles, reports and chronologies |
…\vault.json | Wrapped key material — present only when password protection is on; useless without the password |
…\.casekeeper-in-use.json | "Library in use" marker while the app is open (see network libraries) |
%APPDATA%\CaseKeeper\library-location.json | Remembers a library moved or opened from a custom folder |
Library placement
The library location is resolved in this order:
CASEKEEPER_LIBRARYenvironment variable, if set — useful to force the library onto an encrypted drive via policy.- The folder saved in
library-location.json(set by Settings & Backup → Your library). - The default,
%LOCALAPPDATA%\CaseKeeper.
# Per-user, persistent
setx CASEKEEPER_LIBRARY "E:\SecureVault\CaseKeeper"
In the app:
- Move library copies everything, verifies every file byte-for-byte, checks the database opens, and only then deletes the originals. Any failure leaves the original untouched.
- Use a different library… opens an existing library elsewhere without copying anything; choosing an empty folder starts a new library there.
- If the library can't be reached at startup, CaseKeeper offers to retry or pick another folder — it never silently recreates an empty library in a folder you chose.
Network & shared libraries
A library can live on a NAS or SMB share, and several PCs can point at the same folder — one at a time.
- On network paths the database switches from WAL to the rollback journal (
journal_mode=DELETE), because WAL needs shared memory that SMB doesn't provide. - While open, CaseKeeper writes
.casekeeper-in-use.json(machine, user, process, timestamps), refreshed every minute. Another PC opening the same library is warned first. - A marker left by a crash or dropped connection goes stale after 3 minutes and stops counting.
Password protection
- Turn on under Settings & Backup → Password protection. Every document file and the entire database (notes, OCR text, search index, timeline, complaints) is encrypted at rest with AES-256.
- Documents are decrypted only in memory — viewing, searching, OCR and bundle building never write a readable copy to disk.
- Changing the password is instant (only the wrapping key changes). Protection can be turned off again.
- There is no recovery. A lost password means permanently unreadable data — there's no admin override or escrow. Keep backups.
Backup & restore
- Settings & Backup → Create backup writes one
.zipwith the database and every document, optionally AES-256 encrypted. - If the library is protected and the backup isn't, CaseKeeper warns and offers to add a password.
- Import either adds to the current library (duplicates skipped; safe to repeat) or replaces everything (disaster recovery / new PC).
- Factory reset sits behind a typed confirmation and an offer to back up first.
For scheduled protection, back up the library folder with your normal file-backup tooling while CaseKeeper is closed (an open database may be mid-write), or use the in-app backup.
Privacy & security
- No network use. CaseKeeper makes no internet connections: no account, telemetry, updates check or cloud OCR. Text recognition uses the engine built into Windows.
- Original files are never moved or modified — they're copied into the library and fingerprinted for duplicate detection.
- Sharing uses the Windows Share sheet, behind a confidentiality reminder.
- Library data is sensitive family-court material. Avoid cloud-synced folders unless that's intended, and apply appropriate retention.
Identifiers
| Item | Value |
|---|---|
| Inno Setup AppId | {B6E4A1D7-3F28-4C5B-9A07-5E1C8D42F093} |
| Uninstall registry key | HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{B6E4A1D7-3F28-4C5B-9A07-5E1C8D42F093}_is1 (HKCU for per-user installs) |
| Executable | CaseKeeper.exe |
| Default install folder | %ProgramFiles%\DarkCipher0x Systems\CaseKeeper |
| Publisher | darkcipher0x |
Detection rule: the uninstall key's DisplayVersion, or the file version of CaseKeeper.exe.
Code signing & Smart App Control
The installer and app are not code-signed today.
- Smart App Control is off on enterprise-managed devices, so it won't block managed deployments.
- For App Control for Business / AppLocker, allow by hash or path (
%ProgramFiles%\DarkCipher0x Systems\CaseKeeper\*); refresh hash rules each release. - Verify downloads with the published SHA-256, or build from source and sign with your own certificate (add a
SignToolline toinstaller\CaseKeeper.iss).
Home-user guidance: Managing Smart App Control.
Troubleshooting
| Problem | Solution |
|---|---|
| "Windows protected your PC" | More info → Run anyway (unsigned installer). See signing. |
| Installer refuses to run | Requires 64-bit Windows 10 1809+; check architecture and build |
| Scanned text isn't searchable | Install a Windows OCR language pack for the document's language (Settings → Time & language → Language) |
| "Library in use" warning | Another PC has it open. Close it there, or wait 3 minutes if that PC crashed |
| Library can't be found at startup | Reconnect the drive/NAS and choose Retry, or open a different folder |
| Database errors on a network share | Ensure only one PC uses it; keep the share connected; restore from backup if damaged |
| Forgotten password | Not recoverable. Restore from an unprotected or known-password backup |
| Data missing after reinstall | Check CASEKEEPER_LIBRARY and %APPDATA%\CaseKeeper\library-location.json point at the right folder |
Developers
Dev environment
| Tool | Why | Install |
|---|---|---|
| .NET 8 SDK | Builds the WPF app | winget install Microsoft.DotNet.SDK.8 |
| Inno Setup 6 | Builds the installer | winget install JRSoftware.InnoSetup |
| Git | Source control | winget install Git.Git |
| GitHub CLI | Optional — one-line releases | winget install GitHub.cli |
Get the code from the Source Code page.
Building
# Debug build and run cd CaseKeeper dotnet build dotnet run # Release installer → dist\CaseKeeper-Setup-v<ver>.exe cd .. powershell -ExecutionPolicy Bypass -File build-release.ps1
build-release.ps1 publishes self-contained for win-x64 into publish\, compiles installer\CaseKeeper.iss, and prints the installer path, size and SHA-256. It warns if CHANGELOG.md has no entry for the version being built. The installer's version is read from the built exe, so it can never disagree with the app.
Project layout
| Path | What's there |
|---|---|
CaseKeeper/Models/ | Documents, categories, parties, events, complaints |
CaseKeeper/Data/ | Database (SQLite + FTS5) and DefaultCategories (≈125 England & Wales family-court categories) |
CaseKeeper/Services/ | Library, OCR, PDF rendering, bundles, backup, vault, share, library lock |
CaseKeeper/Views/ | WPF windows and dialogs; MainWindow split into .Documents, .Records, .Bundle partials |
CaseKeeper/UI/ | Converters, natural sort, theme manager |
CaseKeeper/Themes/ | Light and dark palettes |
installer/ | Inno Setup script and pre-install notice |
.github/workflows/ | Tag-triggered release workflow |
build-release.ps1, RELEASING.md, CHANGELOG.md | Release tooling and notes |
Data model
A single SQLite file, casekeeper.db, in the library folder. WAL journal locally, rollback journal on network paths.
| Table | Purpose |
|---|---|
Categories | Built-in and custom categories, with bundle section |
Documents | Imported files: metadata, category, party, fingerprint, star |
PageText | OCR / extracted text per page |
PageNotes | User notes per page |
Parties | People and organisations in the case |
Events | Timeline / chronology |
Complaints, ComplaintDocuments | Complaint log with references, due dates and linked documents |
Settings | Key/value app settings |
SearchIndex | FTS5 virtual table over metadata, page text and notes (source: meta, page, notes, pagenote) |
User search input is converted into a safe FTS5 query (every word must appear, prefix match; quoted phrases match exactly).
Encryption design
password ──PBKDF2-HMAC-SHA256 (600,000 iters, random salt)──▶ wrapping key wrapping key ──unwraps──▶ random master key master key ──▶ AES-256-GCM for every document file (nonce 12 | tag 16 | ciphertext) master key ──▶ SQLCipher passphrase for casekeeper.db
- Implemented in
Services/Vault.cs; key material invault.json(salt, iterations, wrapped key, verifier). - Changing the password only re-wraps the master key — no document re-encryption.
- GCM authenticates as well as encrypts, so tampered files fail to decrypt rather than returning garbage.
- SQLCipher comes from
SQLitePCLRaw.bundle_e_sqlcipher.
Services
| Service | Responsibility |
|---|---|
LibraryService | Resolves the library root (env var → saved location → default), import, move, open-elsewhere |
LibraryLock | "In use" marker for shared libraries (1-minute refresh, 3-minute staleness) |
OcrService | Windows.Media.Ocr text recognition |
PdfRenderService | Windows.Data.Pdf page rendering for the viewer and OCR |
BundleService | PD 27A-style paginated bundles and summary reports (PDFsharp) |
BackupService | Zip backups (optional AES-256), add/replace import, merge |
Vault | Password protection and key management |
ShareService | Windows Share sheet integration |
Dependencies
| Package | Version | Use |
|---|---|---|
| Microsoft.Data.Sqlite | 8.0.10 | Database access |
| SQLitePCLRaw.bundle_e_sqlcipher | 2.1.10 | SQLCipher-enabled SQLite native library |
| PDFsharp-WPF | 6.1.1 | Bundle and report PDFs |
| SharpZipLib | 1.4.2 | Zip backups with AES |
Target framework net8.0-windows10.0.19041.0, minimum OS 10.0.17763.0, self-contained win-x64.
Release process
- Bump the version in
CaseKeeper/CaseKeeper.csproj—Version,AssemblyVersion,FileVersionandInformationalVersionmust agree. Patch for fixes, minor for features, 1.0.0 when stable. - Write patch notes at the top of
CHANGELOG.md(## v0.2.2 — date, then Added / Fixed). - Build:
powershell -ExecutionPolicy Bypass -File build-release.ps1. - Test the upgrade on a machine with the previous version and confirm documents survive.
- Commit and tag:
git tag v0.2.2,git push origin main --tags. - Publish the installer with its SHA-256 in the release notes.
installer\CaseKeeper.iss — it's what lets a new version upgrade an old one instead of installing alongside it.GitHub Actions
.github/workflows/release.yml runs on windows-latest whenever a v* tag is pushed (or manually):
- Sets up .NET 8 and installs Inno Setup via Chocolatey.
- Runs
build-release.ps1. - Fails if the tag doesn't match
<Version>in the project file. - Creates a draft GitHub release with
CHANGELOG.mdas the body and the installer attached.