将多个图标(Win32-Resource)添加到.NET应用程序
可以在Project Properties中设置Application-Icon。 如果你这样做,exe将有这个图标而不是默认的图标。 此图标是win32资源,也可以像这样访问:
我想有我的程序使用的文件类型的特殊图标。 要关联文件类型图标我可以在注册表中指定它(“DefaultIcon”键中的“MyProg.exe,1”)。
那么如何将更多图标添加到我可以将它用于文件类型关联的程序集中?
非常感谢你
ps:它是一个WPF应用程序(.NET 4.0)
Windows对托管资源一无所知,您需要将非托管资源添加到可执行文件中。 在parapura的屏幕截图中,您需要选择Resource file
单选按钮。 这需要一个.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 + Add New Item,Application Manifest File创建所需的app.manifest文件。 使用Project + Add Existing Item将此.rc文件添加到项目中。 双击它并validation您是否可以看到图标和清单。 右键单击顶部节点“添加资源”,然后单击“版本+新建”。 编辑版本信息,请注意它将不再自动匹配AssemblyInfo.cs中的属性
您可以使用Visual Studio命令提示符将.rc文件编译为.res文件:
rc /r something.rc
这会生成您可以在项目属性选项卡中使用的.res文件。 这样做是预建事件是可取的,但有点难以正确。 这可能出错的方式很多,祝你好运。
我刚刚创建了一个简单的工具来完成这个,而不必乱用.res文件。 它是一个很小的实用程序,您可以将其用作Post-Build事件的一部分,并允许您将特定文件夹中的所有图标文件添加到程序集中。 如果我们假设您的主项目文件夹下有一个icons文件夹,则可以添加以下post-build事件:
C:\path\to\InsertIcons.exe $(TargetPath) $(ProjectDir)icons
有关详细说明和下载,请访问http://einaregilsson.com/add-multiple-icons-to-a-dotnet-application/
基于我看到的答案 – 它似乎很微不足道,但遗憾的是它不是那么简单。
让我们从.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
你需要用你正在编译的visual studio更改VS100COMNTOOLS的地方(我正在使用Visual Studio 2010)。
而这仍然不是一切。 如果你想在飞行中更改你的应用程序的图标 – 你可能会对这样的代码snipet感兴趣:
[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); /// /// Sets icon from .exe or .dll into form object /// /// Icon index to use. /// Form to assign to given icon /// true if ok, false if failed. 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#code snipet(SetIcon)在任何解决方案中都适合您。
如果转到项目设置,您将看到设置应用程序图标的方法。
要添加其他图标……
- 在解决方案资源管理器中的项目上的鼠标右键,选择New Item ,然后选择Resources File
- 双击解决方案资源管理器中的资源文件,然后选择添加资源 – >新图标
我成功使用了InsertIcons方法,直到赛门铁克反病毒开始将我的exe标记为可疑。 我的猜测是,赛门铁克并不喜欢签名的变化,这些变化伴随着作为后期构建步骤的exe。
最后,我使用了一个单独的.NET dll类库,使用csproj文件中的以下代码编译:
icons.res
您不需要安装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