问题
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.
回答1:
Overview
Changing the icon in your .exe file is straightforward though a bit cumbersome. You'll potentially need to do three things:
- Prevent your running process from holding a lock on the .exe file which would prevent it from being modified
- Possibly modify file permissions to make it writable
- 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.
回答2:
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
回答3:
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.
回答4:
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?
回答5:
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.
来源:https://stackoverflow.com/questions/1797461/change-wpf-assembly-icon-from-code