Использование 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);

}