No admin required. No network calls. No executing discovered binaries. Just fast, local discovery with deterministic JSON/CSV/text output.
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 |
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.
Pre-built binaries are available for Windows x64 and ARM64. Choose your preferred method:
winget install AppLocate.AppLocateStable releases are automatically submitted to the Windows Package Manager Community Repository. Pre-release versions (alpha, beta, rc) are not published to WinGet.
Install-Module -Name AppLocate -Scope CurrentUserThe 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" -JsonDownload the latest release from GitHub Releases:
applocate-win-x64.zip– Windows x64applocate-win-arm64.zip– Windows ARM64
Extract and add to your PATH, or run directly.
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.exeMore 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 --evidenceOptions (implemented CLI surface):
Input:
<query> 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 <f> Minimum confidence threshold (0-1)
--limit <N> Max results after filtering
Sources:
--running Include running process enumeration
--pid <n> Target specific process id (implies --running)
Output Enrichment:
--evidence Include evidence dictionary
--evidence-keys <k1,k2> 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 <n> Max parallel source queries (default: min(CPU,16))
--timeout <sec> Per-source soft timeout (default: 5)
Diagnostics:
--verbose Verbose diagnostics (warnings)
--trace Per-source timing diagnostics (stderr)
--help Show help
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).
- 0: Results found, or help displayed (when run without arguments or with
--help) - 1: No matches found
- 2: Argument/validation error
Fields are append-only; enum values only extend at tail.
--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].
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) |
- 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.
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
dotnet restore
dotnet build
dotnet format --verify-no-changes # CI enforces formatting
dotnet testRun (may produce limited or no hits depending on environment):
dotnet run --project src/AppLocate.Cli -- vscode --jsonExit codes: 0 (results or help), 1 (no matches), 2 (argument error). See Usage for details.
pwsh ./build/publish.ps1 -X64 -Arm64 -Configuration ReleaseArtifacts land under ./artifacts/<rid>/.
Each published RID artifact now includes a CycloneDX SBOM file (sbom-<rid>.json) listing dependency components for supply-chain transparency.
Categories (representative):
- Core & Models:
AppHitserialization, 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
breakdownpresence and stability.
Run all tests:
dotnet test AppLocate.sln -c ReleaseFilter examples:
# Ranking tests only
dotnet test tests/AppLocate.Core.Tests --filter FullyQualifiedName~RankingTests
# Acceptance scenarios
dotnet test tests/AppLocate.Cli.Tests --filter FullyQualifiedName~AcceptanceSnapshots:
- Make intentional change.
- Run tests; inspect .received. files.
- Approve by replacing .verified files (commit rationale).
Synthetic acceptance tips:
- Override
LOCALAPPDATA,APPDATA,PATHto 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.yamlfor 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
--runningprocess capture scenario. - Performance regression timing harness.
For deterministic tests:
APPDATA,LOCALAPPDATA,PROGRAMDATAPATHAPPLOCATE_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 --jsonBacklog / Later:
- Code signing for releases
- Elevation strategy (
--elevate/--no-elevate) & privileged source gating
See .github/copilot-instructions.md for design/extension guidance. Keep AppHit schema backward compatible.
{ "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"} }