2012-01-18 120 views
16

可以在项目属性中设置应用程序图标。如果你这样做的exe文件将有这个图标,而不是默认的。这个图标是一个Win32的资源,也可以像这样访问:将多个图标(Win32资源)添加到.NET应用程序

change icon

我想为这是我的程序中使用的文件类型的特殊图标。关联一个文件类型图标,我可以在注册表中指定它(在“DefaultIcon”键中的“MyProg.exe,1”)。

so 如何添加更多图标到我可以用于filetype-association的程序集?

非常感谢你

PS:这是一个WPF的应用程序(.NET 4.0)

回答

15

Windows不知道任何关于托管资源的信息,您需要将非托管的资源添加到您的可执行文件中。在parapura的屏幕截图中,您需要选择单选按钮。这需要一个.res文件,这是一个通过在.rc文件上运行Windows SDK rc.exe工具创建的二进制文件。 rc文件是包含资源语句,类似这样的一个简单的文本文件:

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

一定要将此文件保存到项目文件夹,而不UTF-8编码,使用记事本是最好的。使用Project +添加新项目,应用程序清单文件创建所需的app.manifest文件。使用Project + Add Existing Item将此.rc文件添加到您的项目中。双击它并确认您可以看到图标和清单。右键单击顶部节点添加资源,然后单击版本+新建。编辑版本信息,谨防其将不再自动匹配的AssemblyInfo.cs属性

您可以编译rc文件到.RES与Visual Studio命令提示文件:

rc /r something.rc 

哪生成可在项目属性选项卡中使用的.res文件。这样做是预先建立事件是可取的,但有点难以正确。这可能出错的方式很多,祝你好运。

+0

问题解决。但我已经使用[ResEdit](http://www.resedit.net/)创建了rc/res文件。它可以完美运行 – 0xDEADBEEF 2012-01-18 22:37:39

+0

或者只是将包含此类资源的本机DLL部署到应用程序中,因此您不必运行自定义工具或丢失版本信息。 – 2012-02-10 07:30:10

+0

这种方法会丢失文件版本信息,并且如果您还原它(例如使用C++版本风格的.rc文件) - 您仍然会遇到任务管理器/应用程序标题不正确的问题。 (请参阅我自己的解决方案并在最后更新它。)因此,请使用InsertIcons.exe!不要使用官方的Microsoft工具! :-) – TarmoPikaro 2016-05-18 15:43:56

0

如果你去你的项目设置,你会看到一个方法来设置应用程序的图标。

enter image description here

要添加其他图标...

    在解决方案资源管理项目
  • 鼠标右键,并选择新建项目然后资源文件
  • 双击资源文件在解决方案资源管理器中,并选择添加资源 - >新图标
+0

我知道。我已经做到了。如果我编译这个,EXE有选定的图标。但如何添加更多的图标? – 0xDEADBEEF 2012-01-18 15:56:41

+0

@ 0xDEADBEEF请看到我的编辑 – 2012-01-18 16:00:17

+2

不起作用(添加Resource1.resx,装载ICO文件和清洁+构建解决方案)。嗯,我忘了提及(明确)我的程序是WPF/.NET4-应用程序 – 0xDEADBEEF 2012-01-18 16:28:24

8

我刚刚创建了一个简单的工具来完成此操作,而不必惹恼.res文件。这是一个小实用程序,您可以将其用作生成后事件的一部分,并允许您将特定文件夹中的所有图标文件添加到程序集中。如果我们假设你有你的主项目文件夹下的图标文件夹,你可以添加以下生成后事件:

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

进一步的说明和下载可以在http://einaregilsson.com/add-multiple-icons-to-a-dotnet-application/

+0

伟大的工具!完美满足我们的需求。谢谢! – CMerat 2014-05-29 15:05:23

0

基于答案中找到它我看到 - 这似乎相当微不足道,但不幸的是它并不那么简单。

让我们从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++项目程序。

这可以通过使用这样的预构建步骤walkarounded:

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

如果您需要更改VS100COMNTOOLS与你正在编译(我使用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#代码snipet(SetIcon)将适用于任何解决方案。

0

我用InsertIcons成功地接近,直到赛门铁克防病毒开始下垂了我的exe文件为可疑。我的猜测是赛门铁克不喜欢签名中的变化,这是随着exe作为后期构建步骤而出现的。

在我在的csproj文件中使用下面的代码编译一个单独的.NET的DLL类库去年底:

<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 
相关问题