Created
April 19, 2016 16:10
-
-
Save mkoertgen/524b64a8a48cc6991b8308f6aa6d41a4 to your computer and use it in GitHub Desktop.
ClickOnce: Setting a custom icon in 'Add/Remove Programs'
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.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