Single-File Distribution of Windows Apps - Single Binaries and the Limits of OS Dependencies

· · Windows, Deployment, Single Binary, .NET, C++, WebView2, WinUI

This article started from the following post.

On Windows, “we’d like to ship this as a single file if possible” is a very common request. For internal tools, equipment-integration tools, monitoring terminals, offline environments, and sites that want to avoid installers as much as possible, going single-binary is very appealing.

However, if you do not untangle this conversation at the start, it usually stops making sense partway through. That is because “we want a single binary” on Windows tends to mix four separate concerns.

  • We want a single distribution artifact
  • We want to avoid pre-installing the .NET or Visual C++ runtimes
  • We want it to run by just dropping it in place, without an installer or administrator rights
  • We do not want to depend on differences between target Windows versions

These four are not the same thing. In practice, this framing keeps everyone aligned:

You can get quite far toward shipping a single EXE. But you cannot reduce the dependency on the target Windows to zero.

This article organizes that boundary for practical Windows app work.

1. The Conclusion First

Summarizing the conclusion up front:

  • For an ordinary desktop EXE, you can push single-binary packaging quite far
  • However, being able to ship one EXE and not depending on the target Windows are different things
  • For shell extensions, Windows services, drivers, WebView2, and parts of WinUI 3, the real issue is less the file count and more what you register with the OS and what you assume about it
  • The most important thing in practice is to decide separately whether you want a single binary, no installer, or fewer OS dependencies

Put another way, the lines on Windows fall like this.

  • Consolidating the distribution into one artifact: quite feasible
  • Bundling additional runtimes: quite feasible
  • Moving toward xcopy deployment: depends on the kind of app
  • Eliminating dependencies on the target Windows itself: impossible

2. Think of “Single Binary” in Four Levels

2.1 Level A: One distribution artifact

The most superficial level is this.

  • You can email a single file
  • You only need to put one file on a USB stick
  • You only place app.exe at the destination

This is about the apparent distribution unit. Even if the app extracts files temporarily at startup, or depends on OS-side DLLs, this condition alone can still be satisfied.

2.2 Level B: No pre-installed language runtime required

Next is the state where the app runs without pre-installing the .NET runtime or the VC++ redistributable package on the target machine.

  • Static linking for C/C++
  • .NET self-contained
  • .NET single-file
  • .NET Native AOT

At this level, the feeling of “I can carry this around on its own” gets much stronger.

2.3 Level C: No installation or registration required

From here, things suddenly get hard.

A plain EXE may run just by being dropped in place. But these are a different story.

  • Shell extensions
  • Windows services
  • Custom URL schemes and file associations
  • Drivers
  • Components loaded into other processes, such as Explorer or Office

This territory is not satisfied by just placing a file. It requires registration on the OS side, or wiring into a host.

2.4 Level D: No dependency on the target Windows

This is impossible on Windows.

A Windows app ultimately runs on top of Windows APIs, the loader, the security model, and the device stack. Single-binary packaging only covers the app’s own area of responsibility. You are not taking the OS itself along with you.

3. The Areas Where a Single EXE Is Quite Achievable

Even on Windows, some apps lend themselves relatively well to a single EXE.

  • Desktop tools launched standalone
  • Business apps where the EXE itself owns the UI and the processing
  • Tools for communication, file processing, log collection, monitoring, or equipment control
  • Things that do not require host integration with Explorer or Office
  • UIs that do not assume a web runtime

For this type, many things are easy to fold into the app itself.

  • Your own code
  • Resources
  • The manifest
  • Default settings
  • Template data
  • Some third-party libraries
  • The language runtime itself

Furthermore, even without fully embedding DLLs inside the EXE, app-local deployment, placing DLLs next to the EXE, is a perfectly viable mainstream option on Windows. In practice,

  • a single app.exe
  • or app.exe plus a few adjacent DLLs
  • with no installer, no administrator rights, distributable via xcopy

this shape is often easier to maintain than forcing everything into one EXE.

4. The Windows Dependencies That Remain Even With One EXE

If you assume “one EXE means no dependency on the target Windows,” this is where you get hurt. In reality, dependencies remain even with a single EXE.

4.1 OS version dependency

Each Windows API has a minimum supported OS. There are also x64 / Arm64 differences. So even with a single EXE, you need to pin down from the start:

  • Does it run down to Windows 10?
  • Is Windows 11 assumed?
  • Does it also need to run on Windows Server?
  • Which of x86 / x64 / Arm64 are targeted?

4.2 System DLL dependency

Even when you think you have a single EXE, at runtime you are of course using OS-provided components.

  • kernel32.dll
  • user32.dll
  • advapi32.dll
  • The COM infrastructure
  • The service control infrastructure

These are Windows’ area of responsibility.

4.3 Security model dependency

  • UAC
  • File ACLs
  • The Service Control Manager
  • The registry
  • Driver signing policy

Things like these cannot be absorbed into the app alone.

4.4 Host and runtime dependency

If the design is not a standalone EXE but something that rides on a host, dependencies multiply at once.

  • Using WebView2: the WebView2 Runtime is needed
  • Using WinUI 3 / Windows App SDK: the deployment mode needs sorting out
  • Building a shell extension: registration on the Explorer side is needed

In other words, your choice of UI or integration often becomes, directly, your distribution difficulty.

5. Realistic Trade-Offs by Technology

5.1 Native C/C++

Native C/C++ sits on the high-freedom side of single-binary packaging. Static linking is an option, and a standalone EXE can be consolidated quite far.

That said, more important in practice than cramming everything into one file are:

  • What to do about the UCRT and the VC++ runtime
  • Whether to place third-party DLLs app-local
  • How tightly to narrow the target CPU / OS

5.2 .NET

.NET offers single-file, self-contained, and Native AOT, so the apparent distribution unit can be made quite small.

But you need to keep the distinctions straight.

  • framework-dependent: depends on the .NET installed in the target environment
  • self-contained: carries the .NET runtime with it
  • single-file: consolidates the distribution into one artifact
  • Native AOT: further reduces startup-time dependencies, but comes with feature constraints

“Single-file” does not mean “fewer OS dependencies.” What it mainly reduces is how scattered the app’s distribution artifacts are.

5.3 WebView2

Adopting WebView2 completely changes the single-binary difficulty. The real subject here is not the number of EXEs but how you handle the WebView2 Runtime.

Before “can we make it one EXE,” there are questions to answer first.

  • Do you assume the Runtime already exists in the environment?
  • Do you use Evergreen?
  • Do you bundle a Fixed Version?
  • How much responsibility do you take for offline distribution?

5.4 WinUI 3 / Windows App SDK

WinUI 3 also changes your distribution requirements the moment you adopt it. Choosing the UI technology is, in itself, choosing the distribution method.

If a single binary is the top priority, it is often faster to revisit the UI technology assumption first.

6. Areas That Inherently Require Registration and Dependencies

6.1 Shell extensions

A shell extension loaded into Explorer is a different animal from a “drop-in EXE.” Here the real subject is not the file count but how you register with Explorer.

6.2 Windows services

Even if the service executable itself can be a single file, distribution is a separate problem.

  • Registration with the SCM
  • Privileges
  • The logon account
  • Recovery settings

all need consideration. In other words, services are an area where you nail down “how to install” rather than “how to make it one EXE.”

6.3 Drivers

Drivers are even more clear-cut. They only come together as a package including the INF, signing, and the installation procedure, so they barely get onto the single-binary playing field in the first place.

7. A Decision Table for Practice

For a rough judgment, this table is handy.

What you want to build Single-EXE feasibility What to think about first
Standalone Win32 / C++ tool High Static linking, target OS / arch
Standalone WinForms / WPF tool High Suitability of self-contained, single-file, Native AOT
WinUI 3 / Windows App SDK app Medium Deployment mode, additional dependencies
WebView2-based desktop UI Low to medium How the Runtime is distributed
Explorer context-menu extension or preview handler Low COM / registry registration
Windows service Medium SCM registration, privileges, update procedure
App that bundles a driver Low INF, signing, installation

The most important takeaway from this table is that “the number of binaries” and “the scope of distribution responsibility” are different things.

8. What to Decide First in Distribution Design

If you want single-binary packaging to succeed, there are things to decide before implementation.

8.1 Decide what you actually want to be “one”

  • Do you want one distribution artifact?
  • Do you want to eliminate runtime pre-installation?
  • Do you want to eliminate the installer?
  • Do you want to make offline updates easy?

The answer determines which technology you choose.

8.2 Pin down the minimum supported Windows and arch first

Both single-file and Native AOT are fundamentally OS / architecture specific. If you leave this vague and push ahead with “just make it one file,” you get stuck at the end with missing APIs or runtime mismatches.

8.3 Write down what you bundle and what you leave to Windows

In practice, just writing out this table prevents a lot of accidents.

  • What the app bundles
    • The main exe
    • Your own DLLs
    • Settings templates
    • The self-contained runtime
  • What you leave to Windows
    • System DLLs
    • OS APIs
    • SCM / registry / Explorer
    • The driver infrastructure
  • What you assume as separate prerequisites
    • WebView2 Runtime
    • VC++ Redistributable
    • Office / Excel
    • Dedicated drivers

8.4 If you prioritize a single binary, reduce host integration

This one is quite effective.

  • Drop the shell extension and make it a plain EXE
  • Skip running as a service; use Task Scheduler or explicit launch instead
  • Use a native UI instead of WebView2
  • Keep COM closed within your own process

In short, the more you reduce designs that have the OS “load” or “register” your code, the closer you get to a single binary.

9. Summary

Single-binary packaging on Windows is feasible to a considerable extent. But it all comes down to this one statement:

You can make the app a single EXE. But you cannot make the Windows the app depends on into a single EXE.

Five points worth remembering in particular:

  • For an ordinary standalone EXE, you can push single-file distribution remarkably far
  • Static linking for C/C++, .NET single-file, and Native AOT are strong options
  • However, dependencies on the OS version, arch, system DLLs, and the security model do not disappear
  • For shell extensions, services, drivers, WebView2, and parts of WinUI 3, OS registration and additional runtimes become the main story
  • Whether single-binary succeeds is decided by separating, at the start, “what exactly do we want to be one”

If you strongly prioritize a single binary, designing to lower the coupling with the OS at technology-selection time makes success far more likely.

10. References

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Windows App Development

For Windows app distribution, you can avoid rework by designing single-file packaging, runtime bundling, the decision to adopt WebView2 or WinUI, and whether to run as a service, all together.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog