';添加或删除程序';C#ClickOnce应用程序的图标

';添加或删除程序';C#ClickOnce应用程序的图标,c#,winforms,icons,C#,Winforms,Icons,我在堆栈溢出问题中尝试了该解决方案 下面是我的实现。它们都可以编译,并且在代码运行时不会引发异常。我正在将ClickOnce安装文件发布到Web服务器,然后在从计算机卸载后安装它。当我进入“控制面板”“添加或删除程序”时,仍然会看到程序的通用图标。在其他任何地方,我都没有问题,我的图标显示得很好 /* METHOD ONE */ private static void SetAddRemoveProgramsIcon() { //Only run if deployed if

我在堆栈溢出问题中尝试了该解决方案

下面是我的实现。它们都可以编译,并且在代码运行时不会引发异常。我正在将ClickOnce安装文件发布到Web服务器,然后在从计算机卸载后安装它。当我进入“控制面板”“添加或删除程序”时,仍然会看到程序的通用图标。在其他任何地方,我都没有问题,我的图标显示得很好

/*  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());
        }
    }
}
*/
/*方法一*/
私有静态void SetAddRemoveProgramsIcon()
{
//仅在部署时运行
if(System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed&&ApplicationDeployment.CurrentDeployment.IsFirstRun)
{
尝试
{
汇编代码=Assembly.getExecutionGassembly();
AssemblyDescriptionAttribute asdescription=
GetCustomAttribute(代码,类型(AssemblyDescriptionAttribute));
string assemblyDescription=asdescription.Description;
//该图标包含在此程序中
字符串iconSourcePath=Path.Combine(System.Windows.Forms.Application.StartupPath,“forico4.ico”);
如果(!File.Exists(iconSourcePath))
返回;
RegistryKey myUninstallKey=Registry.CurrentUser.OpenSubKey(@“Software\Microsoft\Windows\CurrentVersion\Uninstall”);
字符串[]mySubKeyNames=myUninstallKey.GetSubKeyNames();
for(int i=0;i
在查看注册表并复制其他应用程序的设置后,我终于找到了答案。奇怪的是,您无法在ClickOnce部署的应用程序中引用EXE文件。至少我不能让它工作。因此,我转而引用
.ico
。请务必阅读评论

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());
        }
    }
}
使用System.Deployment.Application;
使用Microsoft.Win32;
//请尽快调用此方法
私有静态void SetAddRemoveProgramsIcon()
{
//仅在第一次安装或更新后的第一次运行时执行
if(ApplicationDeployment.CurrentDeployment.IsFirstRun)
{
尝试
{
//设置应用程序EXE文件的名称-确保在末尾包含“%0”。
//据我所知,不适用于ClickOnce应用程序…注意,这可能会起作用
//从Visual Studio运行时,但在部署时不运行。
//字符串iconSourcePath=Path.Combine(System.Windows.Forms.Application.StartupPath,“example.exe,0”);
//改为使用此选项(请注意,从VisualStudio运行时,此选项可能不起作用,但在部署时起作用。
字符串iconSourcePath=Path.Combine(System.Windows.Forms.Application.StartupPath,“example.ico”);
如果(!File.Exists(iconSourcePath))
{
MessageBox.Show(“我们找不到应用程序图标。请将此错误通知您的软件供应商。”);
返回;
}
RegistryKey myUninstallKey=Registry.CurrentUser.OpenSubKey(@“Software\Microsoft\Windows\CurrentVersion\Uninstall”);
字符串[]mySubKeyNames=myUninstallKey.GetSubKeyNames();
for(int i=0;i
您只需通过以下代码即可完成

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)

我使用VB和VS2013E.St使用了相同的技术
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
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
  private static void SetAddRemoveProgramsIcon()
        {


            //Only execute on a first run after first install or after update
            if (ApplicationDeployment.CurrentDeployment.IsFirstRun)
            {
                try
                {

                //Getting path to the installation directory
                System.Reflection.Assembly assemblyInfo = System.Reflection.Assembly.GetExecutingAssembly(); 
                string assemblyLocation = assemblyInfo.Location;
                Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
                string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());

                string iconSourcePath = Path.Combine(ClickOnceLocation, "youricon.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");                                            
                        // 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() == "SafeShare Outlook Add-in")
                        {                        
                        myKey.SetValue("DisplayIcon", iconSourcePath);
                            break;
                        }
                    }
                }
                catch (System.Exception mye)
                {
                    MessageBox.Show("We could not properly setup the application icons. Please notify your software vendor of this error.\r\n" + mye.ToString());
                }
            }

             }