ClickOnce
ClickOnce is a deployment technology developed by Microsoft that enables the creation of self-updating Windows-based applications, such as those built with Windows Forms, Windows Presentation Foundation (WPF), console applications, and Office solutions, which can be installed and run with minimal user interaction. Introduced as part of the .NET Framework 2.0 in 2005, it addresses key challenges in application deployment by simplifying installation, updates, and security management without requiring administrative privileges on the target machine.[1] Key features of ClickOnce include automatic updates that download only the changed application components, ensuring efficient bandwidth usage and seamless user experience. Applications are self-contained and isolated in a user-specific cache, preventing versioning conflicts with other software on the system. It supports both online-only mode, where the application runs directly from a network location, and offline installation for local execution, with deployment possible via web servers, network shares, or removable media like CD-ROMs. ClickOnce relies on XML-based application and deployment manifests to define files, versions, and prerequisites, facilitating reliable distribution.[2] Security is a core aspect of ClickOnce. For .NET Framework applications, it runs under partial trust by default to limit potential risks, enforced through digital certificates and user consent prompts for elevated permissions. For .NET Core 3.1 and .NET 5 or later, partial trust is unsupported and applications run in full trust, with security relying on code signing via Authenticode certificates. This approach balances ease of deployment with protection against malicious code, allowing non-administrators to install trusted applications safely. Support for ClickOnce extends to modern .NET versions, including .NET Core 3.1 and .NET 5 or later, using tools likedotnet-mage.exe for manifest generation in Visual Studio environments.[2][3]
Introduction
Overview
ClickOnce is a deployment technology developed by Microsoft for .NET Framework and .NET applications, enabling installation and automatic updates specifically for Windows desktop applications such as Windows Forms, Windows Presentation Foundation (WPF), and console applications.[2] It addresses common challenges in software distribution by allowing applications to be published to web servers, network shares, or removable media, where end users can install or run them with minimal intervention.[2] The technology's primary benefits include simplified deployment that does not require administrator rights for installation, as applications are installed in a secure, per-user cache isolated from the system to prevent conflicts with other software.[2] Automatic updates ensure that only modified components are downloaded, reducing bandwidth usage and keeping applications current without manual intervention.[2] Additionally, ClickOnce integrates seamlessly with Visual Studio, providing built-in publishing tools to streamline the development-to-deployment pipeline.[4] In its basic workflow, a user clicks a deployment link in a web browser or accesses a shared location, prompting the application to download from the server, install in the user's profile, and launch either online or offline as configured.[2] At a high level, ClickOnce incorporates partial trust execution to enforce security boundaries by limiting application permissions based on the deployment zone, and it supports rollback capabilities that allow users or administrators to revert to prior versions in case of issues.[2]History
ClickOnce was introduced in 2005 as part of the .NET Framework 2.0, integrated with Visual Studio 2005, to simplify the web-based deployment of Windows desktop applications by enabling easy installation and automatic updates without requiring administrative privileges.[5][6] This technology evolved from earlier Microsoft deployment methods, such as No-Touch Deployment in the .NET Framework 1.1, which allowed running applications directly from a web server but lacked robust update mechanisms, and Windows Installer (MSI), which provided more comprehensive but complex installation processes.[7] Key enhancements followed in subsequent .NET Framework releases. With .NET Framework 3.0 in 2006, ClickOnce gained support for Windows Presentation Foundation (WPF) applications, enabling richer user interfaces through browser-hosted or standalone deployments.[8] Further improvements arrived in .NET Framework 3.5 (2007), and in .NET Framework 4.0 (2010), which introduced security enhancements like improved code access security and more robust update handling to reduce failures.[9][10] Support continued through .NET Framework 4.8, released in 2019, which remains the final major version of the full .NET Framework and fully backs ClickOnce for Windows Forms and WPF apps.[11] As Microsoft shifted focus to the cross-platform .NET (formerly .NET Core), starting with .NET Core 3.1 in 2019, ClickOnce support was adapted for Windows-only desktop applications via the MSBuild-based Publish tool, allowing deployment of .NET 5 and later versions but without native cross-platform capabilities.[12] As of 2025, ClickOnce remains supported on Windows for .NET 9 with no announced full deprecation.[2][13]Deployment and Installation
Supported Applications
ClickOnce primarily supports Windows desktop applications built on the .NET Framework or .NET (formerly .NET Core), including Windows Forms applications for traditional graphical user interfaces, Windows Presentation Foundation (WPF) applications leveraging XAML for rich, declarative UIs, and console applications for command-line operations.[2][14] It also provides limited integration for Office solutions, such as Visual Studio Tools for Office (VSTO) add-ins, enabling deployment of custom extensions for Microsoft Office applications like Excel or Word through the same publishing mechanisms.[15] Applications compatible with ClickOnce must be developed using managed .NET languages such as C# or Visual Basic, targeting either the .NET Framework (version 2.0 and later) or modern .NET versions starting from .NET Core 3.1 and .NET 5 onward for Windows desktop scenarios; native applications written in unmanaged languages like C++ are not supported, as ClickOnce relies on the .NET runtime for execution and deployment.[14] Similarly, cross-platform .NET applications, such as those using .NET MAUI for multi-platform deployment, require additional tooling like MSIX packaging for non-Windows environments, as ClickOnce is inherently tied to Windows-specific installation and execution models. Deployments typically involve a single executable or a set of related assemblies, ensuring the application can be self-contained without complex native dependencies. ClickOnce offers two main deployment modes to accommodate different user needs: online mode, where the application launches directly from a network location and requires an internet connection for initial access and updates, and offline mode, which installs the application locally on the user's machine for execution without network dependency after setup.[2][4] These modes suit various use cases, such as enterprise tools distributed via internal networks for online access or standalone internal applications like data analysis consoles that benefit from offline installation for remote workers.[16] Key limitations include restrictions on application size and type to ensure reliable web-based deployment; by default, the Internet Explorer zone quota for online applications is 250 MB, with partial-trust applications capped at half that amount (125 MB) to prevent security risks, though full-trust scenarios may allow larger sizes with user elevation.[17] ClickOnce does not support kernel-mode drivers, system services, or applications requiring administrative privileges for installation of shared components, as it operates within a user-context sandbox to maintain security isolation.[2]Installation Process
Developers can publish ClickOnce applications using Visual Studio by right-clicking the project in Solution Explorer and selecting Publish, which opens the Publish wizard to configure the deployment profile.[14] This process generates a setup.exe bootstrapper file, which handles prerequisite installations like the .NET runtime, and a .application deployment manifest file that describes the application.[18] Publishing options include specifying the location as a folder, UNC path, HTTP/HTTPS website, FTP server, or removable media such as CD/DVD/USB.[18] Alternatively, developers can use MSBuild from the command line with the/target:publish option to build and deploy the application, producing the same setup.exe and .application files in a Publish subfolder.[19]
For end users, installation begins when clicking a web link to the .application file, prompting the .NET runtime to download and install automatically if the required version is absent on the system.[14] The application then installs to a user-specific cache in %LocalAppData%\Apps\2.0 without requiring administrator privileges, enabling seamless deployment across standard user accounts.[18] Users are presented with options to either run the application online (without full installation or Start menu integration) or install it for offline access, which adds a Start menu shortcut.[14]
Common installation errors include certificate validation failures, where an untrusted or invalid Authenticode certificate triggers a user trust prompt or blocks the process entirely if not signed properly.[2] Network timeouts may occur during manifest downloads from HTTP/HTTPS or FTP locations, potentially requiring retry or manual intervention, though specific handling is managed by the .NET runtime.[18] In cases of failed updates during installation, ClickOnce supports rollback to a previous version, configurable through publishing properties or APIs to restore stability.[2]
Customization during publishing allows developers to specify a publisher name in the Project Designer’s Publish page, which appears in installation dialogs and shortcuts.[18] Enabling offline availability creates Start menu shortcuts, while file associations can be defined in the Publish Options to link document types to the application upon launch.[14] These manifests outline the installation details, such as entry points and prerequisites.[18]
Core Components
Manifests
ClickOnce relies on two primary XML manifest files to define the identity, dependencies, and deployment parameters of an application, serving as the foundational descriptors that enable the runtime to locate, install, and verify the necessary components.[2] The deployment manifest, typically with a .application file extension, outlines the overall deployment structure, including the application version, entry point, and update location, while the application manifest, with a .manifest file extension, provides detailed specifications for the application's assemblies, files, permissions, and runtime dependencies.[20][21] These manifests adhere to specific XML schemas that ensure compatibility and consistency across deployments.[2] Key elements in the deployment manifest include the top-level<assembly> tag, which encapsulates the manifest version (e.g., "1.0") and contains an <assemblyIdentity> element specifying the application's name, version (such as "1.0.0.0"), public key token, processor architecture, and culture.[20] The <deployment> element defines critical URLs, such as the deployment provider for updates (e.g., a file path like "\myServer\sampleDeployment\MyApplicationDeployment.application") and installation settings, while the <compatibleFrameworks> section lists supported .NET Framework versions (e.g., "4.0").[20] In the application manifest, the <assemblyIdentity> identifies the primary assembly with attributes like name and version, the <entryPoint> specifies the executable entry point, and <dependency> elements detail required assemblies and their codebases with size attributes for verification.[21] Additionally, <file> elements describe non-assembly files, including their names, sizes, and optional groupings, and <trustInfo> outlines permission sets, such as unrestricted access.[21]
Manifests are generated automatically during the publishing process in Visual Studio via the Publish Wizard or MSBuild tasks like GenerateApplicationManifest and GenerateDeploymentManifest, which compile project details into the XML structure.[2] For custom configurations, such as adding prerequisites like .NET runtime installers, developers can manually edit manifests using tools like Mage.exe for .NET Framework applications or dotnet-mage.exe for .NET 5 and later, ensuring the XML remains well-formed and schema-compliant.[2][12] During download and installation, these manifests facilitate integrity checks by comparing file hashes and sizes against the declared values, preventing deployment if tampering is detected and thus maintaining application reliability.[2] This validation process supports seamless updates by referencing the deployment manifest's provider URL to fetch new versions when available.[2]
Assemblies
In ClickOnce deployments, .NET assemblies serve as the fundamental building blocks of an application, consisting of executable files (EXEs) and dynamic-link libraries (DLLs) that contain the compiled code, metadata, and resources necessary for the application's functionality. These assemblies are managed within the .NET assembly model, where they can be either strongly named—providing unique identification through a public key token, version, and culture to enable secure sharing—or weakly named for simpler, non-shared scenarios. Additionally, satellite assemblies are utilized to support localization, encapsulating culture-specific resources such as strings and images in separate DLLs that align with the client's current UI culture, allowing the main application assembly to remain neutral and adaptable across languages.[22] ClickOnce packages these assemblies by bundling them into the per-user application cache, a hidden directory structure located under the user's Local Settings folder (typically at %LocalAppData%\Apps\2.0), ensuring isolation and easy access without requiring administrative privileges. During deployment, each assembly is hashed using the SHA-1 algorithm to verify integrity, with the hash value embedded in the application manifest to detect any tampering or corruption before installation. For large applications, ClickOnce supports on-demand downloading of assemblies. For .NET Framework applications, this is via the System.Deployment.Application API, where optional assemblies are marked in the manifest and retrieved asynchronously only when first referenced at runtime, reducing initial download size and bandwidth usage. In .NET 5 and later, this functionality has limitations, with programmatic access unavailable in .NET Core 3.1 to .NET 6 and supported via environment variables in .NET 7+. The application manifest references these assemblies, specifying their dependencies and download groups to orchestrate the packaging process.[23][24][25][12] At runtime, assemblies are loaded from the ClickOnce cache using the runtime's assembly resolution mechanisms. In the .NET Framework, this is handled by the Fusion assembly loader, which performs just-in-time resolution by probing the ClickOnce cache first, then falling back to standard locations like the Global Assembly Cache (GAC) if needed, while respecting strong or weak naming to prevent version conflicts. In .NET 5 and later, resolution uses the .NET runtime's dependency resolver without a GAC. This process ensures per-application isolation, as each ClickOnce app operates within its own cache subdirectory, avoiding interference from other applications or system-wide assemblies. Fusion handles resolution events, such as AssemblyResolve, allowing custom logic for on-demand loading if an assembly is not immediately available in the cache.[26][12] Assembly management in ClickOnce involves automatic cleanup to maintain efficiency, where unused versions are removed from the cache upon successful updates, retaining only the current and immediately previous version to support rollback if necessary. The cache enforces size limits to prevent disk exhaustion, with a default quota of 250 MB for online (non-installed) applications—excluding data files—configurable via registry settings, while installed applications face no such restriction but still benefit from cleanup mechanisms. This approach ensures reliable storage and retrieval without manual intervention.[23]Updating and Maintenance
Update Mechanisms
ClickOnce applications detect updates by checking the deployment manifest at a specified URL upon launch or at configurable intervals. This process involves querying the deployment provider URL, typically an HTTP endpoint or UNC path, to retrieve the latest deployment manifest and compare its version against the currently installed application version. In .NET Framework applications, the check frequency can be set to occur before the application starts (to ensure the latest version runs immediately) or after startup in the background (to minimize launch delays). For .NET Core 3.1 and .NET 5 or later, only before-startup checks are supported.[27][28] Developers configure these options in the publish settings, with the before-startup method serving as the default for ensuring users always access the most recent version. Once a newer version is detected, ClickOnce handles the download and installation process, which can occur in the foreground (blocking the application until complete) or background (allowing continued use of the current version) in .NET Framework. Downloads use delta patching to transfer only the changed assemblies and files, reducing bandwidth usage compared to full redeployments. Users may receive prompts to install the update unless automatic installation is enabled; in such cases, the update applies seamlessly upon the next application restart. The ApplicationDeployment.Update method in the .NET Framework enables synchronous or asynchronous downloads, returning true if an update succeeds or false otherwise, with error handling for issues like network failures. In .NET 7 and later, limited programmatic access to deployment properties is available via new APIs in the System.Deployment namespace.[27][29][30][31] Update strategies in ClickOnce balance reliability and user experience through versioning enforcement and deployment modes. Strict versioning, implemented via the minimumRequiredVersion attribute in the deployment manifest, blocks downgrades by preventing the application from running if the installed version is older than specified, ensuring critical security or compatibility fixes are applied. Inclusive strategies omit this attribute, allowing older versions to run while offering optional updates, which suits scenarios with variable network conditions. Applications deployed over the internet (via HTTP/HTTPS) support automatic checks and delta updates, whereas CD-based or offline deployments rely on manual checks or alternative UNC paths for updates. If an update fails, such as during a corrupted download, the application continues using the previously installed version.[27][2][28] Developers exert fine-grained control over updates through Visual Studio publish settings and manifest configurations. The Updates dialog in the Project Designer allows specifying the update location (e.g., a custom URL distinct from the installation source) and check frequency (e.g., every 7 days, though intervals are unsupported in modern .NET), with expiration periods via the maximumAge attribute to limit how long before rechecking. Programmatic control in .NET Framework uses the System.Deployment.Application namespace, where methods like CheckForDetailedUpdate provide update availability details, and UpdateAsync enables non-blocking installations triggered by user interface elements. These settings are embedded in the deployment manifest, which the application references during runtime checks. For .NET Core 3.1 and later, configuration is limited to publish settings without runtime programmatic control beyond basic checks.[28][30][27]Versioning
ClickOnce employs a versioning model that distinguishes between assembly versions and deployment versions to facilitate updates while maintaining application integrity. The assembly version follows a four-part numbering scheme in the format major.minor.build.revision, such as 1.0.0.0, which is specified in the application's manifest and embedded in the primary assembly.[32][21] This version identifies the application's components and must be incremented for updates to ensure proper dependency resolution, particularly for strong-named assemblies where version mismatches can lead to runtime errors.[3] In contrast, the deployment version, also in the four-part format, is independent of the assembly version and controls the update process; it is set in the deployment manifest and can use an asterisk (*) in the revision field for automatic incrementing during builds.[19][33] Developers should never decrement any part of the version numbers, as this can disrupt update detection and lead to deployment failures.[34] Compatibility in ClickOnce is governed by strict version comparison rules during updates. The runtime checks the deployment manifest's version against the installed version and skips the update if the new version is not higher, preventing unnecessary downloads or overwrites.[35] For backward compatibility with dependencies, assembly binding redirects can be configured in the application's configuration file (app.config) to map requests for older assembly versions to newer ones, allowing seamless integration of updated components without recompiling the entire application. When incrementing assembly versions, especially for strong-named assemblies, all referencing assemblies must be recompiled to avoid binding failures.[3] Version conflicts are mitigated through ClickOnce's cache management, which supports side-by-side installations of multiple application versions. Each version is stored in a dedicated subdirectory within the per-user ClickOnce cache, ensuring isolation of assemblies, data files, and configurations to prevent interference between versions.[23] The cache retains only the current and previous versions by default, automatically cleaning up older ones during upgrades. For handling breaking changes, developers follow best practices such as incrementing the major version number to signal incompatibility, recompiling dependent assemblies, and re-signing manifests to maintain trust and avoid deployment errors.[3] Versioning is managed primarily through integrated development tools. In Visual Studio, the assembly version is defined in the AssemblyInfo.cs file, where developers set the [AssemblyVersion] attribute to control the four-part version for the compiled binaries. The deployment version is configured via the Publish tab in the project properties, allowing automatic revision increments on each publish. For post-build adjustments, such as updating manifest versions manually, the Mage.exe tool (Manifest Generation and Editing Tool) is used to edit and sign the application and deployment manifests, ensuring consistency after changes.[36][37] In .NET 5 and later, dotnet-mage.exe replaces Mage.exe for these operations.[12]Security Features
Code Access Security
ClickOnce applications leverage the .NET Framework's Code Access Security (CAS) to enforce a partial trust execution model, particularly when deployed from untrusted sources such as the internet zone. By default, applications installed via ClickOnce from the internet receive a highly restrictive permission set, limiting access to sensitive resources like file I/O and the Windows registry to prevent potential exploitation by malicious code.[38] This partial trust approach allows applications to run without requiring full administrative privileges on the end user's machine, thereby enhancing security for web-based deployments.[2] Full trust can be granted if explicitly requested and approved, but it exposes the system to greater risks and is typically reserved for trusted environments.[39] Permission sets in ClickOnce are predefined based on security zones, with the MyComputer zone granting full trust for locally installed applications, the Internet zone applying partial trust with severe restrictions, and the Local Intranet zone providing moderate permissions for network shares. Developers can request custom permission sets through the<requestedPermissions> element in the application manifest, allowing tailored access beyond zone defaults while still adhering to CAS constraints.[38] These permissions are configured via the Security page in Visual Studio's Project Designer, where developers select a base zone and adjust individual permissions as needed.[40] If an application demands permissions exceeding the default zone grants, users may encounter a trust prompt to approve the installation.[39]
The granting of permissions relies on evidence collected from the application's origin, including its security zone, installation site, and strong name identity, which collectively inform the CAS policy evaluation. These policies operate at multiple levels—enterprise, machine, and user—enabling administrators to enforce organization-wide security configurations or allow user-specific overrides.[38] For instance, strong name evidence can elevate trust for signed assemblies from verified publishers, influencing the final permission set applied at runtime.[2]
Although CAS was deprecated starting in .NET Framework 4.0 in favor of a simplified security model that disables legacy policy enforcement by default, it remains applicable for ClickOnce applications targeting .NET Framework as of 2025, particularly in legacy environments where partial trust is still desired. However, Microsoft does not recommend using CAS for ClickOnce applications, even in .NET Framework, due to associated security risks and user experience issues.[41][38] In contrast, ClickOnce deployments for .NET Core and .NET 5 or later do not support CAS, requiring full trust execution instead.[2] This transition underscores the shift toward more transparent security practices, but CAS continues to provide a viable partial trust option for compatible .NET Framework-based ClickOnce scenarios.[39]
Authentication and Signing
ClickOnce employs Authenticode digital signing to authenticate the publisher and ensure the integrity of deployment manifests and application assemblies, mitigating risks such as tampering or malicious alterations.[42] This process uses public-key infrastructure (PKI) certificates to bind the software to a verifiable identity, allowing users and the operating system to confirm the application's origin before installation.[39] The signing process involves applying Authenticode signatures to both the application and deployment manifests using a code-signing certificate in .pfx format. Developers can perform signing directly in Visual Studio by navigating to the project's Signing tab, selecting the "Sign the ClickOnce manifests" option, and choosing a certificate from the Windows store, a .pfx file, or generating a test certificate (which defaults to SHA-256 hashing for compatibility with .NET Framework 3.5 and later). Alternatively, command-line tools like Mage.exe or signtool.exe from the Windows SDK can sign manifests with a .pfx certificate, requiring the private key and optional password. While signing is optional, it is essential for deployments over HTTPS to enable trusted publisher identification and avoid warnings in modern browsers. Assemblies themselves may also be signed with strong names for additional integrity checks, though this is separate from manifest signing.[43][42] Certificates play a critical role in establishing trust: the publisher's certificate, issued by a trusted certificate authority (CA), is embedded in the signature to display verified identity details in the trust user interface, distinguishing it from self-signed test certificates that appear as "Unknown Publisher." Certificate chains are validated against the system's trusted root authorities during installation to ensure the issuer's legitimacy. Timestamping, applied via a trusted timestamp authority during signing, embeds a server-verified time to prevent expiration issues, allowing the signature to remain valid even after the certificate lapses (typically extending validity by the timestamp server's policy period). Revocation status is checked through mechanisms like Certificate Revocation Lists (CRL) or Online Certificate Status Protocol (OCSP) as part of Windows' Authenticode validation, blocking installation if the certificate is revoked.[42][44] During installation, users encounter trust prompts in the browser or installer dialog, presenting the publisher's name, certificate details, and application description for approval; unsigned or self-signed applications trigger heightened warnings, with options to proceed at the user's risk. Administrators can pre-trust publishers via group policy to suppress prompts for enterprise deployments. Post-authentication, the application operates within the security boundaries defined by its zone, such as partial trust for Internet-sourced apps.[39][42] Best practices emphasize using CA-issued certificates over self-signed ones for production, applying timestamps to all signatures, and preferring SHA-256 hashing algorithms, as SHA-1 has been deprecated by Microsoft for code signing due to collision vulnerabilities since 2016. Extended Validation (EV) code-signing certificates are recommended for enhanced trust indicators, improving SmartScreen reputation and reducing user hesitation in high-security environments.[45][46]Compatibility and Support
Browser and Platform Support
ClickOnce provides robust browser integration primarily for Microsoft browsers, enabling seamless deployment of Windows applications via web links. It offers full support in the Chromium-based Microsoft Edge, where the feature is enabled by default and leverages the ClickOnce protocol along with DirectInvoke to handle file downloads and launches through registered Windows file handlers.[47] Legacy support remains available in Internet Explorer, allowing direct launches from web pages without additional configuration.[2] However, integration is limited in Google Chrome and Mozilla Firefox due to the deprecation of NPAPI plugins—Chrome phased out support in 2015, and Firefox followed in 2017—necessitating third-party extensions like the ClickOnce Launcher for functionality, though these do not provide native reliability.[48][49] Proper server configuration is essential, with the MIME typeapplication/x-ms-application required for .application files to ensure browsers recognize and process deployment manifests correctly.[50]
Applications can be launched through various web-based methods, including direct hyperlinks to the .application file, embedding in HTML pages via anchor tags, integration within ASP.NET applications, or invocation via JavaScript to initiate downloads.[2] When hosted on HTTPS sites, ClickOnce deployments must avoid mixed content by ensuring all linked resources, including manifests and assemblies, are served over HTTPS to prevent browser warnings or blocks that could interrupt the launch process.[50]
ClickOnce is exclusively compatible with Windows platforms, supporting Windows 10 version 1607 and later, including Windows 11, and requires the .NET Framework 4.0 or higher for runtime execution.[51][52] It lacks native support on macOS or Linux, as the deployment mechanism relies on Windows-specific file associations and the .NET runtime environment. While .NET 8 and later versions enable cross-platform publishing of ClickOnce packages from macOS or Linux development machines, the resulting deployments can only be installed and run on Windows, often requiring custom hosting solutions for non-standard scenarios.[12]
Since 2020, ClickOnce has seen enhanced integration with the Chromium-based Microsoft Edge, including policy controls for enabling or disabling the protocol via edge://flags or group policies.[47] For applications embedding web content, there is growing reliance on the Edge WebView2 control to facilitate modern browser experiences within ClickOnce-deployed apps, though known issues persist with sandboxed iframes, where restricted permissions can prevent proper content loading or script execution in embedded contexts.[53]