固定Java应用的Windows7栏
-
11-09-2019 - |
题
我用Launch4j作为包装,对于我Java应用程序,在Windows7,其中,我的理解是,在本质上叉的一个实例 javaw.exe
这反过来解释Java代码。结果,在试图销我的应用程序的任务吧,Windows,而不是脚 javaw.exe
.没有必要的命令行,我的应用程序将不会运行。
正如你可以看到,窗户也没有意识到爪哇的主机应用程序:该应用程序本身是描述为"Java(TM)平台SE二进制"。
我已经尝试改变登记册的关键 HKEY_CLASSES_ROOT\Applications\javaw.exe
添加价值 IsHostApp
.这种改变行为的禁用钉住我的应用程序完全;显然不是我想要的。
在阅读有关 Windows如何解释的实例,一个单一的应用程序 (及 一个现象中讨论这个问题),我产生了兴趣,在嵌入一个应用程序的用户模型ID(AppUserModelID)进入我的Java应用程序。
我相信,我可以解决这个问题通过一个独特的 AppUserModelID
到窗户。还有一个 shell32
方法这一点, SetCurrentProcessExplicitAppUserModelID
.以下格雷戈里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
}
这似乎没有任何效果,但该功能将返回没有错误。诊断为什么是某种谜给我。任何建议?
工作执行情况
最后的执行工作的是 回答我的后续行动的问题 关于如何通过 AppID
使用南国防军.
我已经授予金格雷戈里Pakosz'辉煌的答案JNI,我在正确的轨道。
作为参考,我相信使用这种技术可能使用的任何Api讨论 在这篇文章 在Java应用程序。
解决方案
我没有窗户,7但是,这里是什么,可能让你开始:
Java面:
package com.stackoverflow.homework;
public class MyApplication
{
static native boolean setAppUserModelID();
static
{
System.loadLibrary("MyApplicationJNI");
setAppUserModelID();
}
}
和在地面,在对源代码的`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的解决方案。然而,由于应用程序不需要任何其他机的方法, 南国防军 是另一个解决方案,将保存你从文字母代码只是为了转移到windows api。如果你决定去南国防军,注意到这一事实, SetCurrentProcessExplicitAppUserModelID()
期待一个UTF-16串。
当它的工作在你的沙盒,下一步是增加操作系统的检测在应用程序 SetCurrentProcessExplicitAppUserModelID()
显然只适用于Windows7:
- 你可以做到这一点从Java侧的检查
System.getProperty("os.name");
返回"Windows 7"
. - 如果你从小JNI段我给了你可以增强它通过动态加载
shell32.dll
库使用LoadLibrary
然后回来的SetCurrentProcessExplicitAppUserModelID
功能使用的指针GetProcAddress
.如果GetProcAddress
返回NULL
, 它意味着的符号并不存在shell32
因此,它不Windows7。
编辑: 南国防军解决方案.
参考文献:
- JNI书 为更JNI实例
- Java地访问(南国防军)
其他提示
有是一个Java库提供所述新的Windows 7用于Java。这就是所谓的 J7Goodies: //www.strixcode.com”的rel = “noreferrer”>施特里克斯代码。使用它的应用程序可适当固定到Windows 7任务栏。您也可以创建自己的跳转列表等。
尝试使用 JSmooth 。我总是用这一个。在JSmooth是有称为下Skeleton
的选项由Windowed Wrapper
在EXE过程劳克Java应用程序
请参阅此图像上。
另外的命令行参数可被传递。结果, 我想,这可能是你的解决方案。
马亭
我已经使用JNA实现访问SetCurrentProcessExplicitAppUserModelID方法和使用时作为MSDN文档建议它工作得很好。我从来没有在你在你的代码段有办法使用的JNA API。我的实现符合典型JNA用法代替。
首先,接口SHELL32定义:
interface Shell32 extends StdCallLibrary {
int SetCurrentProcessExplicitAppUserModelID( WString appID );
}
然后,使用JNA加载SHELL32并调用该函数
final Map<String, Object> WIN32API_OPTIONS = new HashMap<String, Object>() {
{
put(Library.OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
put(Library.OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
}
};
Shell32 shell32 = (Shell32) Native.loadLibrary("shell32", Shell32.class,
WIN32API_OPTIONS);
WString wAppId = new WString( "Vendor.MyJavaApplication" );
shell32.SetCurrentProcessExplicitAppUserModelID( wAppId );
许多过去你所提到的化妆使用的Windows COM这是相当困难的直接与JNA使用的文章中的API的。我已经取得了一些成功创建自定义DLL来调用这些API的(例如使用SHGetPropertyStoreForWindow用来设置子模块的窗口不同的应用程序ID),我然后使用JNA在运行时访问。
SetCurrentProcessExplicitAppUserModelID(或SetAppID())实际上会做你想做什么。但是,它可能是更容易修改您的安装设置你的快捷方式AppUserModel.ID属性 - 从的上述应用程序用户模型ID 文件:
在 System.AppUserModel.ID 一>应用程序的快捷方式文件的属性。的快捷方式(作为的IShellLink,CLSID_ShellLink,或.lnk文件)支持整个外壳用来通过IPropertyStore和其他属性设定机制的特性。这允许在任务栏,以确定恰当的快捷方式到引脚,并确保属于工艺窗口被适当地与该任务栏按钮相关联。 注意:创建快捷方式时,System.AppUserModel.ID属性应该应用到的快捷方式。当使用Microsoft Windows安装程序(MSI)安装应用程序时,的 MsiShortcutProperty 表允许在安装过程中被创建时的AppUserModelID要被施加到该快捷方式。
最新jna-platform
库现在包括JNA绑定SetCurrentProcessExplicitAppUserModelID
:
我固定矿而没有任何ID设置。 有一个在Launch4J一种选择,如果你正在使用它,你说你怎么办呢?
可以改变标头JNI桂然后它环绕与JRE的罐子。 好事是它运行.exe文件的过程中,而不是现在与你的JAR运行的javaw.exe。它可能做它的引擎盖(不知道)下。 另外我也注意到,它需要较少的40-50%左右的CPU资源是再好不过了!
和牵制工作正常,所有的窗口功能被启用。
我希望它能帮助的人,因为我花了近2天试图解决这个问题,我的未修饰的JavaFX应用程序。