私は Windows 7 で Java アプリケーションのラッパーとして Launch4j を使用しています。私の理解では、これは本質的にそのインスタンスをフォークjavaw.exe
し、次に Java コードを解釈します。その結果、アプリケーションをタスク バーにピン留めしようとすると、代わりに Windows がピン留めされますjavaw.exe
。必要なコマンド ラインがなければ、アプリケーションは実行されません。
ご覧のとおり、Windows は Java がホスト アプリケーションであることも認識していません。アプリケーション自体は「Java(TM) Platform SE バイナリ」として記述されています。
HKEY_CLASSES_ROOT\Applications\javaw.exe
値を追加するためにレジストリ キーを変更しようとしましたIsHostApp
。これにより、アプリケーションのピン留めが完全に無効になり、動作が変更されます。明らかに私が欲しいものではありません。
Windows が 1 つのアプリケーションのインスタンスをどのように解釈するか(およびこの質問で説明されている現象) について読んだ後、Java アプリケーションにアプリケーション ユーザー モデル ID (AppUserModelID) を埋め込むことに興味を持つようになりました。
これは、Windowsに固有の を渡すことで解決できると思いAppUserModelID
ます。これにはshell32
方法がありSetCurrentProcessExplicitAppUserModelID
ます。Gregory Pakosz の提案に従って、アプリケーションが の別のインスタンスとして認識されるように実装しました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
}
これは効果がないように見えますが、関数はエラーなしで戻ります。理由を診断することは、私にとって謎のようなものです。助言がありますか?
実用的な実装
機能した最終的な実装は、 JNA を使用して渡す方法に関する私のフォローアップの質問に対する答えです。AppID
私は、Gregory Pakosz の JNI に対する素晴らしい回答に報奨金を授与し、私を正しい軌道に乗せました。
参考までに、この手法を使用すると、この記事で説明した API のいずれかを Java アプリケーションで使用できるようになると思います。