Question

Faisant suite à ma question précédente concernant la barre des tâches Windows 7 , je voudrais diagnostiquer pourquoi Windows ne reconnaît pas que ma demande est indépendante de javaw.exe. J'ai actuellement le code JNA ci-dessous pour obtenir le 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() + ".");
        }
    }
}

La sortie de l'application est apparemment charabia:

1: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
2: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
3: ????????????????P???????????

Être conscient du fait que la sortie peut être UTF-16, en (3) I essayé de convertir un tableau d'octets à partir de UTF-16. En toute honnêteté, je ne sais pas si mon approche est ici comme (a) Je ne sais pas la taille d'un PWSTR et (b) Je ne sais pas si GetCurrentProcessExplicitAppUserModelID est en effet de retour un tableau d'octets ou une chaîne.

Je suis conscient que JSmooth va exécuter le processus de GUI dans un emballage qui simule cet effet. Launch4j prétend faire la même chose, mais ne semble pas fonctionner. Je cherche à avoir le jeu de AppUserModelID quel que soit l'emballage Java .

Qu'est-ce qui ne va pas ici?

Était-ce utile?

La solution

Je ne vois pas votre question avant sinon j'aurais donné un essai, même sans prime.

Voici ce que je suis venu avec. S'il vous plaît noter, comme indiqué dans le code lui-même, je ne l'ai pas implémenter de la mémoire appropriée nettoyer avec la fonction CoTaskMemFree (de Ole32.dll). Donc, je vous suggère de ne prendre que la mise en œuvre pour SetCurrentProcessExplicitAppUserModelID()

package com.stackoverflow.AppIdTest;

import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.WString;
import com.sun.jna.ptr.PointerByReference;

public class AppIdTest
{

  public static void main(String[] args) throws Exception
  {
    setCurrentProcessExplicitAppUserModelID(AppIdTest.class.getName());

    System.out.println(getCurrentProcessExplicitAppUserModelID());
  }

  // DO NOT DO THIS, IT'S JUST FOR TESTING PURPOSE AS I'M NOT FREEING THE MEMORY
  // AS REQUESTED BY THE DOCUMENTATION:
  //
  // http://msdn.microsoft.com/en-us/library/dd378419%28VS.85%29.aspx
  //
  // "The caller is responsible for freeing this string with CoTaskMemFree when
  // it is no longer needed"
  public static String getCurrentProcessExplicitAppUserModelID()
  {
    final PointerByReference r = new PointerByReference();

    if (GetCurrentProcessExplicitAppUserModelID(r).longValue() == 0)
    {
      final Pointer p = r.getValue();


      return p.getString(0, true); // here we leak native memory by lazyness
    }      
    return "N/A";
  }

  public static void setCurrentProcessExplicitAppUserModelID(final String appID)
  {
    if (SetCurrentProcessExplicitAppUserModelID(new WString(appID)).longValue() != 0)
      throw new RuntimeException("unable to set current process explicit AppUserModelID to: " + appID);
  }

  private static native NativeLong GetCurrentProcessExplicitAppUserModelID(PointerByReference appID);
  private static native NativeLong SetCurrentProcessExplicitAppUserModelID(WString appID);


  static
  {
    Native.register("shell32");
  }
}

Est-ce que ça marche pour vous?

Au moins ici, il imprime correctement les:

  

com.stackoverflow.AppIdTest.AppIdTest

Autres conseils

Si vous avez juste besoin de régler le AppUserModelId alors le code ci-dessus est assez JNA. Toutefois, si vous voulez profiter des nouvelles fonctionnalités de Windows 7 dans votre application Java puis vérifier J7Goodies une bibliothèque Java fournissant des extensions de la barre des tâches de Windows 7.


EDIT : plus d'info de J7Goodies Guide du programmeur

  

4.2. Réglage AppUserModelID

     

Pour utiliser l'un des Windows 7 dispose d'une application doit explicitement   définir l'identificateur de processus -   ID d'application du modèle de l'utilisateur (AppUserModelID). Il ne peut pas avoir plus de   128 caractères et ne peuvent pas contenir des espaces. Chaque section doit être   -camel, par exemple:

 CompanyName.ProductName.SubProduct.VersionInformation
     

Cet identifiant   doit être défini avant toute GUI (fenêtre) est affichée. Vous définissez en appelant:

// Remember to set AppUserModelID before creating any UI
AppUserModelId.setCurrentProcessId("StrixCode.J7Goodies.Appname");
  

4.3. Définition des propriétés fenêtre

     

Une application Java ne peut pas être épinglé à la barre des tâches Windows 7 à moins que ses propriétés de la fenêtre sont définies. le   propriétés se composent de quatre champs:

     
      
  • AppUserModelID - le même que celui passé à AppUserModelId.setCurrentProcessId(String)
  •   
  • RelaunchDisplayName - nom de l'application
  •   
  • RelaunchCommand - la commande complète utilisée pour lancer l'application. Dans le cas d'un programme Java, il sera: <path to javaw.exe> -jar <path to application jar>
  •   
  • RelaunchIcon - chemin vers l'icône de l'application
  •   
     

Important : RelaunchCommand et RelaunchDisplayName doit toujours être en   ensemble. Pour définir ces propriétés utilisent la classe simple de 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();

Voici un exemple plus simple sur comment appeler 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);

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top