Created
July 19, 2012 15:57
-
-
Save josheinstein/3144904 to your computer and use it in GitHub Desktop.
Install ClickOnce application programmatically (C#)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Deployment.Application; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
namespace InstallClickOnceApp | |
{ | |
/// <summary> | |
/// InstallClickOnceApp.exe uri | unc | |
/// Programmatically installs a ClickOnce application under the current user's profile without | |
/// launching the application. Perfect for group policy deployment or logon scripts. | |
/// </summary> | |
public static class Program | |
{ | |
private static AutoResetEvent waitHandle; | |
private const int E_OK = 0; | |
private const int E_NOARGS = 1; | |
private const int E_INVALIDURI = 2; | |
private const int E_MANIFESTERROR = 3; | |
private const int E_REQUIREMENTS = 4; | |
private const int E_DOWNLOADERROR = 5; | |
/// <summary> | |
/// Main program entry point, which receives the command line arguments passed to the application, if any. | |
/// </summary> | |
/// <param name="args">The command line arguments passed to the application.</param> | |
public static void Main( string[] args ) | |
{ | |
Console.WriteLine( "Install ClickOnce Application Utility" ); | |
Console.WriteLine( ); | |
if ( args == null || args.Length == 0 ) { | |
PrintUsage( null ); | |
Environment.Exit( E_NOARGS ); | |
} | |
Uri deploymentUri; | |
if ( !Uri.TryCreate( args[0], UriKind.Absolute, out deploymentUri ) ) { | |
PrintUsage( "Invalid deployment URI: {0}", args[0] ); | |
Environment.Exit( E_INVALIDURI ); | |
} | |
waitHandle = new AutoResetEvent( false ); | |
using ( var host = new InPlaceHostingManager( deploymentUri, false ) ) { | |
GetApplicationManifest( host ); | |
AssertApplicationRequirements( host ); | |
DownloadApplication( host ); | |
} | |
Console.WriteLine( "Done" ); | |
} | |
/// <summary> | |
/// Begins downloading the application manifest and blocks until complete. | |
/// </summary> | |
/// <remarks> | |
/// If an error occurs, the process will exit and the method will not return. Cheap, I know. I'm in a hurry. | |
/// </remarks> | |
/// <param name="host">The ClickOnce hosting manager.</param> | |
private static void GetApplicationManifest( InPlaceHostingManager host ) | |
{ | |
Console.WriteLine( "Retrieving application manifest." ); | |
host.GetManifestCompleted += ( sender, e ) => { | |
if ( e.Error != null ) { ExitWithError( e.Error, E_MANIFESTERROR ); } | |
Console.WriteLine( ); | |
Console.WriteLine( "Product: {0}", e.ProductName ); | |
Console.WriteLine( "Log: {0}", e.LogFilePath ); | |
Console.WriteLine( ); | |
waitHandle.Set( ); | |
}; | |
host.GetManifestAsync( ); | |
waitHandle.WaitOne( ); | |
} | |
/// <summary> | |
/// Verifies that the computer meets the requirements of the application based on its manifest. | |
/// (ie. assemblies that are required to be in the GAC are already present, framework version, etc.) | |
/// </summary> | |
/// <remarks> | |
/// If an error occurs, the process will exit and the method will not return. Cheap, I know. I'm in a hurry. | |
/// </remarks> | |
/// <param name="host">The ClickOnce hosting manager.</param> | |
private static void AssertApplicationRequirements( InPlaceHostingManager host ) | |
{ | |
Console.WriteLine( "Verifying system requirements." ); | |
try { | |
host.AssertApplicationRequirements( ); | |
} | |
catch ( Exception error ) { | |
ExitWithError( error, E_REQUIREMENTS ); | |
} | |
} | |
/// <summary> | |
/// Begins downloading the application binaries and blocks until complete. | |
/// </summary> | |
/// <remarks> | |
/// If an error occurs, the process will exit and the method will not return. Cheap, I know. I'm in a hurry. | |
/// </remarks> | |
/// <param name="host">The ClickOnce hosting manager.</param> | |
private static void DownloadApplication( InPlaceHostingManager host ) | |
{ | |
Console.WriteLine( "Downloading application." ); | |
host.DownloadApplicationCompleted += ( sender, e ) => { | |
if ( e.Error != null ) { ExitWithError( e.Error, E_DOWNLOADERROR ); } | |
Console.WriteLine( "Download completed." ); | |
waitHandle.Set( ); | |
}; | |
host.DownloadApplicationAsync( ); | |
waitHandle.WaitOne( ); | |
} | |
/// <summary> | |
/// Displays basic instructions for how to run the application as well as an optional | |
/// additional error message. | |
/// </summary> | |
/// <param name="message">If not null, this error message is displayed under the usage.</param> | |
/// <param name="args">String format placeholder values.</param> | |
private static void PrintUsage( string message, params object[] args ) | |
{ | |
Console.WriteLine( ); | |
Console.WriteLine( "Usage: InstallClickOnceApp <url | unc>" ); | |
Console.WriteLine( ); | |
if ( message != null ) { | |
Console.WriteLine( message, args ); | |
Console.WriteLine( ); | |
} | |
} | |
/// <summary> | |
/// This method terminates the process with the specified exit code after writing the | |
/// exception message to the console. | |
/// </summary> | |
/// <param name="error">The error message to write.</param> | |
/// <param name="exitCode">The exit code to return to the OS.</param> | |
private static void ExitWithError( Exception error, int exitCode = 99 ) | |
{ | |
Console.WriteLine( "Error: {0}", error.Message ); | |
Console.WriteLine( ); | |
Environment.Exit( exitCode ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment