dotnet / wpf

WPF is a .NET Core UI framework for building Windows desktop applications.
MIT License
7.04k stars 1.17k forks source link

Change taskbar icon at runtime on deployed app #3590

Open vic-yes opened 3 years ago

vic-yes commented 3 years ago

I would like to change taskbar icon to identity what type the current app is, so I set a default icon for the app and the icon will be changed according to the type returned from server when the app is launching.

I just change the icon like this:

Application.Current.MainWindow.Icon = new BitmapImage(new Uri(string.Format("AppLogos/{0}.ico", terminal.TerminalType.Name), UriKind.Relative));

It's working well on Visual Studio but I found out that it's not changing my task bar on deployed app (Install the app using a MSI file).

So is there a way to do it?

UPDATE

To force the icon refresh on my deployed app I have to pin/unpin my icon taskbar, unfortunately this is a user command only so I can't do this in wpf programmatically.

lindexi commented 3 years ago

@563203132 Maybe you forget to package the AppLogos files.

vic-yes commented 3 years ago

@lindexi Thank you for your reply. I’m totally sure these files have been packaged in because the top-left attached icon has been changed.

lindexi commented 3 years ago

@563203132 Could you upload a mini repo?

ryalanms commented 3 years ago

Thanks, @563203132. We need a test project to investigate further.

vic-yes commented 3 years ago

Hi @lindexi , @ryalanms , please try the following test project. Source Code: Demo.zip Installer: Demo_Installer.zip

It's working well on Visual Studio: image image

but it doesn't work on the deployed app: image image

vic-yes commented 3 years ago

@ryalanms , @lindexi , any updates? or anything else do you need me to provide?

musli commented 3 years ago

@563203132 Hello, I try to copy all the files released by your msi to the D disk and find that you can replace the icon normally, not anywhere on the C disk, you can try to add administrator rights to your application, then package and try

lindexi commented 3 years ago

@563203132 This issue appears to be a file permission issue. Thank you @musli

Try putting the program in a folder that normal permissions can access, such as a D: drive

Translation:

看起来是文件权限的问题,@musli 尝试将 msi 安装完成后的内容拷贝出来放在 D 盘,此时可以正常运行,显示符合预期的图标

细节请加群 714704041

vic-yes commented 3 years ago

Hi @musli , @lindexi , thanks, I tried to just copy the build package before, but it's still not working to install the app to D disk even though running it with administrator permission, it doesn't seem to be a permission problem, the icon can't be changed as long as running it in the install folder.

musli commented 3 years ago

@563203132 @lindexi After many experiments, the icon of the taskbar is always equal to the icon of the startup file, such as changing the icon of the shortcut to the program to a tiger, then the icon of the taskbar where the program runs will also be a tiger. image

vic-yes commented 3 years ago

@musli , It seems not, the taskbar icon will be changed when I pin/unpin the taskbar. image image image

Seems there is a cache, but I don't know how to refresh it programmatically.

musli commented 3 years ago

@563203132

  1. I just said that way you can try, build a shortcut for "Demo.exe", and then modify the icon of this shortcut to run the program, you will find that the icon of the taskbar is the icon you just modified
  2. I've rewritten a packaging profile here, the packaged program is normal, maybe you can try it (I'm packaging with Visual Studio's WIX template)

DemoInstall.zip

[msi]DemoInstall.zip

vic-yes commented 3 years ago

@musli , Thanks, but I would like to build an All-In-One terminal, that says there are some terminal types, I can config the type of a terminal dynamically in the server(it means a terminal can be an email app or a browser app at different moments, that's controlled completely in the server.), and the taskbar icon can be changed accordingly to identify what type the terminal is when the terminal is launching, so the shortcut of the terminal is just a default icon, only when the terminal is launching does it know what icon should be displayed.

musli commented 3 years ago

@563203132 I found an interesting thing 1.The taskbar of "Demo.exe" released by msi does not change as the icon of the form changes

  1. However, if you modify "Demo.exe" to "Demo1.exe" and run it again, the icon of the taskbar will change as the icon of the form changes This means that you can create a "Run.exe" as the main program, and then use "Run.exe" to start "Demo.exe" to solve the problem, although this approach is a bit frustrating Demo Video.zip
vic-yes commented 3 years ago

@musli , thanks for you help, and I believe there must be a normal way can be solve it unless it's a underlying bug.

cregx commented 3 years ago

I think that it is a bug. I tried @musli's idea, creating a runner.exe that runs the real application. As of now, changing the application icon in the taskbar under the following conditions has worked.

  1. if I call the runner.exe directly from the program directory.
  2. or if I pin a shortcut to the runner.exe in the start (pin to start).

But now it gets interesting: If I pin the original exe in addition to the pinned runner.exe in the startup, then the change of the application icon in the taskbar does not work anymore.

So, in my opinion, the problem is related to Windows' own shortcut management.

musli commented 3 years ago

@563203132 @lindexi Maybe there's a problem with your packaging, and I created a wix SetupProject that uses it to compile a .msi installation package, and the program that runs out doesn't have that problem There's also a small finding that your problem won't exist when the taskbar doesn't merge icons (from Quicker of master) Demo.zip

TwoTinyTrees commented 2 years ago

Hey there! I am having the EXACT same issue. BUT, I noticed that when I login to the machine as a local account (i.e. non-domain user), the app icon shows as I'd expect in the Taskbar. HOWEVER, when I then pin, the icon goes to the undesired state. I un-pin, and it shows as I wish it to, but THEN I simply right-click the icon and it reverts and I cannot pin or unpin any longer. WTF!!!

vishalmsft commented 2 years ago

@vic-yes @TwoTinyTrees
The issue is with how OS is caching the icons. If you will try native applications, the observation will remain same. Simple set of setups will be just to replace the raw resource in the cmd.exe after pinning. The icon for cmd.exe will get updated, but, the icon used for pinning isn't. If you unpin, you can see the original icon.

Renaming the exe file fixes the issue. I will recommend to close the issue here and have one opened with Windows team.

Thank you

jespersh commented 2 years ago

Before you do, could you check these calls are hit? https://github.com/dotnet/wpf/blob/b63c69eaf5b58e758765a37bb18064bbc94832ad/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Window.cs#L3977-L3987

chj124 commented 2 years ago

I had struggled with this same issue for a while. We have an app in the Startup group in Windows. The app starts minimized and changes its icon after it launches yet the taskbar keeps the default icon, not the forms current icon. If it starts with the form visible this isn't a problem.

One simple solution was to create a console app that calls the real app. Put the launcher in the startup. This solved my problem, app starts minimized and uses the current form icon which was generated after the app starts.

Simple launcher code: var appName = ConfigurationManager.AppSettings.Get("AppToRun"); Process.Start(appName);