Использование JNA для получения / установки идентификатора приложения
на мой предыдущий вопрос о панели задач Windows 7, Я хотел бы диагностировать, почему Windows не признает, что мое приложение не зависит от javaw.exe
. В настоящее время у меня есть следующий код JNA для получения AppUserModelID
:
public class AppIdTest {
public static void main(String[] args) {
NativeLibrary lib;
try {
lib = NativeLibrary.getInstance("shell32");
} catch (Error e) {
System.err.println("Could not load Shell32 library.");
return;
}
Object[] functionArgs = new Object[1];
String functionName = null;
Function function;
try {
functionArgs[0] = new String("Vendor.MyJavaApplication")
.getBytes("UTF-16");
functionName = "GetCurrentProcessExplicitAppUserModelID";
function = lib.getFunction(functionName);
// Output the current AppId
System.out.println("1: " + function.getString(0));
functionName = "SetCurrentProcessExplicitAppUserModelID";
function = lib.getFunction(functionName);
// Set the new AppId
int ret = function.invokeInt(functionArgs);
if (ret != 0) {
Logger.out.error(function.getName() + " returned error code "
+ ret + ".");
}
functionName = "GetCurrentProcessExplicitAppUserModelID";
function = lib.getFunction(functionName);
// Output the current AppId
System.out.println("2: " + function.getString(0));
// Output the current AppID, converted from UTF-16
System.out.println("3: "
+ new String(function.getByteArray(0, 255), "UTF-16"));
} catch (UnsupportedEncodingException e) {
System.err.println("System does not support UTF-16 encoding.");
} catch (UnsatisfiedLinkError e) {
System.err.println(functionName + " was not found in "
+ lib.getFile().getName() + ".");
}
}
}
выход приложения, по-видимому, тарабарщина:
1: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
2: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
3: ????????????????P???????????
зная о том, что выход может быть UTF-16, в (3) я попытался преобразовать массив байтов из UTF-16. Честно говоря, я не знаю, правильно ли мой подход здесь, поскольку (a) я не знаю размер PWSTR
и (б) я не знаю, если GetCurrentProcessExplicitAppUserModelID
действительно возвращает массив байтов или строка.
Я знаю, что JSmooth будет запускать процесс GUI в оболочке, которая имитирует этот эффект. Launch4j утверждает, что делает то же самое, но, похоже, не работает. Я ищу, чтобы иметь AppUserModelID
set независимо от оболочки Java.
что происходит здесь?
3 ответов
Я не видел ваш вопрос раньше, иначе я бы дал попробовать даже без награды.
вот что я придумал. обратите внимание, как указано в самом коде, я не реализовал надлежащую очистку памяти с помощью
Если вам просто нужно установить AppUserModelId, то вышеуказанного кода JNA достаточно. Однако, если вы хотите воспользоваться новыми функциями Windows 7 в приложении Java, проверьте J7Goodies библиотека Java, предоставляющая расширения панели задач Windows 7.
редактировать: Подробнее от J7Goodies руководство программиста
4.2. Настройка AppUserModelID
для использования любого из Функции Windows 7, приложение должно явно задать идентификатор процесса – ID модели пользователя приложения (
AppUserModelID
). Он не может иметь больше, чем 128 символов и не может содержать пробелы. Каждый раздел должен быть верблюжья шкура, например:CompanyName.ProductName.SubProduct.VersionInformation
этот идентификатор должен быть установлен перед отображением любого GUI (окна). Вы устанавливаете его, вызывая:
// Remember to set AppUserModelID before creating any UI
AppUserModelId.setCurrentProcessId("StrixCode.J7Goodies.Appname");
4.3. Настройка Свойств Окна
приложение Java не может быть прикреплен к панели задач Windows 7, если не определены ее свойства окна. Этот свойства состоят из четырех полей:
- AppUserModelID-то же самое, что прошло в
AppUserModelId.setCurrentProcessId(String)
- RelaunchDisplayName-имя приложения
- RelaunchCommand-полная команда, используемая для запуска приложения. В случае Java-программы это будет:
<path to javaw.exe> -jar <path to application jar>
- RelaunchIcon-путь к значку приложения
важно:
RelaunchCommand
иRelaunchDisplayName
всегда должен быть установлен вместе. Чтобы задать эти свойства, используйте простой класс WindowProperties.
WindowProperties props = new WindowProperties(myFrame);
props.setRelaunchCommand("<full path to javaw.exe –arguments>");
props.setRelaunchDisplayName("My Java Application");
props.setRelaunchIcon("<full path to an .ico or .exe file>");
props.setAppUserModelID("StrixCode.J7Goodies.Appname");
props.save();
вот более простой пример того, как позвонить SetCurrentProcessExplicitAppUserModelID
via JNA
:
import com.sun.jna.*;
import com.sun.jna.win32.*;
interface Shell32 extends StdCallLibrary {
Shell32 INSTANCE = (Shell32) Native.loadLibrary("shell32", Shell32.class, W32APIOptions.DEFAULT_OPTIONS);
NativeLong SetCurrentProcessExplicitAppUserModelID(WString appID);
}