Добавление нескольких иконок (Win32-Resource) в .NET-приложение - PullRequest
17 голосов
/ 18 января 2012

можно установить значок приложения в свойствах проекта. Если вы сделаете это, у exe будет этот значок вместо значка по умолчанию. этот значок является win32-ресурсом, и к нему также можно получить доступ следующим образом:

change icon

Я хочу иметь специальные значки для типов файлов, которые используются моей программой. чтобы связать значок типа файла, я могу указать его в реестре («MyProg.exe, 1» в разделе «DefaultIcon»).

так как ДОБАВИТЬ БОЛЬШЕ иконок в сборку, чтобы я мог использовать ее для ассоциации типов файлов?

большое спасибо

ps: это WPF-приложение (.NET 4.0)

Ответы [ 5 ]

16 голосов
/ 18 января 2012

Windows ничего не знает об управляемых ресурсах, вам нужно добавить неуправляемые ресурсы в ваш исполняемый файл. На скриншоте parapura вам нужно выбрать переключатель Resource file. Для этого требуется файл .res, двоичный файл, созданный с помощью средства Windows SDK rc.exe для файла .rc. Файл .rc представляет собой простой текстовый файл, содержащий операторы ресурсов, подобные этому:

1 ICON "mainicon.ico"
2 ICON "alternative1.ico"
3 ICON "alternative2.ico"
1 24 "app.manifest"

Обязательно сохраните этот файл в папке вашего проекта без кодировки utf-8, лучше всего использовать Блокнот. Создайте требуемый файл app.manifest с помощью Project + Добавить новый элемент, Файл манифеста приложения. Добавьте этот файл .rc в свой проект с помощью Project + Add Existing Item. Дважды щелкните по нему и убедитесь, что вы видите значки и манифест. Щелкните правой кнопкой мыши верхний узел, добавьте ресурс и выберите «Версия + новый». Отредактируйте информацию о версии, помните, что она больше не будет автоматически соответствовать атрибутам в AssemblyInfo.cs

Вы можете скомпилировать файл .rc в файл .res с помощью командной строки Visual Studio:

rc /r something.rc

Создает файл .res, который вы можете использовать на вкладке свойств проекта. Рекомендуется делать это перед сборкой, но немного сложно понять. Количество способов, которыми это может пойти не так, многочисленно, удачи.

10 голосов
/ 10 февраля 2012

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

C:\path\to\InsertIcons.exe $(TargetPath) $(ProjectDir)icons

Дополнительное описание и файл для загрузки можно найти по адресу http://einaregilsson.com/add-multiple-icons-to-a-dotnet-application/

1 голос
/ 15 апреля 2016

Основываясь на ответах, которые я вижу - это кажется довольно тривиальным, но, к сожалению, это не так просто.

Давайте начнем с файла .rc - вы можете быстро написать файл, например так: myown.rc:

1 ICON "..\\Folder1\\icon1.ico"
2 ICON "..\\folder2\\icon2.ico"
1 24 "myown.manifest"

Но следующий вопрос - где взять файл манифеста, который вам нужен для вашего приложения.

Можно извлечь используемый в настоящее время файл манифеста, используя командную строку, например:

mt -inputresource:myOwnNetExe.exe;#1 -out:myown.manifest

И затем вы можете использовать этот манифест со своим исполняемым файлом .net.

Но это еще не все.Из самого проекта вы не можете указать относительный путь к вашему .res файлу, вы можете использовать только абсолютный путь.Сохраните .csproj и отредактируйте его вручную с помощью блокнота - чтобы сделать путь относительным.После этого проект компилируется очень хорошо.

Но в svn / git - вы, вероятно, не поместите файл .res - только исходный код.Необходимо скомпилировать .rc в .res.

Лучше всего сделать это на этапе проекта / предварительной сборки.

Но, конечно, rc.exe не может быть запущен, так как это проект C ++, и мыесть проект C #, который не заботится о путях проекта C ++.

Это можно обойти, используя шаг предварительной сборки, например:

cd $(ProjectDir)
call "%VS100COMNTOOLS%\vsvars32.bat" >nul
rc /c 1252 /nologo myown.rc

Где вам нужно изменить VS100COMNTOOLS в Visual Studio, с которойвы компилируете (я использую Visual studio 2010).

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

[DllImport("shell32.dll")]
public static extern IntPtr ExtractIcon(IntPtr hInst, string file, int nIconIndex);

[DllImport("user32.dll", SetLastError = true)]
static extern bool DestroyIcon(IntPtr hIcon);

/// <summary>
/// Sets icon from .exe or .dll into form object
/// </summary>
/// <param name="iIconIndex">Icon index to use.</param>
/// <param name="form">Form to assign to given icon</param>
/// <returns>true if ok, false if failed.</returns>
bool SetIcon( object form, int iIconIndex, String dllOrExe = null )
{
    if( dllOrExe == null )
        dllOrExe = System.Reflection.Assembly.GetExecutingAssembly().Location;

    IntPtr hIcon = ExtractIcon(IntPtr.Zero, dllOrExe, iIconIndex);

    if( hIcon == IntPtr.Zero )
        return false;

    Icon icon = (Icon) Icon.FromHandle(hIcon).Clone();
    DestroyIcon(hIcon);

    form.GetType().GetProperty("Icon").SetValue(form, icon);
    return true;
}

Где в form_load вы можете разместить вызов так:

SetIcon(this, N);

Где N = 0 для первого значка, N = 1 - для второго и т. Д.

18.5.2016 Обновление Мой подход работает нормально - однако - после этого файла сборкисвойства - информация о версии исчезает.Восстановить его можно с помощью типичного файла C ++ .rc, но, к сожалению, для меня это как-то нарушает атрибуты сборки - диспетчер задач отобразит ваш exe-файл как «Приложение».Я попытался собрать немного глубже, если возможно как-то изменить название манифеста / приложения - но безрезультатно.После этого я также использовал предложенное здесь решение InsertIcons.exe.

Так что, если вас не интересует информация о версии файла - вы можете использовать мое решение, если вам нужна версия файла, а менеджер задач должен правильно показывать ваше приложение - используйте InsertIcons.exe.Фрагмент кода C # (SetIcon) здесь будет работать для вас в любом решении.

0 голосов
/ 25 января 2017

Я успешно использовал подход InsertIcons, пока антивирус Symantec не начал отмечать мой exe как подозрительный. Я предполагаю, что Symantec не понравилось изменение подписи, связанное с тем, что он запутался в exe как шаг после сборки.

В конце концов я пошел с отдельной библиотекой классов .NET dll, скомпилированной с использованием следующего кода в файле csproj:

<PropertyGroup>
   <Win32Resource>icons.res</Win32Resource>
</PropertyGroup>

Вам не нужно устанавливать инструменты сборки c ++, но вам нужен компилятор ресурсов, как описано в принятом ответе выше.

Мой файл icons.rc выглядит так:

1  ICON  "IconA.ico"
2  ICON  "IconB.ico"
3  ICON  "IconC.ico"

И команда предварительной сборки:

"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\rc.exe" $(ProjectDir)icons.rc
0 голосов
/ 18 января 2012

Если вы зайдете в настройки своего проекта, вы увидите способ установить значок для приложения.

enter image description here

Чтобы добавить дополнительные значки ...

  • Правая кнопка мыши в Project в обозревателе решений и выберите Новый элемент , а затем Файл ресурсов
  • Дважды щелкните файл ресурсов в обозревателе решений и выберите Добавить ресурс -> Новая иконка
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...