Search code examples
javawindowsnsislaunch4jtaskbar

Win 7 pin to task bar + launch4j + NSIS


We struggle to make the Java Swing App named JabRef (http://jabref.sourceforge.net/) pinnable to the task bar of Windows. What we did so far:

  • set the AppModelUserID in JabRef through JNA. We verified the correct value through output
  • build fat jar and from this an executable (exe) with launch4j
  • create an installer with NSIS using the WinShell plugin
  • the installer creates a shortcut using the same AppModelUserID that is set in JabRef. We verified this via a hex editor.
  • grouping works: you can start either via shortcut or exe
  • what does NOT work: right-click on task bar item only shows "close application" action, nothing else.

Any ideas how to debug any further?

This shows the right-click menu. enter image description here


Solution

  • If the pinned shortcut is not "taken over" by the application when you run it then the AppModelUserIDs are not set correctly.

    You can verify the ID in a .lnk by using this tool (shellproperty.exe read "System.AppUserModel.ID" from "%appdata%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\MyApp.lnk")

    In a running application the AppModelUserID can be set per window and/or on the process. Querying these is a bit harder for external apps but you can call them on yourself with GetCurrentProcessExplicitAppUserModelID and SHGetPropertyStoreForWindow.

    If Windows thinks your application is a hosted app then it will hide the pin menu-item, see Registering an Application as a Host Process. It looks like Java applications are registered as a host process.

    If either the process itself or the shortcut file used to launch the process has an explicit AppUserModelID, then the host process list is ignored and the application is treated as a normal application by the taskbar. The application's running windows are grouped together under a single taskbar button and the application can be pinned to the taskbar.

    My only suggestion is to use JNA/JNI to call SetCurrentProcessExplicitAppUserModelID in both your launcher application (if it is a separate process) and in your main application hosted by javaw.exe.