Solución:
Finalmente lo descubrí después de mirar el registro y copiar la configuración de otra aplicación. Es extraño que no pueda hacer referencia al archivo EXE en una aplicación implementada con ClickOnce. Al menos no pude hacer que funcionara. Entonces, volví a hacer referencia al .ico
en lugar de. ¡Asegúrate de leer los comentarios!
using System.Deployment.Application;
using Microsoft.Win32;
//Call this method as soon as possible
private static void SetAddRemoveProgramsIcon()
{
//Only execute on a first run after first install or after update
if (ApplicationDeployment.CurrentDeployment.IsFirstRun)
{
try
{
// Set the name of the application EXE file - make sure to include `,0` at the end.
// Does not work for ClickOnce applications as far as I could figure out... Note, this will probably work
// when run from Visual Studio, but not when deployed.
//string iconSourcePath = Path.Combine(System.Windows.Forms.Application.StartupPath, "example.exe,0");
// Reverted to using this instead (note this will probably not work when run from Visual Studio, but will work on deploy.
string iconSourcePath = Path.Combine(System.Windows.Forms.Application.StartupPath, "example.ico");
if (!File.Exists(iconSourcePath))
{
MessageBox.Show("We could not find the application icon. Please notify your software vendor of this error.");
return;
}
RegistryKey myUninstallKey = Registry.CurrentUser.OpenSubKey(@"SoftwareMicrosoftWindowsCurrentVersionUninstall");
string[] mySubKeyNames = myUninstallKey.GetSubKeyNames();
for (int i = 0; i < mySubKeyNames.Length; i++)
{
RegistryKey myKey = myUninstallKey.OpenSubKey(mySubKeyNames[i], true);
object myValue = myKey.GetValue("DisplayName");
Console.WriteLine(myValue.ToString());
// Set this to the display name of the application. If you are not sure, browse to the registry directory and check.
if (myValue != null && myValue.ToString() == "Example Application")
{
myKey.SetValue("DisplayIcon", iconSourcePath);
break;
}
}
}
catch(Exception mye)
{
MessageBox.Show("We could not properly setup the application icons. Please notify your software vendor of this error.rn" + mye.ToString());
}
}
}
Seguí la misma técnica usando VB y VS2013E. Pasos:
- Haga clic con el botón derecho en el nodo del proyecto en el Explorador de soluciones.
- Agregar Exisitng -> Logo.ico
- Observe que el archivo se agrega al árbol del proyecto.
- Haga clic derecho en esta entrada y seleccione “Propiedades”.
- “Copiar al directorio de salida” seleccione “Copiar siempre”.
Los pasos aseguraron que el archivo Logo.ico esté empaquetado en la implementación. Los bloques de código son los siguientes:
Imports System.Deployment.Application.ApplicationDeployment
Imports System.Reflection
Imports System.IO
Imports Microsoft.Win32
Module ControlPanelIcon
' Call this method as soon as possible
' Writes entry to registry
Public Function SetAddRemoveProgramsIcon() As Boolean
Dim iName As String = "iconFile.ico" ' <---- set this (1)
Dim aName As String = "appName" ' <---- set this (2)
Try
Dim iconSourcePath As String = Path.Combine(System.Windows.Forms.Application.StartupPath, iName)
If Not IsNetworkDeployed Then Return False ' ClickOnce check
If Not CurrentDeployment.IsFirstRun Then Return False
If Not File.Exists(iconSourcePath) Then Return False
Dim myUninstallKey As RegistryKey = Registry.CurrentUser.OpenSubKey("SoftwareMicrosoftWindowsCurrentVersionUninstall")
Dim mySubKeyNames As String() = myUninstallKey.GetSubKeyNames()
For i As Integer = 0 To mySubKeyNames.Length Step 1
Dim myKey As RegistryKey = myUninstallKey.OpenSubKey(mySubKeyNames(i), True)
Dim myValue As Object = myKey.GetValue("DisplayName")
If (myValue IsNot Nothing And myValue.ToString() = aName) Then
myKey.SetValue("DisplayIcon", iconSourcePath)
Return True
End If
Next i
Catch ex As Exception
Return False
End Try
Return False
End Function
End Module
La llamada a la función devuelve verdadero si se realiza la acción deseada. Falso de lo contrario. En el formulario principal, llamada a función como esta:
Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
' Modify registry to show icon in Control Panel - Add/Remove Programs
ControlPanelIcon.SetAddRemoveProgramsIcon()
End Sub
Gracias a los colaboradores de esta publicación, y un agradecimiento especial al ícono personalizado para la aplicación ClickOnce en ‘Agregar o quitar programas’.