В Visual Studio отсутствует способ запуска компилятора ресурсов Win32 из задачи MSBuild, и ни одна из его встроенных функций для создания ресурсов не создает необработанные ресурсы.По этой причине вы можете выбрать:
- Создать файл .res «вручную», как описано в связанной статье, или
- Добавить задачу сборки, чтобы можно было вызывать ресурс Win32.Компилятор из вашего .csproj
Сначала я объясню различия между пятью различными типами «ресурсов», которые могут существовать в файле .exe или .dll, включая «Ресурсы Win32», которые требуются JumpList.
Затем я объясню, как создать пользовательскую задачу сборки, которая позволяет встраивать произвольные ресурсы Win32 в исполняемый файл C # или VB.NET.
Пять видов ресурсов вИсполняемый файл Win32
Существует пять различных типов «ресурсов», которые могут существовать в файле .exe или .dll:
- Ресурсы Win32 * Встраиваемые ресурсы
- NET Framework "Ресурсы "
- Объекты CLR в ResourceSet
- Ресурсы XAML
- Ресурсы WPF (объекты в ResourceDictionary)
Ресурсы Win32
Первоначальный вид ресурса был Win32 «Ресурс».Этот тип ресурса определен в файле .rc и имеет нумерованные или именованные ресурсы, каждый из которых имеет тип и блок данных.
Компилятор ресурсов Win32, rc.exe, компилирует файл .rc в двоичный файл .res, который затем может быть добавлен к полученному исполняемому файлу.
Доступ к ресурсам Win32 осуществляется с помощью Win32 FindResource
и LoadResource
functions.
Ресурсы Win32 встраиваются в приложения C ++, добавляя их в файл .rc, который компилируется в файл .res и связывается с исполняемым файлом.Их также можно добавить по факту с помощью программы rc.exe.Для приложений на C # и VB.NET MSBuild может добавить готовый файл .res к исполняемому файлу, который он создает с помощью компилятора Csc или Vbc, или может создать файл по умолчанию для вас.Ни в C #, ни в VB.NET нет возможности создавать файлы .res, отличные от заданных по умолчанию, из файлов .rc, и для этого нет задачи MSBuild.
Вы можете просматривать ресурсы Win32 в .exeили .dll, открыв сам файл .exe или .dll в Visual Studio с помощью команды Файл -> Открыть.
Типичное приложение на C, C ++ или MFC будет иметь много ресурсов Win32, например, будет указано каждое диалоговое окно.ресурсом.
Типичное приложение WPF будет иметь только три ресурса Win32 по умолчанию, созданные компилятором C # или VB.NET: ресурс версии, RT_MANIFEST и значок приложения.Содержимое этих ресурсов создается из атрибутов Assembly в коде и элемента <ApplicationIcon>
в файле .csproj или .vbproj.
Это ресурс, который ищет JumpList.
Встроенные ресурсы
«Встроенный ресурс» - это ресурс NET Framework.Структура данных, содержащая эти ресурсы, управляется CLR более удобным способом для доступа через управляемый код.Каждый ресурс идентифицируется строковым именем, которое по соглашению начинается с пространства имен класса, с которым связан ресурс.
Встроенный ресурс - это просто двоичный объект двоичных данных с именем.Фактический тип данных либо известен вызывающему, либо выведен из имени, аналогично файлам в файловой системе.Например, встроенный ресурс с именем, оканчивающимся на «.jpg», скорее всего, будет файлом JPEG.
Доступ к встроенным ресурсам осуществляется с использованием Assembly.GetManifestResourceStream
и его дочерних элементов GetManifestResourceInfo
и GetManifestResourceNames
. * 1063.*
Встроенные ресурсы встраиваются в файлы .exe и .dll, добавляя файл в проект и устанавливая для действия сборки значение «Встроенный ресурс».
Вы можете просматривать встроенные ресурсы в .exe или.dll, открыв ее в NET Reflector и просмотрев папку «Ресурсы».
Встроенные ресурсы обычно используются в WinForms, но почти никогда не используются в WPF.
Наборы ресурсов (.resx / .resources)
Несколько объектов NET Framework, таких как строки и значки, можно объединить в одно хранилище данных «Набор ресурсов», которое хранится в .exe в виде единого встроенного ресурса NET Framework. Например, это используется WinForms для хранения таких вещей, как значки и строки, которые нелегко включить в сгенерированный код.
Объекты в наборе ресурсов могут быть извлечены индивидуально с использованием классов ResourceManager
и ResourceSet
, определенных в CLR.
Объекты в наборе ресурсов определяются в исходном коде файлом .resx. Данные могут быть непосредственно в файле .resx (как в случае строк) или ссылаться на файл .resx (как в случае значков). Когда проект создается, содержимое, указанное в каждом файле .resx, сериализуется в двоичную форму и сохраняется как один встроенный ресурс с расширением «.resx», заменяемым на «.resources».
Вы можете просмотреть объекты в наборе ресурсов, открыв .exe или .dll в NET Reflector, открыв папку «Ресурсы», щелкнув файл «.resources» и посмотрев элементы в правой панели.
Многие функции эпохи WinForms обычно используют файлы .resx и ResourceSets аналогично старым файлам Win32 .rc для хранения нескольких ресурсов, таких как строки, вместе. Они также используются самой WinForms для хранения настроек в форме, которая не может быть в коде позади.
Приложения WPF почти никогда не используют произвольные объекты в ResourceSets, хотя сам WPF использует ResourceSets для внутреннего хранения скомпилированного XAML.
Ресурсы XAML
Ресурс XAML WPF - это скомпилированный файл XAML, который хранится в ResourceSet. Имя внутри набора ресурсов - это исходное имя файла, в котором «.xaml» заменено на «.g.baml». Содержимое может быть любым допустимым XAML, наиболее распространенными типами являются Window, Page, UserControl, ResourceDictionary и
Применение.
Ресурсы WPF можно загрузить с помощью Application.LoadComponent()
или путем ссылки на исходное имя файла XAML в контексте WPF. Кроме того, любой ресурс WPF, имеющий код позади (как указано x:Class
), будет автоматически загружен и применен к каждому объекту, созданному из этого класса во время его вызова InitializeComponent
.
Ресурсы WPF создаются путем добавления файла .xaml в проект и установки для его действия по сборке «Ресурс», «Страница» или «ApplicationDefinition». Это заставляет компилятор скомпилировать файл в BAML и добавить его в соответствующий ResourceSet.
Вы можете просмотреть ресурсы XAML в .exe или .dll, открыв их в NET Reflector с установленной надстройкой BamlViewer, выбрав в меню Сервис -> BAML Viewer и используя BAML Viewer, чтобы перейти к конкретному. Файл g.baml внутри .resources.
Ресурсы WPF в ResourceDictionary
В WPF почти все из того, что известно как «ресурсы», являются записями в ResourceDictionary. ResourceDictionaries описаны в XAML, либо в других объектах, таких как Windows и UserControls, либо в отдельных файлах XAML, которые содержат только ResourceDictionary. Каждый из них обозначен «x: Key», который может быть любого типа объекта. Сами ресурсы также могут быть объектами любого типа.
На ресурсы
на WPF можно ссылаться в XAML с использованием расширений разметки {StaticResource}
и {DynamicResource}
, или их можно загружать в коде с использованием FindResource
.
Ресурсы WPF добавляются в ResourceDictionary путем добавления их в файл XAML, который содержит ResourceDictionary внутри элемента <ResourceDictionary>
, и присвоения им атрибута x:Key
.
Ресурсы WPF широко используются в WPF, включая кисти, стили, данные, геометрию, шаблоны и т. Д.
Вы можете просматривать ресурсы WPF в .exe или .dll, просматривая ресурсы XAML, как описано выше, и для каждого, заглядывая в теги ResourceDictionary, чтобы увидеть сами ресурсы.
Включение ресурсов Win32 в исполняемый файл C # или VB.NET
Как легко встраивать произвольные ресурсы Win32 в C # или VB.NET .exe
Из приведенного выше обсуждения вы заметите, что легко добавить любой тип ресурса в ваше приложение на C # или VB.NET , за исключением для ресурсов Win32. Чтобы сделать это проще, вы можете добавить дополнительную задачу сборки и цель. Вот как:
- Создайте проект, содержащий одну задачу сборки "Win32ResourceCompiler", и скомпилируйте его
- Создайте файл .targets, содержащий одну цель, которая использует эту задачу для автоматического встраивания файла .rc в .res
- Настройте ваш проект на использование полученного файла .res
Задача предельно проста:
public class Win32ResourceCompiler : ToolTask
{
public ITaskItem Source { get; set; }
public ITaskItem Output { get; set; }
protected override string ToolName { get { return "rc.exe"; } }
protected override string GenerateCommandLineCommands()
{
return @"/r /fo """ + Output.ItemSpec + @""" """ + Source.ItemSpec + @"""";
}
protected override string GenerateFullPathToTool()
{
// TODO: Return path to rc.exe in your environment
}
}
Файл .targets также очень прост. Это будет что-то вроде этого:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="SomeNamespace.Win32ResourceCompiler" AssemblyFile="Something.dll" />
<PropertyGroup>
<CoreCompileDependsOn>$(CoreCompileDependsOn);CompileWin32RCFile</CoreCompileDependsOn>
</PropertyGroup>
<Target Name="CompileWin32RCFile" Outputs="@(Win32RCFile->'%(filename).res')">
<Win32ResourceCompiler
Source="@(Win32RCFile)"
Output="@(Win32RCFile->'%(filename).res')" />
</Target>
</Project>
Теперь в вашем файле .csproj добавьте ссылку на ваш файл .targets:
<Import Project="Win32ResourceCompiler.targets" />
И, конечно же, вам нужно указать в файле .rc тип файла Win32RCFile:
<ItemGroup>
<Win32RCFile Include="MyWin32Resources.rc" />
</ItemGroup>
С помощью этой настройки вы можете создать традиционный Win32 .rc файл, чтобы указать все ваши ресурсы Win32, включая вашу версию, манифест, значок приложения и столько дополнительных значков, сколько вы хотите. Каждый раз, когда вы компилируете, все эти ресурсы Win32 будут добавляться в ваш файл .exe.
Это займет немного времени для настройки, но в долгосрочной перспективе будет гораздо более приятным и простым, чем ручное редактирование файла .res.
Вы можете указать несколько значков в вашем файле .rc следующим образом:
1 ICON ApplicationIcon.ico
2 ICON JumpListIcon.ico
3 ICON AnotherIcon.ico
Здесь - документация для всех операторов определения ресурса, которые вы можете использовать в файле .rc.
Также обратите внимание, что вышеупомянутый файл .targets был набран под влиянием момента и не был протестирован. Документацию по синтаксису файлов MSBuild (.csproj и .targets) можно найти здесь и здесь , а хорошие примеры файлов .targets можно найти в каталоге c: \ Windows \ Microsoft.NET \ Framework \ v3.5).