2013-04-26 9 views
5

Próbowałem rozwiązanie w przepełnienie stosu pytań Custom icon for ClickOnce application in 'Add or Remove Programs' i Is there a way to change the icon of a ClickOnce application in 'Add or Remove Programs'?.„Dodaj lub usuń programy” ikony dla aplikacji C# ClickOnce

Oto moje implementacje. Zarówno kompilacja, jak i wyjątki są generowane podczas uruchamiania kodu. Publikuję pliki instalacyjne ClickOnce na serwerze internetowym, a następnie instaluję je po odinstalowaniu z komputera. Po przejściu do panelu sterowania Dodaj lub usuń programy, nadal widzę ogólną ikonę dla mojego programu. Wszędzie indziej nie mam problemów i ikona pojawia się dobrze.

/* METHOD ONE */ 
private static void SetAddRemoveProgramsIcon() 
{ 
    //Only run if deployed 
    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed && ApplicationDeployment.CurrentDeployment.IsFirstRun) 
    { 
     try 
     { 
      Assembly code = Assembly.GetExecutingAssembly(); 
      AssemblyDescriptionAttribute asdescription = 
       (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(code, typeof(AssemblyDescriptionAttribute)); 
      string assemblyDescription = asdescription.Description; 

      //The icon is included in this program 
      string iconSourcePath = Path.Combine(System.Windows.Forms.Application.StartupPath, "forico4.ico"); 

      if (!File.Exists(iconSourcePath)) 
       return; 

      RegistryKey myUninstallKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"); 
      string[] mySubKeyNames = myUninstallKey.GetSubKeyNames(); 
      for (int i = 0; i < mySubKeyNames.Length; i++) 
      { 
       RegistryKey myKey = myUninstallKey.OpenSubKey(mySubKeyNames[i], true); 
       object myValue = myKey.GetValue("DisplayName"); 
       if (myValue != null && myValue.ToString() == "admin") 
       { 
        myKey.SetValue("DisplayIcon", iconSourcePath); 
        break; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      System.Windows.Forms.MessageBox.Show(ex.Message.ToString()); 
     } 
    } 
} 
*/ 

/* METHOD TWO */ 
private static void SetAddRemoveProgramsIcon() 
{ 
    //only run if deployed 
    if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed 
     && ApplicationDeployment.CurrentDeployment.IsFirstRun) 
    { 
     try 
     { 
      string iconSourcePath = Path.Combine(System.Windows.Forms.Application.StartupPath, "forico4.ico"); 
      if (!File.Exists(iconSourcePath)) 
       return; 

      RegistryKey myUninstallKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"); 
      string[] mySubKeyNames = myUninstallKey.GetSubKeyNames(); 
      for (int i = 0; i < mySubKeyNames.Length; i++) 
      { 
       RegistryKey myKey = myUninstallKey.OpenSubKey(mySubKeyNames[i], true); 
       object myValue = myKey.GetValue("DisplayName"); 
       if (myValue != null && myValue.ToString() == "GoldMailAkamai") 
       { 
        myKey.SetValue("DisplayIcon", iconSourcePath); 
        break; 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.ToString()); 
     } 
    } 
} 
*/ 

Odpowiedz

3

W końcu zorientowałem się, po obejrzeniu rejestru i skopiowaniu innych ustawień aplikacji. Dziwne, że nie można odwoływać się do pliku EXE w wdrożonej aplikacji ClickOnce. Przynajmniej nie mogłem go uruchomić. Więc zamiast tego powróciłem do odwołania do .ico. Pamiętaj, aby przeczytać komentarze!

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(@"Software\Microsoft\Windows\CurrentVersion\Uninstall"); 
      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.\r\n" + mye.ToString()); 
     } 
    } 
} 
+0

Dlaczego nie możemy tego zrobić bez włamywania do rejestru? – HackSlash

0

Możesz to zrobić po prostu za pomocą poniższego kodu.

string Install_Reg_Loc = @"Software\Microsoft\Windows\CurrentVersion\Uninstall"; 

string displayIcon = @"C:\MorganTech\setup-icon.ico"; 

RegistryKey hKey = (Registry.LocalMachine).OpenSubKey(Install_Reg_Loc, true); 

RegistryKey appKey = hKey.OpenSubKey(productName); 

appKey.SetValue("DisplayIcon", (object)displayicon, RegistryValueKind.String) 
1

Użyłem tej samej techniki przy użyciu VB i VS2013E. Kroki:

  1. Kliknij prawym przyciskiem myszy węzeł projektu w Eksploratorze rozwiązań.
  2. Dodaj Exisitng -> Logo.ico
  3. Obserwuj, czy plik został dodany do drzewa projektu.
  4. Kliknij ten wpis prawym przyciskiem myszy i wybierz "Właściwości".
  5. "Kopiuj do katalogu wyjściowego" wybierz "Kopiuj zawsze".

Kroki te zapewniły, że plik Logo.ico jest pakowany we wdrożeniu. Bloki kodu są następujące:

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("Software\Microsoft\Windows\CurrentVersion\Uninstall") 
      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 

Wywołanie funkcji zwraca wartość true, jeśli zostanie wykonana zamierzona czynność. Fałszywe w przeciwnym razie. W formularzu głównym, wywołanie funkcji tak:

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 

Dzięki autorów niniejszej delegowania i specjalne podziękowania dla Custom icon for ClickOnce application in 'Add or Remove Programs'.

Powiązane problemy