applocate

Find any app on Windows — instantly.
Ever needed to locate where an application is actually installed? Or find its config files for backup, migration, or troubleshooting? AppLocate searches registry keys, Start Menu shortcuts, running processes, package managers, and more. It then ranks results by confidence and returns structured output you can script against.
Inspired by Linux's locate—but purpose-built for Windows application discovery.
No admin required. No network calls. No executing discovered binaries. Just fast, local discovery with deterministic JSON/CSV/text output.
Features
Unlike single-purpose tools that check one location, AppLocate casts a wide net—querying the registry, Start Menu shortcuts, running processes, PATH directories, Windows services, MSIX packages, and popular package managers like Scoop, Chocolatey, and WinGet—all in parallel. Results from every source are merged, deduplicated, and ranked by confidence so you get a single authoritative answer instead of hunting through scattered system locations. Need to find where that mystery node.exe is actually running from? AppLocate sees it live and traces it back to its install root.
Here's what's currently implemented:
| Area | Status | Notes |
|---|
| Registry uninstall | Yes | HKLM/HKCU + WOW6432Node |
| App Paths | Yes | HKLM/HKCU exe registration |
| Start Menu shortcuts | Yes | User + common .lnk resolution |
| Processes | Yes | Running process discovery |
| PATH search | Yes | PATH directories + where.exe |
| MSIX / Store | Yes | Appx package enumeration |
| Services & Tasks | Yes | Service + scheduled task binaries |
| Heuristic FS scan | Yes | Bounded depth/time scan |
| Scoop | Yes | User/global apps + manifests |
| Chocolatey | Yes | Machine-scope packages |
| WinGet | Yes | Package provenance |
| Ranking | Yes | Token matching, evidence synergy, penalties |
| Config/Data rules | Yes | 147-app YAML rule pack |
| Existence filtering | Yes | Filters non-existent paths |
| Evidence emission | Yes | Via --evidence flag |
| Single-file publish | Yes | Win x64/ARM64 + SBOM |
| Plugin system | Pending | Data-only aliases/rules |
How It Works
AppLocate runs all discovery sources in parallel, streams results through a ranking pipeline, and collapses to the best hits per type. For a detailed architecture walkthrough—including source APIs, scoring components, and output flow—see the Dataflow Diagram.
Installation
Pre-built binaries are available for Windows x64 and ARM64. Choose your preferred method:
WinGet (Windows Package Manager)

winget install AppLocate.AppLocate
Stable releases are automatically submitted to the Windows Package Manager Community Repository. Pre-release versions (alpha, beta, rc) are not published to WinGet.
PowerShell Gallery

Install-Module -Name AppLocate -Scope CurrentUser
The module bundles applocate.exe and exposes PowerShell-friendly functions:
# Search and get parsed objects
Find-App "chrome" | Select-Object path, confidence
# Get JSON output with filtering
Get-AppLocateJson -Query "vscode" -ConfidenceMin 0.7 -Limit 3
# Raw CLI invocation with any flags
Invoke-AppLocate "git" "--all" "--evidence" -Json
Manual Download
Download the latest release from GitHub Releases:
applocate-win-x64.zip – Windows x64
applocate-win-arm64.zip – Windows ARM64
Extract and add to your PATH, or run directly.
Usage
PS> applocate curl
[0.72] Exe C:\Program Files\Git\mingw64\bin\curl.exe
[0.69] Exe C:\Windows\System32\curl.exe
[0.62] Exe C:\Users\user\AppData\Local\...\curl-x.xx.x\bin\curl.exe
More examples:
# Find VS Code installation and config paths
applocate code
# Get JSON output for scripting (e.g., backup settings)
applocate "visual studio" --json --config
# Find where a running process lives
applocate node --running --exe
# Locate Git install directory for PATH debugging
applocate git --install-dir --json | ConvertFrom-Json | Select-Object -Expand path
# Find all Chrome data (profiles, cache) with evidence of where it came from
applocate chrome --data --all --evidence
Options (implemented CLI surface):
Input:
App name / alias / partial tokens
-- Treat following tokens as literal query
Output Format:
--json | --csv | --text Output format (default: text)
--no-color Disable ANSI color in text output
Filtering:
--user | --machine Scope filters
--exe | --install-dir | --config | --data Type filters (combinable)
--all Return ALL hits (no per-type collapsing)
--confidence-min Minimum confidence threshold (0-1)
--limit Max results after filtering
Sources:
--running Include running process enumeration
--pid Target specific process id (implies --running)
Output Enrichment:
--evidence Include evidence dictionary
--evidence-keys Only specified evidence keys (implies --evidence)
--score-breakdown Show scoring component contributions per result
--package-source Show package type & source list in text/CSV
Performance:
--threads Max parallel source queries (default: min(CPU,16))
--timeout Per-source soft timeout (default: 5)
Diagnostics:
--verbose Verbose diagnostics (warnings)
--trace Per-source timing diagnostics (stderr)
--help Show help
Default Behavior
Without --all, results are intelligently collapsed:
exe: Up to 3 high-confidence executables from distinct directories, each paired with its install directory. Variant siblings (e.g., multiple installed versions) may also surface.
config / data: Single best hit per type, tie-broken by scope (machine > user) then evidence richness.
Use --all to see every distinct hit (useful for debugging ranking or alternate install roots).
Exit Codes
- 0: Results found, or help displayed (when run without arguments or with
--help)
- 1: No matches found
- 2: Argument/validation error
Output and Evidence
Minimal JSON Hit Example
{
"type": 1,
"scope": 0,
"path": "C:/Users/u/AppData/Local/Programs/Code/Code.exe",
"version": null,
"packageType": 3,
"source": ["StartMenuShortcutSource","RegistryUninstallSource"],
"confidence": 0.92,
"evidence": {"Shortcut":"...Code.lnk","DisplayName":"Visual Studio Code"}
}
Fields are append-only; enum values only extend at tail.
Confidence
--evidence adds key/value provenance. Examples:
{"Shortcut":"C:/Users/u/.../Code.lnk"}
{"ProcessId":"1234","ExeName":"Code.exe"}
{"DisplayName":"Google Chrome","HasInstallLocation":"true"}
Confidence heuristic (phase 1): token & fuzzy coverage, exact exe/dir boosts, alias equivalence, evidence synergy (shortcut+process), multi-source diminishing returns, penalties (temp/broken). Scores ∈ [0,1].
Score Breakdown
Use --score-breakdown to see how each result's confidence score was computed:
[0.86] Exe C:\Users\user\AppData\Local\Programs\Microsoft VS Code\Code.exe
breakdown: base=0.08 name=0.35 token=0.27 alias=0 evidence=0 multi=0.17 penalties=0 total=0.86
| Bucket | Description |
|---|
base | Type baseline (Exe starts higher than InstallDir) |
name | Filename match quality (exact, partial, fuzzy Levenshtein) |
token | Query token coverage + contiguous span bonus |
alias | Built-in alias match (e.g., "code" → "vscode") |
evidence | Registry/shortcut/process evidence boosts |
multi | Multi-source corroboration (diminishing returns) |
penalties | Path quality deductions (temp, cache, generic dirs) |
Security & Privacy
- No network or telemetry
- Does not execute discovered binaries
- Least privilege by default (no admin required for core features)
- Read-only posture – only queries registry, file system, and package managers
- Output sanitization to prevent terminal injection
For enterprise deployments or security-conscious environments, see SECURITY_REVIEW.md for a detailed threat model, attack surface analysis, and hardening recommendations.
Project Layout
src/AppLocate.Core # Domain models, abstractions, sources, ranking & rules engine
├─ Abstractions/ # Interfaces (ISource, ISourceRegistry, IAmbientServices)
├─ Models/ # AppHit, ScoreBreakdown, PathUtils, EvidenceKeys
├─ Sources/ # All discovery sources (Registry, AppPaths, StartMenu, Process, PATH, MSIX, Services, HeuristicFS, Scoop, Chocolatey, Winget)
├─ Ranking/ # Scoring logic, alias canonicalization
└─ Rules/ # YAML rule engine for config/data expansion
src/AppLocate.Cli # CLI entry point with System.CommandLine + manual parsing
tests/AppLocate.Core.Tests # Unit tests for ranking, rules, sources
tests/AppLocate.Cli.Tests # CLI integration, acceptance, snapshot tests
rules/apps.default.yaml # Config/data rule pack (147 apps)
build/publish.ps1 # Single-file publish script (win-x64 / win-arm64)
assets/ # Logo (SVG, ICO)
AppLocate.psm1 # PowerShell module wrapper
Build
Quick Start
dotnet restore
dotnet build
dotnet format --verify-no-changes # CI enforces formatting
dotnet test
Run (may produce limited or no hits depending on environment):
dotnet run --project src/AppLocate.Cli -- vscode --json
Exit codes: 0 (results or help), 1 (no matches), 2 (argument error). See Usage for details.
Publish Single-File
pwsh ./build/publish.ps1 -X64 -Arm64 -Configuration Release
Artifacts land under ./artifacts//.
Each published RID artifact now includes a CycloneDX SBOM file (sbom-.json) listing dependency components for supply-chain transparency.
Tests
Categories (representative):
- Core & Models:
AppHit serialization, deterministic JSON shape.
- Ranking: tokenization, alias equivalence vs evidence alias, fuzzy distance, boosts/penalties, Steam auxiliary demotion, span/coverage.
- CLI Deterministic: argument parsing/validation, exit codes, type filters,
--package-source, selective --evidence-keys.
- Snapshot (Verify): golden projections with volatile fields stripped.
- Rules Parsing: YAML subset correctness and expansion.
- Acceptance (synthetic): VS Code (code/vscode), portable app, MSIX fake provider; PATH alias discovery (oh‑my‑posh), running process (
--running).
- Score breakdown: JSON
breakdown presence and stability.
Run all tests:
dotnet test AppLocate.sln -c Release
Filter examples:
# Ranking tests only
dotnet test tests/AppLocate.Core.Tests --filter FullyQualifiedName~RankingTests
# Acceptance scenarios
dotnet test tests/AppLocate.Cli.Tests --filter FullyQualifiedName~Acceptance
Snapshots:
- Make intentional change.
- Run tests; inspect .received. files.
- Approve by replacing .verified files (commit rationale).
Synthetic acceptance tips:
- Override
LOCALAPPDATA, APPDATA, PATH to point to temp fixtures.
- Inject MSIX packages via
APPLOCATE_MSIX_FAKE (JSON array) for deterministic enumeration.
- Inject Scoop apps via
APPLOCATE_SCOOP_FAKE (JSON object with roots/apps) for deterministic enumeration.
- Inject Chocolatey packages via
APPLOCATE_CHOCO_FAKE (JSON object with directories/metadata) for deterministic enumeration.
- Use .lnk shortcuts to exercise Start Menu + evidence synergy.
Adding acceptance scenarios:
- Build temp layout & dummy exe(s).
- Optionally add rule entries in
rules/apps.default.yaml for config/data.
- Invoke CLI and assert required hit types & confidence ≥0.8.
- Avoid dependence on real machine installs.
Contributor guidelines:
- Keep tests deterministic; no network or real software dependencies.
- Strip/ignore volatile data in snapshots (timestamps, absolute temp roots).
- Prefer suffix or logical assertions over full absolute path equality.
- Document ranking expectation changes in commits.
- Use
[Fact(Skip=..)] sparingly with backlog reference.
Planned test expansions:
- Rule pack growth (≥50 apps) with fixtures.
- Live
--running process capture scenario.
- Performance regression timing harness.
Advanced
Environment Overrides
For deterministic tests:
APPDATA, LOCALAPPDATA, PROGRAMDATA
PATH
APPLOCATE_MSIX_FAKE (JSON array of fake MSIX packages)
APPLOCATE_SCOOP_FAKE (JSON object with roots and apps)
APPLOCATE_CHOCO_FAKE (JSON object with directories and package metadata)
Example:
$env:APPLOCATE_MSIX_FAKE='[{"name":"SampleApp","family":"Sample.App_123","install":"C:/tmp/sample","version":"1.0.0.0"}]'
applocate sample --json
Roadmap
Backlog / Later:
Contributing
See .github/copilot-instructions.md for design/extension guidance. Keep AppHit schema backward compatible.