Original question
I use Launch4j as a wrapper for my Java application under Windows 7, which, to my understanding, in essence forks an instance of javaw.exe
that in turn interprets the Java code. As a result, when attempting to pin my application to the task bar, Windows instead pins javaw.exe
. Without the required command line, my application will then not run.
As you can see, Windows also does not realize that Java is the host application: the application itself is described as "Java(TM) Platform SE binary".
I have tried altering the registry key HKEY_CLASSES_ROOT\Applications\javaw.exe
to add the value IsHostApp
. This alters the behavior by disabling pinning of my application altogether; clearly not what I want.
After reading about how Windows interprets instances of a single application (and a phenomenon discussed in this question), I became interested in embedding a Application User Model ID (AppUserModelID) into my Java application.
I believe that I can resolve this by passing a unique AppUserModelID
to Windows. There is a shell32
method for this, SetAppID()
. (Or SetCurrentProcessExplicitAppUserModelID
?) Is it possible to call it via JNI? If so, would this even resolve the issue?
On a side note, I was curious if any of the APIs discussed in this article could be implemented for a Java application.
Edit after implementing JNA, as Gregory Pakosz suggested
I've now implemented the following in an attempt to have my application recognized as a separate instance of javaw.exe
:
NativeLibrary lib;
try {
lib = NativeLibrary.getInstance("shell32");
} catch (Error e) {
Logger.out.error("Could not load Shell32 library.");
return;
}
Object[] args = { "Vendor.MyJavaApplication" };
String functionName = "SetCurrentProcessExplicitAppUserModelID";
try {
Function function = lib.getFunction(functionName);
int ret = function.invokeInt(args);
if (ret != 0) {
Logger.out.error(function.getName() + " returned error code "
+ ret + ".");
}
} catch (UnsatisfiedLinkError e) {
Logger.out.error(functionName + " was not found in "
+ lib.getFile().getName() + ".");
// Function not supported
}
This appears to have no effect, but the function returns without error. Diagnosing why is something of a mystery to me. Any suggestions?
Working implementation
The final implementation that worked is the answer to my follow-up question concerning how to pass the AppID
using JNA.
I had awarded the bounty to Gregory Pakosz' brilliant answer for JNI that set me on the right track.