从代码更改 WPF 程序集图标

发布于 2024-08-12 14:29:00 字数 175 浏览 7 评论 0原文

有没有办法从代码中更改 WPF 程序集图标?我指的不是窗口图标,而是 .exe 文件上显示的图标。

编辑:

我试图在应用程序图标的表示中实现交互性 - 不同的用户启动的操作与当前状态相结合应该会导致不同的应用程序图标。我依赖于应用程序的视觉表示,因为它没有可见的窗口,并且交互基于热键和一般系统使用模式。

Is there a way to change a WPF assembly icon from code? I'm not referring to the window icon, but to the icon that appears on the .exe file.

EDIT:

I'm trying to achieve interactivity in the application icon's representation - different user-initiated actions combined with a current state should lead to a different application icon. I rely on the visual representation of the application as it has no visible window and the interaction is based on hot-keys and general system usage patterns.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

安稳善良 2024-08-19 14:29:00

概述

更改 .exe 文件中的图标很简单,但有点麻烦。您可能需要做三件事:

  1. 防止正在运行的进程锁定 .exe 文件,这会阻止它被修改
  2. 可能修改文件权限以使其可写
  3. 实际编辑 .exe 文件以替换图标

详细信息

步骤 3 - 实际编辑 .exe 文件 - 是最有趣的,所以我将从这里开始。您将在 kernel32.dll 中使用 BeginUpdateResource()UpdateResource()EndUpdateResource() 调用。基本上您是这样做的:

byte[] data = File.ReadAllBytes(newIconFilePath);
       // Or otherwise load icon data

IntPtr hUpdate = BeginUpdateResource(exePath, false);
UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(1), LANG_SYSTEM_DEFAULT,
               data, data.Length);
EndUpdateResource(hUpdate, false);

您需要为函数添加 DllImport 声明并实现常量。有关如何操作的详细信息,请参阅 MSDN 上的文档 BeginUpdateResourceUpdateResourceEndUpdateResource 工作。

对于第 1 步 - 防止 .exe 被锁定 - 简单的解决方案是向应用程序启动添加代码,以检查当前 .exe 是否正在从临时目录运行 (Path.GetTempPath())。如果没有,它会使用 File.Copy() 将 .exe 以及所需的任何其他文件复制到临时目录,然后使用一个提供原始 .exe 位置的附加命令行参数来执行它。然后原始进程退出,删除 .exe 文件上的锁定。

对于第 2 步 - 更正权限 - 这只是修改 ACL 并可能触发 UAC 对话框的问题。那里有很多示例,您可能不需要这样做,因此我将跳过进一步的解释

最终说明

上述步骤实际上允许您编辑真实 . exe 文件。但是,如果您只需要更改视觉图标,我建议您使用快捷方式并编辑其图标。

Overview

Changing the icon in your .exe file is straightforward though a bit cumbersome. You'll potentially need to do three things:

  1. Prevent your running process from holding a lock on the .exe file which would prevent it from being modified
  2. Possibly modify file permissions to make it writable
  3. Actually edit the .exe file to replace the icon

Details

Step 3 - actually editing the .exe file - is the most interesting, so I'll start there. You will use the BeginUpdateResource(), UpdateResource() and EndUpdateResource() calls in kernel32.dll. Basically you do this:

byte[] data = File.ReadAllBytes(newIconFilePath);
       // Or otherwise load icon data

IntPtr hUpdate = BeginUpdateResource(exePath, false);
UpdateResource(hUpdate, RT_ICON, MAKEINTRESOURCE(1), LANG_SYSTEM_DEFAULT,
               data, data.Length);
EndUpdateResource(hUpdate, false);

You'll need to add DllImport declarations for the functions and implement the constants. See the documentation on MSDN for details on how BeginUpdateResource, UpdateResource, and EndUpdateResource work.

For step 1 - preventing your .exe from being locked - the easy solution is to add code to your application startup that checks to see if the current .exe is running from the temporary directory (Path.GetTempPath()). If not, it copies the .exe to the temporary directory using File.Copy() along with any additional files needed, then executes it with one additional command line argument that gives the location of the original .exe. The original process then exits, removing the lock on the .exe file.

For step 2 - correcting permissions - this simply a matter of modifying the ACLs and possibly triggering a UAC dialog. There are plenty of examples out there and you probably don't need to do this, so I'll skip further explanation

Final note

The above steps will actually allow you to edit the actual icon of your real .exe file. However if you just need a visual icon change I would recommend you use a shortcut and edit its icon instead.

濫情▎り 2024-08-19 14:29:00

您在文件夹窗口中查看 exe 时看到的图标是在 exe 内部设置的,可以从代码中更改该图标,但这比您想象的要麻烦。

您在开始菜单、桌面和快速启动工具栏上看到的图标都设置在快捷方式文件中(每个位置都有不同的文件),编辑这些文件并不困难。

您可以使用 Com 和 IShellLink 来完成
http://msdn.microsoft.com/en- us/library/bb776891%28VS.85%29.aspx

这是一个简化事情的包装类:
http://vbaccelerator.com/home/NET/Code/ Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/article.asp

您还可以使用 Windows 脚本主机来完成此操作:
http://www.codeproject.com/KB/dotnet/shelllink.aspx

The icon that you see when looking at the exe in a folder window is set inside the exe, it is possible to change that icon from code but it's more trouble than you think.

The icons you see on the start menu, desktop and quick launch toolbar are set in shortcut files (a different file on each location), editing those files isn't that difficult.

You can do it with Com and IShellLink
http://msdn.microsoft.com/en-us/library/bb776891%28VS.85%29.aspx

Here's a wrapper class that simplifies things:
http://vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/Creating_and_Modifying_Shortcuts/article.asp

You can also do it with windows scripting host:
http://www.codeproject.com/KB/dotnet/shelllink.aspx

岁月静好 2024-08-19 14:29:00

Nir 建议使用快捷方式确实是最好的方法,如果您想要改变实际的桌面图标。

对于无窗口应用程序来说,更好的方法可能是在通知区域安装一个图标。您可以在通知区域中阅读有关在 win32 中添加/更改图标的详细信息 此处。 .NET 通过 System.Windows.Forms 支持此功能。通知图标。这些 API 中的任何一个都可以让您根据需要更改/设置图标动画;为您提供一个经批准的地点来通知用户事件;并为您提供一个中心位置,让用户使用菜单与您的应用程序进行交互。这还有一个好处,即使窗口最大化,您的图标仍然可见(前提是用户没有隐藏它,在这种情况下您可能想让他们这样做)。

另请参阅 Windows 7 指南以礼貌地使用通知区域。使用操作系统总是比反对它更容易。

Nir's suggestion to use shortcuts is really your best approach if you want to make the actual desktop icon change.

Probably a better approach for a windowless application is install an icon in the notification area. You can read up on the details of adding / changing an icon in win32 in the notification area here. .NET supports this functionality through System.Windows.Forms.NotifyIcon. Either of these APIs will let you change/animate the icon as desired; give you an approved place to notify the user of events; and give you a central place to let the user interact with your application using menus. This also has the benefit that even when windows are maximized, your icon is still visible (providing that the user hasn't hidden it, in which case you probably want to let them do so).

See also, Windows 7 guidelines for polite usage of the notification area. It's always easier to work with the operating system than against it.

阳光下的泡沫是彩色的 2024-08-19 14:29:00

嗯,您不应该在 exe 文件运行时更改它!

程序集图标在项目文件中定义。您可以在构建过程中更改它,但在应用程序运行后就不能更改

您想实现什么目标?

Ummm, you are not meant to change an exe file while it is running!

The assembly icon is defined in the project file. You can change that as part of the build process but not once the application is running

What are you trying to achieve?

诠释孤独 2024-08-19 14:29:00

来自 msdn

当系统显示图标时,它必须从.exe或.dll文件中提取适当的图标图像。系统使用以下步骤来选择图标图像:

1) 选择 RT_GROUP_ICON 资源。如果存在多个此类资源,则 Microsoft Windows NT/Windows 2000/Windows XP 将使用资源脚本中列出的第一个资源,而 Windows 95/Windows 98/Windows Millennium Edition (Windows Me) 将选择按字母顺序列出的第一个资源。

2) 从 RT_GROUP_ICON 资源中选择适当的 RT_ICON 图像。如果存在多个图像,系统将使用以下标准来选择图像:
选择尺寸最接近要求尺寸的图像。
如果存在两个或多个该尺寸的图像,则选择与显示器颜色深度相匹配的图像。

如果没有图像与显示器的颜色深度完全匹配,则选择具有不超过显示器的颜色深度的最大颜色深度的图像。如果都超过颜色深度,则选择颜色深度最低的。

对我来说,解决这个问题的自然方法是改变 Windows 资源管理器的行为方式。
我建议你看看 shell 扩展。您也许可以编写一个 shell 扩展,根据某些状态更改图标或使用图标覆盖来指示状态。其中最棘手的部分是让您的 shell 扩展了解应用程序状态。

一个可执行文件可以有多个图标资源,外壳扩展可以从应用程序提供的图标中获取特定的图标。

From msdn:

When the system displays an icon, it must extract the appropriate icon image from the .exe or .dll file. The system uses the following steps to select the icon image:

1) Select the RT_GROUP_ICON resource. If more than one such resource exists, Microsoft Windows NT/Windows 2000/Windows XP uses the first resource listed in the resource script, while Windows 95/Windows 98/Windows Millennium Edition (Windows Me) chooses the first resource listed in alphabetical order.

2) Select the appropriate RT_ICON image from the RT_GROUP_ICON resource. If more than one image exists, the system uses the following criteria to choose an image:
The image closest in size to the requested size is chosen.
If two or more images of that size are present, the one that matches the color depth of the display is chosen.

If no images exactly match the color depth of the display, the image with the greatest color depth that does not exceed the color depth of the display is chosen. If all exceed the color depth, the one with the lowest color depth is chosen.

The natural way - to me - to approach this is to change the way windows explorer behaves.
I suggest you take a look at shell extensions. You might be able to write a shell extension that changes the icon based on some state or uses icon overlays to indicate state. The trickiest part of that would be to make your shell extension aware of the application state.

An executable file can have more than one icon resource, an shell extension could get a specific icon from the icons offered in the application.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文