gpt4 book ai didi

java - 将 Java 应用程序固定到 Windows 7 任务栏

转载 作者:IT老高 更新时间:2023-10-28 20:54:00 24 4
gpt4 key购买 nike

我在 Windows 7 下使用 Launch4j 作为我的 Java 应用程序的包装器,据我了解,它实质上派生了一个 javaw.exe 的实例,该实例反过来解释了 Java 代码。因此,当尝试将我的应用程序固定到任务栏时,Windows 改为固定 javaw.exe。如果没有所需的命令行,我的应用程序将无法运行。

Result of pinning a Launch4j application to the taskbar

如您所见,Windows 也没有意识到 Java 是宿主应用程序:应用程序本身被描述为“Java(TM) Platform SE 二进制文件”。

我已尝试更改注册表项 HKEY_CLASSES_ROOT\Applications\javaw.exe 以添加值 IsHostApp。这通过完全禁用我的应用程序的固定来改变行为;显然不是我想要的。

Result of specifying javaw.exe as a host application

在阅读了 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 .

引用资料:

关于java - 将 Java 应用程序固定到 Windows 7 任务栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1834599/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com