Squirrel/Squirrel.Windows
An installation and update framework for Windows desktop apps
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓26+ active contributors
- ✓Distributed ownership (top contributor 40% of recent commits)
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Stale — last commit 2y ago
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/squirrel/squirrel.windows)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/squirrel/squirrel.windows on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Squirrel/Squirrel.Windows
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Squirrel/Squirrel.Windows shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 26+ active contributors
- Distributed ownership (top contributor 40% of recent commits)
- MIT licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Squirrel/Squirrel.Windows
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Squirrel/Squirrel.Windows.
What it runs against: a local clone of Squirrel/Squirrel.Windows — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Squirrel/Squirrel.Windows | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch develop exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 684 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Squirrel/Squirrel.Windows. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Squirrel/Squirrel.Windows.git
# cd Squirrel.Windows
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Squirrel/Squirrel.Windows and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Squirrel/Squirrel.Windows(\\.git)?\\b" \\
&& ok "origin remote is Squirrel/Squirrel.Windows" \\
|| miss "origin remote is not Squirrel/Squirrel.Windows (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
&& ok "default branch develop exists" \\
|| miss "default branch develop no longer exists"
# 4. Critical files exist
test -f "src/Setup/winmain.cpp" \\
&& ok "src/Setup/winmain.cpp" \\
|| miss "missing critical file: src/Setup/winmain.cpp"
test -f "Squirrel.sln" \\
&& ok "Squirrel.sln" \\
|| miss "missing critical file: Squirrel.sln"
test -f "src/Setup/Setup.vcxproj" \\
&& ok "src/Setup/Setup.vcxproj" \\
|| miss "missing critical file: src/Setup/Setup.vcxproj"
test -f "docs/using/update-process.md" \\
&& ok "docs/using/update-process.md" \\
|| miss "missing critical file: docs/using/update-process.md"
test -f "docs/getting-started/1-integrating.md" \\
&& ok "docs/getting-started/1-integrating.md" \\
|| miss "missing critical file: docs/getting-started/1-integrating.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 684 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~654d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Squirrel/Squirrel.Windows"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Squirrel.Windows is an installation and update framework for Windows desktop applications that packages apps as NuGet files and delivers silent, background updates without UAC prompts or reboots. It provides both a C#/.NET library and command-line tools to handle the complete application lifecycle—packaging, distributing, installing, and updating—mimicking Chrome's seamless update model for Windows desktop apps. Monolithic solution structure: Squirrel.sln is the main entry point; the top-level directory contains build scripts (devbuild.cmd), NuGet tooling (.nuget/), and documentation (docs/). The docs/ tree is comprehensive, split into getting-started/, using/, and contributing/ guides. Source code directories are not visible in the top 60 files, suggesting they sit deeper in the project hierarchy (likely src/ or under solution folders).
👥Who it's for
Windows desktop application developers (C#, C++, or any language) who want to implement Chrome-like installation and auto-update capabilities without managing complex installer infrastructure. Both enterprise software makers and indie developers use it to reduce deployment friction.
🌱Maturity & risk
Production-ready but actively seeking maintainers. The project has a substantial codebase (1.67M lines of C++, 799K of C#), established CI/CD via Azure Pipelines (visible in .github/workflows/build.yml), and comprehensive documentation. However, a recent GitHub issue (#1470) explicitly calls for contributors, signaling maintenance pressure on the core team.
Moderate maintenance risk: the project is actively seeking help (see issue #1470), suggesting the maintainer pool is thin. The mixed-language codebase (C++, C#, Batchfile) raises complexity for new contributors. No visible test suite metadata in the top-level structure, which is concerning for an installer framework where failures have high user impact. Dependency on .NET Framework and NuGet ecosystem means Windows-only scope.
Active areas of work
The project is in a seeking-contributors phase per issue #1470. CI/CD is configured (.github/workflows/build.yml), indicating ongoing build validation. Documentation is actively maintained with guides for building (docs/contributing/building-squirrel.md), integrating, packaging, and debugging. No specific sprint or milestone data is visible, but the presence of issue templates and organized workflows suggests steady-state operations rather than active feature development.
🚀Get running
git clone --recursive https://github.com/squirrel/squirrel.windows
cd squirrel.windows
devbuild.cmd
The --recursive flag pulls submodules (configured in .gitmodules). The devbuild.cmd batch script orchestrates the full build (see README).
Daily commands:
From the repository root, run devbuild.cmd (Windows batch script). This compiles the solution and produces the Squirrel toolchain. No dev server in the traditional sense—this is a build tool and library, not a web application. To integrate Squirrel into an app, developers use the compiled NuGet package or reference it directly.
🗺️Map of the codebase
src/Setup/winmain.cpp— Entry point for the native C++ Setup executable that handles installation, updates, and machine-wide installs—all developers must understand the bootstrap flow.Squirrel.sln— Root solution file defining the entire project structure and all dependencies—required starting point for building and understanding module organization.src/Setup/Setup.vcxproj— C++ project configuration that compiles the core Setup binary used for all installation and update operations across the framework.docs/using/update-process.md— Documents the critical update flow and delta-package mechanics that define how Squirrel delivers updates to end-user applications.docs/getting-started/1-integrating.md— Integration guide showing how applications consume Squirrel's APIs and events—essential for understanding the public contract.src/Setup/UpdateRunner.h— Core header defining the update execution engine that orchestrates all update operations and state transitions.README.md— Project overview explaining Squirrel's mission as a Chrome-like auto-update framework for Windows desktop apps.
🛠️How to make changes
Add a new Update Operation Handler
- Define the operation enum in Setup.h alongside existing operations (INSTALL, UPDATE, UNINSTALL, etc.) (
src/Setup/Setup.h) - Add case handler in UpdateRunner::Execute() in UpdateRunner.cpp to dispatch the operation (
src/Setup/UpdateRunner.cpp) - Implement the operation logic (file operations, registry changes, etc.) in the corresponding handler (
src/Setup/UpdateRunner.cpp) - Update documentation in docs/using/install-process.md or docs/using/update-process.md with new operation details (
docs/using/install-process.md)
Add Support for a New Package Distribution Channel
- Create new documentation file in docs/using/ (e.g., amazon-s3.md, github.md serve as templates) (
docs/using/amazon-s3.md) - Document the release naming and versioning convention in docs/using/naming.md (
docs/using/naming.md) - Add examples showing how UpdateManager connects to your channel in docs/using/update-manager.md (
docs/using/update-manager.md) - Update the integration guide (docs/getting-started/3-distributing.md) with channel-specific steps (
docs/getting-started/3-distributing.md)
Extend Setup.exe Manifest & Resources
- Modify Setup.rc to add or update version info, icons, and string resources (
src/Setup/Setup.rc) - Update compat.manifest to enable new Windows compatibility flags (e.g., high-DPI, UAC levels) (
src/Setup/compat.manifest) - Add resource constants to resource.h if new string IDs or icons are needed (
src/Setup/resource.h) - Rebuild Setup.vcxproj to regenerate the Setup.exe binary with new resources (
src/Setup/Setup.vcxproj)
Add a New Integration Example or Getting-Started Guide
- Create a new markdown file in docs/getting-started/ (follow naming convention: N-topic.md) (
docs/getting-started/0-overview.md) - Reference the new guide from docs/getting-started/0-overview.md to include it in the learning path (
docs/getting-started/0-overview.md) - Add sample code or example project files in docs/getting-started/example/ if applicable (
docs/getting-started/example/MyApp.zip) - Link from README.md or main docs index (docs/readme.md) to promote the new guide (
README.md)
🔧Why these technologies
- C++ (Win32 + WTL) — Setup.exe must run before any managed runtime (.NET) is available; Win32 is the only universal, boot-time-safe option. WTL provides type-safe GUI abstractions without bloat.
- NuGet Package Format — Reuses existing .nupkg ecosystem and tooling; allows developers to version and distribute releases using familiar MSBuild/dotnet workflows.
- Delta Compression & Binary Patching — Reduces update payload from 50–200MB to 5–50MB; critical for consumer adoption and bandwidth efficiency.
- Windows Registry & AppData Directories — Per-user and machine-wide install metadata; shortcuts and uninstaller registration must follow Windows conventions for discoverability.
- Managed APIs (.NET/C#) — UpdateManager and integration layers run in-process with host applications (typically C# or .NET); easier to invoke from higher-level code.
⚖️Trade-offs already made
-
Separate managed (UpdateManager) and native (Setup.exe) layers
- Why: Setup.exe must run at boot-time and during admin elevation before managed runtime initialization.
- Consequence: Adds complexity to inter-process communication and state synchronization; requires careful versioning of the Setup binary.
-
Delta-based updates via binary patching rather than full-file replacement
- Why: Drastically reduces bandwidth and install time (50–100× compression).
- Consequence: Patch generation is compute-intensive; broken deltas can corrupt installations; fallback to full-package must always be available.
-
Automatic elevation to admin on machine-wide installs
- Why: Allows single-click install to Program Files and system-wide shortcuts.
- Consequence: UAC prom
🪤Traps & gotchas
- Recursive clone required:
git clone --recursiveis mandatory; missing it will leave submodules empty and cause build failures. 2. Windows-only build:devbuild.cmdis a batch script; there is no cross-platform build system visible (no Makefile, no shell script). Linux/Mac developers cannot build this directly. 3. NuGet.exe in repo: The project vendors.nuget/NuGet.exerather than relying on a system NuGet, suggesting strict version control on the package manager. 4. Mixed C++/C# requires dual tooling: Contributing requires both Visual Studio (or Rider) for C# and a C++ compiler (MSVC likely). 5. No visible unit test directory in top 60 files: Installer frameworks are safety-critical, but test structure is not immediately obvious; ask maintainers where test projects live.
🏗️Architecture
💡Concepts to learn
- Delta Update Packages — Squirrel's signature optimization—generating minimal diffs between versions to reduce bandwidth for updates. The
docs/using/delta-packages.mdfile is dedicated to this; critical for understanding performance claims. - NuGet Package Specification (NuSpec) — Squirrel packages applications as NuGet
.nupkgfiles; understanding NuSpec format and metadata is essential for packaging and distributing apps via Squirrel. - Silent Installation (No UAC/Reboot) — A core design goal: Squirrel installs apps without UAC prompts or system reboots. This requires native code (C++) to manipulate files/registry in low-level ways; understanding the constraints is vital for contributing.
- Background Update Checking — Updates run asynchronously without interrupting the user; the framework must coordinate file locks, process restart, and rollback. See
docs/getting-started/5-updating.md. - Application Signing & Certificates — Squirrel can verify update packages using code signing certificates (
docs/using/application-signing.md); essential for security and distribution validation. - Multi-Channel Distribution (Dev/Beta/Release) — Like Chrome, Squirrel supports update channels; users can opt into early builds. This requires server-side manifest logic and client-side channel selection.
- Embedded Native C++ in .NET Interop — The C++ core (1.67M LOC) must interop with the C# API via P/Invoke or COM; critical knowledge for contributors touching both layers.
🔗Related repos
electron/electron— Electron uses Squirrel.Windows (or derivatives) for auto-updates on Windows; understanding how a major framework integrates Squirrel reveals best practicesNuGet/Home— Squirrel is built on NuGet packages; following NuGet development helps understand the packaging layer and spec evolutionSquirrel/Squirrel.Mac— Sister project providing macOS equivalent to Squirrel.Windows; valuable for understanding the architecture patterns and cross-platform philosophycuiliang/ClickOnceToWinget— Alternative Windows app distribution model; comparison illuminates why Squirrel chose the NuGet-based approach over ClickOnce or WinGetmicrosoft/winget-cli— Modern Windows package manager; understanding WinGet helps contextualize Squirrel as a legacy (but still widely used) alternative for self-managed distribution
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for FxHelper.cpp native C++ helper functions
The repo contains src/Setup/FxHelper.cpp but no visible test coverage in the file structure. Given Squirrel's support for native C++ applications, testing the Framework helper utilities is critical for reliability. This is a high-value contribution that directly impacts application compatibility.
- [ ] Create src/Setup.Tests/ directory structure for C++ unit tests (using Google Test or similar)
- [ ] Write tests for FxHelper.cpp covering Framework detection, version checking, and runtime initialization
- [ ] Integrate C++ test runner into .github/workflows/build.yml CI pipeline
- [ ] Document test execution in docs/contributing/building-squirrel.md
Complete missing update-process.md delta packages integration section
docs/using/delta-packages.md and docs/using/update-process.md exist, but the update process documentation appears incomplete (README.md snippet cuts off). Delta packages are a core performance feature but lack integration guidance. Contributors should bridge these docs with specific code examples and the UpdateManager API.
- [ ] Review docs/using/update-process.md and identify missing delta package workflow steps
- [ ] Add concrete code examples in docs/using/update-process.md showing how UpdateManager integrates with delta package logic
- [ ] Cross-reference docs/using/delta-packages.md with the actual UpdateManager implementation in src/
- [ ] Add a complete end-to-end example in docs/getting-started/5-updating.md demonstrating delta package usage
Add GitHub Actions workflow for NuGet package publishing and signing verification
The repo has .github/workflows/build.yml but lacks automated validation for the critical path: NuGet package creation (docs/using/octopack.md) and code signing (docs/using/application-signing.md). New CI workflow would catch packaging regressions early and validate signing configurations match documentation.
- [ ] Create .github/workflows/package-verification.yml workflow
- [ ] Add steps to build NuGet packages using the documented OctoPack integration (docs/using/octopack.md)
- [ ] Add verification steps for package metadata and signing certificates per docs/using/application-signing.md
- [ ] Test against the example project in docs/getting-started/example/MyApp.zip
- [ ] Document the new workflow in docs/contributing/building-squirrel.md
🌿Good first issues
- Add unit tests for the C# API surface in
docs/using/custom-squirrel-events.md—document the event signatures and write basic integration tests to validate event firing during install/update cycles. - Expand
docs/using/debugging-installs.mdanddocs/using/debugging-updates.mdwith concrete examples and screenshots showing how to inspect update manifests and logs; these docs reference images indocs/using/images/but lack step-by-step walkthroughs. - Create a CI/CD integration guide: add a document under
docs/using/showing how to automate Squirrel packaging and publishing in Azure DevOps or GitHub Actions (currently.github/workflows/build.ymlexists but is not exposed in user docs).
⭐Top contributors
Click to expand
Top contributors
- @anaisbetts — 40 commits
- @robmen — 16 commits
- @AArnott — 7 commits
- @GeertvanHorrik — 6 commits
- @bitdisaster — 4 commits
📝Recent commits
Click to expand
Recent commits
51f5e2c— Merge branch 'master' into develop (anaisbetts)35b1a0b— just make the ding dang buffer bigger (anaisbetts)aaec357— Merge branch 'pr/1868' into develop (anaisbetts)1bc2a6a— Allow running as admin in Wine (Forest)5e44cb4— Merge pull request #1862 from q837477816/develop (anaisbetts)f900ac4— Fix weird indentation (DamonYuRC)24e770f— fix race condition via delete file directly (DamonYuRC)0a8a9ee— Fix the app can not restart after an unexpected exit during the upgrade (DamonYuRC)63e2a4b— Fix app can not restart after an unexpected exit during the apply releases (DamonYu6)b26d124— Merge pull request #1835 from tbertels/patch-1 (anaisbetts)
🔒Security observations
Squirrel.Windows is a privileged installation framework with moderate security posture. Key risks center on native code execution in installation/update mechanisms, privilege escalation vectors in machine-wide installers, and potential integrity verification gaps for update packages. The codebase lacks visible implementation of code signing, integrity verification, and secure configuration management. Recommendations include implementing cryptographic verification for all update packages, enforcing code signing with certificate pinning, hardening the native Setup module with input validation, and establishing
- High · Native Code Execution in Setup Module —
src/Setup/unzip.cpp, src/Setup/unzip.h, src/Setup/UpdateRunner.cpp. The Setup module (C++ code in src/Setup/) handles unzipping and extraction operations (unzip.cpp/h). Native code responsible for file extraction and execution during installation phases presents risks for arbitrary code execution if input validation is insufficient. The module appears to process update.zip files which could be vectors for malicious payloads. Fix: Implement strict validation of ZIP file contents before extraction, verify digital signatures of update packages, implement sandboxing for extraction operations, and perform comprehensive input validation on all extracted files. - High · Potential Privilege Escalation in Machine-Wide Installer —
src/Setup/MachineInstaller.cpp, src/Setup/MachineInstaller.h. The MachineInstaller component (src/Setup/MachineInstaller.cpp/h) handles machine-wide installations which typically require elevated privileges. Insufficient validation in privilege handling or insecure elevation techniques could allow privilege escalation attacks. Fix: Implement principle of least privilege, validate all operations before privilege elevation, use secure APIs for elevation (ShellExecuteEx with runas), implement audit logging for elevated operations, and verify manifest compatibility settings. - Medium · Unsigned Executable Resources —
src/Setup/Setup.vcxproj, src/Setup/compat.manifest. Setup.exe and related executable resources (Setup.ico, small.ico, manifest files) are present but code signing status cannot be verified from static analysis. Unsigned executables increase risk of tampering and make it difficult for users to verify authenticity. Fix: Implement code signing for all executable outputs using authenticode certificates, verify signatures during update checks, and distribute certificates securely through certificate pinning mechanisms. - Medium · Binary Resource Embedded Without Apparent Integrity Checks —
src/Setup/flags1.bin, src/Setup/update.zip. The repository contains a compiled binary resource (src/Setup/flags1.bin) and embedded update.zip file with no visible integrity verification mechanism (checksums, signatures) in the file structure. Fix: Implement cryptographic checksums (SHA-256) for all binary resources, verify integrity before loading/extracting, use code signing for update packages, and maintain a manifest of expected hashes. - Medium · Potential DLL Injection/Sideloading Risk —
src/Setup/compat.manifest, src/Setup/Setup.vcxproj, src/Setup/stdafx.h. The Setup module references multiple system components through manifest files (compat.manifest, targetver.h) and may load DLLs dynamically. Without explicit DLL search path configuration, there's potential for DLL hijacking attacks. Fix: Use SetDllDirectory() to restrict DLL search paths, implement ASLR and DEP protections, avoid loading DLLs from current directory, and use full paths for all external dependencies. - Medium · Missing Security Headers and Configuration Management —
src/Setup/, docs/using/. No visible configuration management or secure defaults documentation for runtime security configurations (HTTPS pinning, certificate validation, update server validation) in the partial file structure provided. Fix: Document and implement secure defaults for certificate validation, implement HTTPS-only communication, use certificate pinning for update checks, and store configuration securely (not in plaintext). - Low · Incomplete Security Documentation —
docs/, SECURITY.md (missing). While security-related documentation exists (docs/using/application-signing.md, docs/using/debugging-installs.md), there is no visible threat model, security architecture document, or vulnerability disclosure policy. Fix: Create a SECURITY.md file with vulnerability disclosure policy, develop and publish security architecture documentation, create a threat model for the installer framework, and document all security assumptions.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.