Программно изменить значок исполняемого файла

Я разрабатываю приложение под названием WeatherBar. Его основная функциональность основана на его взаимодействии с панелью задач Windows 7 - он меняет значок в зависимости от погодных условий в определенном месте.

Все значки, которые я использую в приложении, хранятся в скомпилированном файле собственных ресурсов (.res) - я использую его вместо встроенного манифеста ресурсов только для значков. По умолчанию я изменяю свойство Icon основной формы, чтобы соответствующим образом изменить значки, и оно работает нормально, пока значок не закреплен на панели задач. Когда он закрепляется, значок на панели задач автоматически переключается на значок по умолчанию для исполняемого файла (с индексом 0 в файле ресурсов).

Проведя небольшое исследование, я решил, что способ изменить значок - это изменить значок ярлыка (поскольку все закрепленные приложения на самом деле являются ярлыками, хранящимися в папке пользователя). Но это не сработало.

Я предполагаю, что мне нужно изменить значок исполняемого файла и, следовательно, использовать UpdateResource, но я не совсем уверен в этом. Мой исполняемый файл не имеет цифровой подписи, поэтому его изменение не должно вызывать проблем.

Как бы можно было решить эту проблему?


person Den Delimarsky    schedule 29.03.2010    source источник
comment
@Vivek Это не решает проблему и не решает ее.   -  person Den Delimarsky    schedule 29.03.2010
comment
На самом деле я использую Windows API Code Pack для управления списками переходов и прогрессом на панели задач, но я не вижу возможности (на данный момент) заменить значок исполняемого файла.   -  person Den Delimarsky    schedule 29.03.2010
comment
msdn.microsoft.com/en-us/magazine/dd942846.aspx# id0420051 windowsteamblog.com/blogs/developers/archive/2009/07/28/ Посмотрите OverlayImage в APICodePack.   -  person JohnForDummies    schedule 29.03.2010
comment
OverlayIcon - это немного другое дело. Проблема в том, что он показывает свернутый значок (16x16) в углу, тогда как в моем случае он должен отображаться как основной значок приложения. В крайнем случае - я воспользуюсь этим.   -  person Den Delimarsky    schedule 30.03.2010


Ответы (3)


Если вы хотите сделать это программно, я бы начал с просмотра Portable Формат исполняемого файла (запись в Википедии). Раздел ресурсов (.rsrc, см. Раздел 6.9) должен содержать значок. Используя эту информацию, вы можете написать инструмент для изменения значка.

Если вы просто хотите быстро изменить значок в существующем файле, вы можете взломать его в редакторе ресурсов Visual Studio. Я проверил это с файлом, удалив старый значок и добавив новый. Значок .exe изменился в проводнике на новый значок, и новый значок появился в меню «Пуск», когда я перетащил его туда.

-- Редактировать --

Да, я согласен с использованием UpdateResource это хороший подход. Вот пример, который я обнаружил использования для этого функций C ++, и подпись P / Invoke для UpdateResource и FindResource.

person Paul Williams    schedule 06.04.2010
comment
Интересный подход. Хотя есть проблема - редактор ресурсов - хороший инструмент, и я использовал его некоторое время, но мне нужно изменить значок прямо в коде. Конечный пользователь не сможет использовать редактор ресурсов для изменения значка каждую минуту. - person Den Delimarsky; 07.04.2010

 private void button1_Click(object sender, EventArgs e)
    {
      String path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
      String name = "test";
      Shell32.Shell shl = new Shell32.ShellClass();
      // Optional code to create the shortcut
      System.IO.StreamWriter sw = new System.IO.StreamWriter(path + @"\" + name + ".lnk", false);
      sw.Close();
      // End optional code
      Shell32.Folder dir = shl.NameSpace(path);
      Shell32.FolderItem itm = dir.Items().Item(name + ".lnk");
      Shell32.ShellLinkObject lnk = (Shell32.ShellLinkObject)itm.GetLink;
      // Optional code to create the shortcut
      lnk.Path = Environment.GetFolderPath(Environment.SpecialFolder.System)
+ @"\notepad.exe";
      lnk.Description = "nobugz was here";
      lnk.Arguments = @"c:\sample.txt";
      lnk.WorkingDirectory = @"c:\";
      // End optional code
      lnk.SetIconLocation(Environment.GetFolderPath(Environment.SpecialFolder.System)
+ "cmd.exe", 1);
      lnk.Save(null);
    }

Это было взято из http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/9e23a82c-8bed-4b96-8b9a-4c2b6136a622/

Это может помочь.

person Art W    schedule 29.03.2010
comment
Выглядит знакомо. Здесь нет решения. - person Hans Passant; 29.03.2010
comment
Как упоминал nobugz, это не решение. Мне нужно изменить значок в самом исполняемом файле, а не в ярлыке. - person Den Delimarsky; 29.03.2010

Решил реализовать обходной путь - в миниатюре окна изменится значок (это возможно в Windows 7). Если значок откреплен, пользователь может увидеть изменение значка. Если он закреплен, эскиз будет изменяться в соответствии с текущими погодными условиями.

Мне кажется, что структура закрепленных значков (фактически являющаяся ярлыком) не позволяет динамически изменять значок. Если я ошибаюсь, я открыт для комментариев и идей по этому поводу.

person Den Delimarsky    schedule 26.04.2010