将图标作为资源嵌入到WPF应用程序中 [英] Embed Icons into WPF Application as Resource

查看:112
本文介绍了将图标作为资源嵌入到WPF应用程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将图标嵌入我的WPF应用程序中,以便可以使用以下代码将其拉出以用作Windows 7 JumpList中的图标:

I am trying to embed an icon into my my WPF application so that I can pull it out for use as an icon in the Windows 7 JumpList using the following code:

newScene.IconResourcePath = System.Reflection.Assembly.GetEntryAssembly().Location;
newScene.IconResourceIndex = 0;

我已使用以下方法使其工作: http://dennisdel.com/?p=38

I've gotten it to work using the following method: http://dennisdel.com/?p=38

但是,它没有似乎不是最好的方法,似乎应该有一种更简单的方法将图标资源嵌入到我的应用程序中,同时仍将程序的应用程序属性中的 图标和清单选项保留为选中状态

However, it doesn't seem like the best approach and it seems like there should be an easier way to embed an icon resource into my application while still leaving the "Icon and Manifest" option checked in the Application properties for my program.

我尝试了许多方法,包括将图标构建操作设置为资源和嵌入式资源,但是每次我在资源编辑器中打开.exe时,图标不会显示。

I've tried numerous methods including setting the icon build action as a resource and an embedded resource, but every time I open my .exe in a resource editor, the icon does not appear.

有任何建议吗?

推荐答案

Visual Studio它没有从MSBuild任务执行Win32资源编译器的方法,并且没有用于创建资源的嵌入式功能会创建原始资源。因此,您的选择是:

Visual Studio does not come with a way to execute the Win32 resource compiler from a MSBuild task, and none of its embedded functionality for creating resources created raw resources. Because of this your choices are:


  1. 按照链接文章中的说明手动创建.res文件,或者

  2. 添加一个构建任务,以便您可以从.csproj中调用Win32资源编译器

首先,我将说明.exe或.dll文件中可能存在的五种不同资源之间的差异,包括JumpList所需的 Win32资源。

First I will explain the differences between the five different kinds of "resources" that can exist in a .exe or .dll file, including "Win32 Resources" that JumpList requires.

解释如何构造自定义生成任务,该任务允许您将任意Win32资源嵌入C#或VB.NET可执行文件中。

I will then explain how to construct a custom build task that allows you to embed arbitrary Win32 Resources in a C# or VB.NET executable.

.exe或.dll文件中可以存在五种不同的资源:

There are five different kinds of "resources" that can exist in a .exe or .dll file:


  • Win32资源

  • NET Framework嵌入式资源

  • CLR对象在ResourceSet中

  • XAML资源

  • WPF资源(资源中的对象电子词典)

  • Win32 Resources
  • NET Framework "Embedded Resources"
  • CLR Objects within a ResourceSet
  • XAML Resources
  • WPF Resources (Objects within a ResourceDictionary)

Win32资源

最初的一种资源是Win32资源。这种资源是在.rc文件中定义的,具有编号或命名的资源,每个资源都有一个类型和一个数据块。

Win32资源编译器rc.exe将.rc文件编译为二进制.res文件,然后可以将其添加到生成的可执行文件中。

The original kind of resource was a Win32 "Resource". This kind of resource is defined in a .rc file and has either numbered or named resources, each of which has a type and a blob of data. The
Win32 resource compiler, rc.exe, compiles the .rc file into a binary .res file can then be added to the resulting executable.

使用Win32 FindResource LoadResource 函数访问Win32资源。

Win32 resources are accessed using the Win32 FindResource and LoadResource functions.

Win32资源通过将它们添加到.rc文件中而嵌入到C ++应用程序中,该文件被编译为.res文件并链接到可执行文件中。也可以在使用rc.exe程序后添加它们。对于C#和VB.NET应用程序,MSBuild可以将预先构建的.res文件添加到通过Csc或Vbc编译器创建的可执行文件中,也可以为您构建默认文件。 C#和VB.NET都不能够从.rc文件构建非默认.res文件,并且没有MSBuild任务可以为您执行此操作。

Win32 resources are embedded into C++ applications by adding them to the .rc file, which is compiled to a .res file and linked into the executable. They can also be added after the fact using the rc.exe program. For C# and VB.NET applications, MSBuild can add a prebuilt .res file to the executable it creates via the Csc or Vbc compiler or it can build a default one for you. Neither C# nor VB.NET has the ability to build non-default .res files from .rc files, and there is no MSBuild task to do this for you.

您可以通过使用文件->打开在Visual Studio中打开.exe或.dll文件本身来查看.exe或.dll中的Win32资源。

You can view the Win32 Resources in a .exe or .dll by opening the .exe or .dll file itself in Visual Studio using File -> Open.

典型的C, C ++或MFC应用程序将具有许多Win32资源,例如,每个对话框都将由一个资源指定。

A typical C, C++ or MFC application will have many Win32 Resources, for example every dialog box will be specified by a resource.

典型的WPF应用程序将仅构造三个默认Win32资源。由C#或VB.NET编译器提供:版本资源,RT_MANIFEST和应用程序图标。这些资源的内容由代码中的Assembly属性和.csproj或.vbproj文件文件中的< ApplicationIcon> 元素构造。

A typical WPF application will have just the three default Win32 resources constructed by the C# or VB.NET compiler: The version resource, the RT_MANIFEST, and the application icon. The contents of these resources are constructed from Assembly attributes in the code and the <ApplicationIcon> element in the .csproj or .vbproj file file.

这是JumpList所需的资源。

This is the kind of resource that the JumpList is looking for.

嵌入式资源

嵌入式资源是NET Framework资源。包含这些资源的数据结构由CLR以更有利于被托管代码访问的方式进行管理。每个资源都由一个字符串名标识,按照惯例,该字符串名以与该资源关联的类的名称空间开头。

An "embedded resource" is a NET Framework resource. The data structure containing these resources is managed by the CLR in a manner more conducive for access by managed code. Each resource is identified by a string name, which by convention begins with the namespace of the class the resource is associated with.

嵌入式资源只是二进制数据的一小块一个名字。实际数据类型是调用者已知的,或者是从名称推断的,类似于文件系统中的文件。例如,名称以 .jpg结尾的嵌入式资源可能是JPEG文件。

An embedded resource is just a blob of binary data with a name. The actual data type is either known by the caller or inferred from the name, similar to files in a file system. For example, an embedded resource with a name ending in ".jpg" is likely to be a JPEG file.

使用 Assembly访问嵌入式资源.GetManifestResourceStream 及其兄弟版本 GetManifestResourceInfo GetManifestResourceNames

将嵌入的资源嵌入到.exe和.dll文件中,方法是将该文件添加到项目中,并将生成操作设置为嵌入资源。

Embedded resources are embedded into .exe and .dll files by adding the file to the project and setting the build action to "Embedded Resource".

您可以通过在NET Reflector中打开.exe或.dll来查看嵌入式资源,并查看 Resources文件夹。

You can view the Embedded Resources in a .exe or .dll by opening it in NET Reflector and looking at the "Resources" folder.

嵌入式资源通常用于WinForms,但几乎从来没有使用WPF。

Embedded resources are commonly used in WinForms but almost never with WPF.

资源集(.resx / .resources)

多个NET Framework对象(例如字符串和图标)可以组合在一起,成为单个资源集数据结构,该数据结构作为单个NET Framework嵌入式资源存储在.exe中。例如,WinForms使用它存储不容易包含在生成的代码中的图标和字符串之类的东西。

Multiple NET Framework objects such as strings and icons can be combined together into a single "Resource Set" data struture that is stored in the .exe as a single NET Framework Embedded Resource. For example this is used by WinForms to store things like icons and strings that are not easy to include in the generated code.

资源集中的对象可以使用来单独检索CLR定义的 ResourceManager ResourceSet 类。

Objects in a Resource Set can be retrieved individually using the ResourceManager and ResourceSet classes defined by the CLR.

资源集中的对象在源代码中由.resx文件定义。数据可以直接位于.resx文件中(如字符串),也可以由.resx文件引用(如图标)。在构建项目时,每个.resx文件指定的内容都将序列化为二进制形式,并存储为单个嵌入式资源,其扩展名 .resx替换为 .resources。

Objects in a Resource Set are defined in source code by a .resx file. The data can be directly in the .resx file (as in the case of strings) or referenced by the .resx file (as in the case of icons). When the project is built, the content specified by each .resx files is serialized into a binary form and stored as a single Embedded Resource with the extension ".resx" replaced by ".resources".

您可以通过以下方法来查看资源集中的对象:在NET Reflector中打开.exe或.dll,打开Resources文件夹,单击 .resources文件,然后查看右侧的项目-

You can view the objects in a Resource Set by opening the .exe or .dll in NET Reflector, opening the Resources folder, clicking on a ".resources" file, and looking at the items in the right-hand pane.

许多WinForms时代常用的.resx文件和ResourceSets功能类似于旧的Win32 .rc文件,用于存储多个资源,例如字符串all一起。 WinForms本身也使用它们来将设置存储在表单中,而这些表单不能放在后面的代码中。

Many WinForms-era features commonly used .resx files and ResourceSets in a manner similar to the old Win32 .rc files, to store multiple resources such as strings all together. They are also used by WinForms itself for storing settings on a form that cannot go in the code behind.

WPF应用程序几乎从未在ResourceSets中使用任意对象,尽管WPF本身使用资源集在内部存储已编译的XAML。

WPF applications almost never uses arbitrary objects in ResourceSets, though WPF itself uses ResourceSets internally to store compiled XAML.

XAML资源

WPF XAML资源是存储在ResourceSet中的已编译XAML文件。资源集中的名称是原始文件名,用 .xaml替换为 .g.baml。内容可以是任何有效的XAML,最常见的类型是Window,Page,UserControl,ResourceDictionary和

应用程序。

A WPF XAML Resource is a compiled XAML file that is stored inside a ResourceSet. The name inside the resource set is the original filename with ".xaml" replaced with ".g.baml". The content can be any valid XAML, the most common types being Window, Page, UserControl, ResourceDictionary, and
Application.

WPF资源可以是使用 Application.LoadComponent()加载,或通过在WPF上下文中引用原始XAML文件名加载。此外,任何具有代码后缀(由 x:Class 指定)的WPF资源都将自动加载并应用于该类在<$期间创建的每个对象。 c $ c> InitializeComponent 调用。

WPF Resources can be loaded using Application.LoadComponent() or by referencing the original XAML file name in a WPF context. In addition, any WPF Resource that has code behind (as specified by x:Class) will automatically be loaded and applied to each object that is created of that class during its InitializeComponent call.

WPF资源是通过在项目中添加.xaml文件并将其生成操作设置为资源来创建的,页面或 ApplicationDefinition。这将导致编译器将文件编译为BAML并将其添加到适当的ResourceSet中。

WPF Resources are created by adding a .xaml file to your project and setting its build action to "Resource", "Page", or "ApplicationDefinition". This causes the compiler to compile the file to BAML and add it to the appropriate ResourceSet.

您可以通过在NET中打开文件来查看.exe或.dll中的XAML资源。安装了BamlViewer加载项的Reflector,从菜单中选择工具-> BAML Viewer,然后使用BAML Viewer浏览到.resources中的特定.g.baml文件。

You can view the XAML resources in .exe or .dll by opening it in NET Reflector with the BamlViewer add-in installed, selecting Tools -> BAML Viewer from the menu, and using the BAML Viewer to browse to the specific .g.baml file inside the .resources.

ResourceDictionary中的WPF资源

在WPF中,几乎所有所谓的资源都是ResourceDictionary中的条目。在XAML中,在其他对象(例如Windows和UserControls)中或在仅包含ResourceDictionary的单独XAML文件中,都描述了ResourceDictionaries。每个对象都由 x:Key标识,该对象可以是任何对象类型。资源本身也可以是任何对象类型。

In WPF, almost all of what are known as "resources" are entries in a ResourceDictionary. The ResourceDictionaries are described in XAML, either within other objects such as Windows and UserControls, or in separate XAML files that contain only a ResourceDictionary. Each is identified by an "x:Key", which can be any object type. The resources themselves can also be any object type.

可以在XAML中使用 {StaticResource} 引用WPF资源。和 {DynamicResource} 标记扩展,或者可以使用 FindResource 在代码中加载。

WPF resources can be referenced in XAML using the {StaticResource} and {DynamicResource} markup extensions, or can be loaded in code using FindResource.

WPF资源添加到ResourceDictionary中,方法是将它们添加到XAML文件中,该文件包含在< ResourceDictionary> 元素内的ResourceDictionary,并为它们提供 x:Key 属性。

WPF resources are added to a ResourceDictionary by adding them to the XAML file that contains the ResourceDictionary inside the <ResourceDictionary> element and giving them a x:Key attribute.

WPF资源在WPF中得到广泛使用,包括画笔,样式,数据,几何图形,模板,等等。

WPF resources are used extensively in WPF, including brushes, styles, data, geometries, templates, etc.

您可以通过如上所述浏览XAML资源并查看ResourceDictionary标记中的每个资源来查看.exe或.dll中的WPF资源。

You can view the WPF Resources in a .exe or .dll by browsing the XAML Resources as described above and for each one looking inside the ResourceDictionary tags to see the resources themselves.

如何轻松嵌入任意Win32资源进入C#或VB.NET .exe

您将在上面的讨论中注意到,很容易将各种类型的资源添加到C#或VB中适用于Win32资源的.NET应用程序 except 。为简化此操作,您可以添加其他构建任务和目标。方法如下:

You will note from the discussion above that it is easy to add every type of resource to your C# or VB.NET application except for Win32 Resources. To make this easy you can add an additional build task and target. Here is how:


  1. 构造一个包含单个 Win32ResourceCompiler构建任务的项目并对其进行编译

  2. 创建一个包含单个目标的.targets文件,该目标使用此任务将.rc文件自动构建为.res

  3. 将您的项目设置为使用生成的.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文件也非常简单。遵循以下原则:

The .targets file is also very simple. It will be something along these lines:

<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文件的引用:

Now in your .csproj file, add a reference to your .targets file:

<Import Project="Win32ResourceCompiler.targets" />

当然,您需要为.rc文件指定Win32RCFile文件类型:

And of course you need to give your .rc file a file type of Win32RCFile:

<ItemGroup>
  <Win32RCFile Include="MyWin32Resources.rc" />
</ItemGroup>

通过此设置,您可以创建传统的Win32 .rc文件来指定所有Win32资源,包括版本,清单,应用程序图标以及所需的更多其他图标。每次编译时,所有这些Win32资源都将添加到您的.exe文件中。

With this setup you can create a traditional Win32 .rc file to specify all your Win32 resources, including your version, manifest, application icon, and as many additional icons as you want. Every time you compile, all these Win32 resources will be added to your .exe file.

设置起来需要花费一些时间,但在安装过程中却更加令人满意和简单。

This takes a little while to set up but is much more satisfying and simpler in the long run than manually editing a .res file.

您可以在.rc文件中指定多个图标,如下所示:

You can specify multiple icons in your .rc file like this:

1 ICON ApplicationIcon.ico
2 ICON JumpListIcon.ico
3 ICON AnotherIcon.ico

这里是可以在.rc文件中使用的所有资源定义语句的文档。

Here is the documentation for all the resource definition statements you can use in a .rc file.

还请注意,上面的.targets文件是在一时冲动,尚未经过测试。有关MSBuild(.csproj和.targets)文件语法的文档,可以找到此处此处 ,可以在c:filesWindows\Microsoft.NET\Framework\v3.5目录中找到.targets文件的好示例。

Also note that the above .targets file was typed up on the spur of the moment and has not been tested. Documentation on the syntax of MSBuild (.csproj and .targets) files can be found here and here, and good examples of .targets files can be found in the c:\Windows\Microsoft.NET\Framework\v3.5 directory).

这篇关于将图标作为资源嵌入到WPF应用程序中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆