Skip to content

Instantly share code, notes, and snippets.

@mkoertgen
Created April 19, 2016 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mkoertgen/524b64a8a48cc6991b8308f6aa6d41a4 to your computer and use it in GitHub Desktop.
Save mkoertgen/524b64a8a48cc6991b8308f6aa6d41a4 to your computer and use it in GitHub Desktop.
ClickOnce: Setting a custom icon in 'Add/Remove Programs'
using System;
using System.Deployment.Application;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.Win32;
namespace MyApp
{
internal class ClickOnce
{
private readonly Uri _activationUri;
public string Query => _activationUri?.Query ?? string.Empty;
public string[] Args => AppDomain.CurrentDomain?.SetupInformation?.ActivationArguments?.ActivationData;
public ClickOnce()
{
try
{
_activationUri = (ApplicationDeployment.IsNetworkDeployed &&
ApplicationDeployment.CurrentDeployment.ActivationUri != null)
? ApplicationDeployment.CurrentDeployment.ActivationUri
: null;
}
catch (Exception ex)
{
Trace.TraceWarning("Cannot access clickonce environment: {0}", ex.Message);
_activationUri = null;
}
}
static ClickOnce()
{
// only run if clickonce deployed, on first run only
if (ApplicationDeployment.IsNetworkDeployed &&
ApplicationDeployment.CurrentDeployment.IsFirstRun)
SetAddRemoveProgramsIcon();
}
private static void SetAddRemoveProgramsIcon(string iconPath = TaconIcon)
{
// cf.: http://stackoverflow.com/questions/10927109/custom-icon-for-clickonce-application-in-add-or-remove-programs
try
{
var assembly = Assembly.GetExecutingAssembly();
var displayName = assembly.GetProduct(); // cf. ClickOnce.targets --> ClickOnce DisplayName
//the icon is included in this program
var iconSourcePath = GetIconPath(assembly, iconPath);
if (!File.Exists(iconSourcePath))
return;
using (var uninstallKey =
Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"))
{
if (uninstallKey == null)
return;
var subKeyNames = uninstallKey.GetSubKeyNames();
foreach (var subKeyName in subKeyNames)
{
using (var myKey = uninstallKey.OpenSubKey(subKeyName, true))
{
var myValue = myKey?.GetValue("DisplayName");
if (myValue == null || myValue.ToString() != displayName)
continue;
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}
}
}
catch (Exception ex)
{
Trace.TraceWarning("Could not set Add/Remove application icon: {0}", ex);
}
}
private const string MyIcon = @"Resources\MyApp.ico";
private static string GetIconPath(Assembly assembly = null, string iconPath = MyIcon)
{
var safeAssembly = assembly ?? Assembly.GetExecutingAssembly();
var appPath = Path.GetDirectoryName(GetAssemblyLocation(safeAssembly));
// ReSharper disable once AssignNullToNotNullAttribute
return Path.Combine(appPath, iconPath);
}
private static string GetAssemblyLocation(this Assembly assembly)
{
return new Uri(assembly.CodeBase).LocalPath;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment