What is Squirrel in the Windows application management world?

Written by Alex Marin · February 17th, 2026 · 6min read

There are many tools that are designed to assist you in managing all aspects of it. In the application management area, there is also the free Squirrel project, available on GitHub.

In this article, I’d like to explain what Squirrel is, how you can detect if it's running on your machine, and how we can stop it.

Squirrel: It's like ClickOnce but WorksCopy link to this sectionLink to this section copied!

This is their trademark statement: "It's like ClickOnce but Works”.

Overall, Squirrel is an installation and update framework for Windows Desktop applications.

If you are a developer, you can package, distribute, and update applications in the infrastructure but only within the user context.

This framework has its pros and cons.

One advantage is that user-based installations do not require elevation for installation, and the core system itself is not modified, which makes them safe.

As a disadvantage, we can see that this is not a full-fledged IT management solution like Intune or MECM where, in large infrastructures, the preferred way of deploying applications is via per-machine context.

Squirrel framework for windows application management

Squirrel relies on NuGet-based packaging, meaning the developers must package the apps as .nupkg files, leveraging existing tools.

Squirrel does provide:

  • Wizard-free installations
  • Background Updates
  • Delta Updates
  • Simple integration

The Squirrel managed applications are typically stored under:

%LOCALAPPDATA%\AppName\
%LOCALAPPDATA%\AppName\app-<version>\

Detecting and Stopping Squirrel on a User MachineCopy link to this sectionLink to this section copied!

Here is the catch: Squirrel does not run as a central background service that updates your applications.

Instead, each application that uses Squirrel includes its own copy of an Update.exe in the installation directory. This is typically found under:

%LOCALAPPDATA%\AppName\

The Update.exe is a Squirrel updater binary, meaning it is the same component bundled per app.

When the application wants to check for updates, it simply calls its local Update.exe. So, basically, every Squirrel-packaged app has its own updater.

Let me show you a few examples:

%LOCALAPPDATA%\Slack\Update.exe
%LOCALAPPDATA%\Microsoft Teams\Update.exe
%LOCALAPPDATA%\MyCustomApp\Update.exe

But how do the regular checks and updates occur, you might wonder?

The Update.exe is triggered by either the application itself (when run) or a scheduled task. The Update.exe checks the release file and looks into the app feed URL.

If a new version is available, then it downloads the new nupkg and installs it under a new app-<version> folder. The shortcut is then updated to point to the latest version.

However, if we want to figure out if Squirrel is running, we must look at more than just Update.exe. There is also the Squirrel.exe.

Now you might wonder, what is the purpose of Squirrel.exe if Squirrel doesn’t act as a central repository?

As mentioned above, the Update.exe is the main updater binary shipped with every Squirrel-packaged app, while Squirrel.exe serves as a helper bootstrapper that gets invoked during installation and update operations.

Its responsibilities include creating or updating shortcuts, registering/unregistering the application in the system and running the install hooks defined by the developer.

This is not a long-running background service, since this runs only briefly when necessary. In most cases, you will see Squirrel.exe called by Update.exe as part of the update cycle.

But how can we stop it?

Considering that we now have a general understanding of how Squirrel operates, we can use PowerShell to check if either Update.exe or Squirrel.exe is running.

However, just to make sure that we are terminating an application packaged by Squirrel, we need to see if the actual Update.exe process is running from one of the known folders of Squirrel applications.

Remember that other “normal” applications may also have an Update.exe, so we don’t want to kill them as well.

This is the PowerShell script:

function Test-SquirrelAppFolder {
    param([string]$folder)
    $releasesFile = Join-Path $folder "RELEASES"
    $appFolders   = Get-ChildItem -Path $folder -Directory -ErrorAction SilentlyContinue |
                    Where-Object { $_.Name -like "app-*" }
    return (Test-Path $releasesFile -and $appFolders)
}
$procs = Get-Process -ErrorAction SilentlyContinue | Where-Object {
    $_.ProcessName -in @("Update","Squirrel")
}
foreach ($proc in $procs) {
    try {
        $path   = $proc.Path
        $folder = Split-Path $path -Parent
        if ($path -like "$env:LOCALAPPDATA\*") {
            if (Test-SquirrelAppFolder $folder) {
                Write-Host "$($proc.ProcessName).exe detected for app in $folder (PID $($proc.Id)). Killing..."
                Stop-Process -Id $proc.Id -Force
                if ($proc.ProcessName -eq "Update") {
                    $squirrelPath = Join-Path $folder "Squirrel.exe"
                    if (Test-Path $squirrelPath) {
                        $squirrelProc = Get-Process -ErrorAction SilentlyContinue | Where-Object {
                            $_.Path -eq $squirrelPath
                        }
                        if ($squirrelProc) {
                            Write-Host "Squirrel.exe also running (PID $($squirrelProc.Id)). Killing..."
                            Stop-Process -Id $squirrelProc.Id -Force
                        }
                        else {
                            Write-Host "Squirrel.exe exists in $folder but is not running."
                        }
                    }
                }
            }
            else {
                Write-Host "$($proc.ProcessName).exe at $path does not appear to be Squirrel. Skipping."
            }
        }
        else {
            Write-Host "$($proc.ProcessName).exe at $path is outside LOCALAPPDATA. Likely not Squirrel. Skipping."
        }
    }
    catch {
        Write-Warning "Could not inspect process $($proc.Id): $_"
    }
}

So, what does the script do exactly?

We know that Squirrel.exe is always present inside the app folder, alongside Update.exe.

However, we also know that Squirrel.exe may not always be called during an update or installation.

So we are performing two checks:

  1. Check if Update.exe is running, and if so, we determine which folder it is coming from
  2. If this is a local folder, we check if Squirrel.exe exists in that folder or if it runs in the same location

If the statements are true, we kill the Update.exe and Squirrel.exe (in case they are running).

ConclusionCopy link to this sectionLink to this section copied!

Squirrel.Windows is a lightweight installer and updater framework that simplifies application distribution in the user context.

Unlike enterprise tools, it doesn’t run as a central service. Instead, each app ships its own Update.exe and Squirrel.exe to handle updates and housekeeping locally under %LOCALAPPDATA%.

For IT admins, this means detection requires checking process paths and folder structures to confirm Squirrel activity. The provided PowerShell script ensures only genuine Squirrel processes are terminated, avoiding accidental interference with other updaters.

In short, understanding how Squirrel works allows you to safely monitor and control its behavior in your environment.

Final TakeawaysCopy link to this sectionLink to this section copied!

You've probably seen Squirrel.exe or Update.exe running under %LOCALAPPDATA%. Wondered what they're doing? Another updater framework to keep track of. These belong to Squirrel.Windows and various apps use it for installations and updates.

  • Squirrel.exe serves as the helper bootstrapper for Squirrel.Windows. Creates shortcuts. Registers applications. Executes developer-defined install hooks during installations and updates. It's not a persistent background service, which surprises some people since it runs briefly when needed, does its job, and then closes.
  • Update.exe acts as the primary updater binary shipped with every Squirrel-packaged application. Each app maintains its own copy in %LOCALAPPDATA%\Slack\Update.exe, %LOCALAPPDATA%\Microsoft Teams\Update.exe, and so on.
  • Squirrel-managed apps reside under %LOCALAPPDATA%\AppName\ containing Update.exe, Squirrel.exe, and versioned folders like app-1.2.3. Examples you'll see: %LOCALAPPDATA%\Slack\, %LOCALAPPDATA%\Microsoft Teams\, %LOCALAPPDATA%\Discord\.
  • To stop Squirrel processes, terminate Update.exe and Squirrel.exe (if running): Stop-Process -Name Update -Force and Stop-Process -Name Squirrel -Force.
  • Common Squirrel-managed applications? Slack, Microsoft Teams, Discord, and plenty of others you probably use daily. Any application with Update.exe sitting in %LOCALAPPDATA%\AppName\ probably uses Squirrel for updates. It's become pretty popular with desktop app developers.
  • Key indicators a folder contains a Squirrel-managed application: RELEASES file (holds version metadata), app-<version> folder structure showing version progression like app-1.2.3, app-1.2.4, and sometimes .nupkg files from NuGet packages.
  • Squirrel doesn't run as a central background service managing all your applications. Each app ships its own updater - that's the whole architecture. It doesn't do machine-wide deployments (user context only), doesn't require elevation, and isn't comparable to enterprise platforms like Intune or MECM.
Written by
See author's page
Alex Marin

Application Packaging and SCCM Deployments specialist, solutions finder, Technical Writer at Advanced Installer.

Comments: