我在 Windows 7 下使用 Launch4j 作为我的 Java 应用程序的包装器,据我了解,它实质上派生了一个 javaw.exe
的实例,该实例反过来解释了 Java 代码。因此,当尝试将我的应用程序固定到任务栏时,Windows 改为固定 javaw.exe
。如果没有所需的命令行,我的应用程序将无法运行。
如您所见,Windows 也没有意识到 Java 是宿主应用程序:应用程序本身被描述为“Java(TM) Platform SE 二进制文件”。
我已尝试更改注册表项 HKEY_CLASSES_ROOT\Applications\javaw.exe
以添加值 IsHostApp
。这通过完全禁用我的应用程序的固定来改变行为;显然不是我想要的。
在阅读了 how Windows interprets instances of a single application 之后(和 a phenomenon discussed in this question ),我开始有兴趣将应用程序用户模型 ID (AppUserModelID) 嵌入到我的 Java 应用程序中。
我相信我可以通过将唯一的 AppUserModelID
传递给 Windows 来解决此问题。有一个 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
}
这似乎没有效果,但函数返回没有错误。诊断为什么对我来说是个谜。有什么建议吗?
工作实现
最终的实现是the answer to my follow-up question关于如何使用 JNA 传递 AppID
。
我已将赏金授予 Gregory Pakosz 对 JNI 的出色回答,这让我走上了正轨。
作为引用,我相信使用这种技术可以使用所讨论的任何 API in this article在 Java 应用程序中。
最佳答案
我没有 Windows 7,但这里有一些可以帮助您入门的东西:
在 Java 方面:
package com.stackoverflow.homework;
public class MyApplication
{
static native boolean setAppUserModelID();
static
{
System.loadLibrary("MyApplicationJNI");
setAppUserModelID();
}
}
而在 native 端,在`MyApplicationJNI.dll 库的源代码中:
JNIEXPORT jboolean JNICALL Java_com_stackoverflow_homework_MyApplication_setAppUserModelID(JNIEnv* env)
{
LPCWSTR id = L"com.stackoverflow.homework.MyApplication";
HRESULT hr = SetCurrentProcessExplicitAppUserModelID(id);
return hr == S_OK;
}
您的问题明确要求 JNI 解决方案。但是,由于您的应用程序不需要任何其他 native 方法,jna是另一种解决方案,它可以让您不必为了转发到 windows api 而编写 native 代码。如果您决定使用 jna,请注意 SetCurrentProcessExplicitAppUserModelID()
需要一个 UTF-16 字符串。
当它在您的沙箱中工作时,下一步是在您的应用程序中添加操作系统检测,因为 SetCurrentProcessExplicitAppUserModelID()
显然仅在 Windows 7 中可用:
- 您可以通过检查
System.getProperty("os.name");
返回"Windows 7"
来从 Java 端执行此操作。 - 如果您从我提供的 JNI 小片段构建,您可以通过使用
LoadLibrary
动态加载shell32.dll
库来增强它然后使用GetProcAddress
取回SetCurrentProcessExplicitAppUserModelID
函数指针.如果GetProcAddress
返回NULL
,则表示shell32
中不存在该符号,因此它不是 Windows 7。
编辑:JNA Solution .
引用资料:
- The JNI book更多 JNI 示例
- Java Native Access (JNA)
关于java - 将 Java 应用程序固定到 Windows 7 任务栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1834599/