Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JNA获取/设置应用程序标识符_Java_Windows 7_Jna_Utf 16 - Fatal编程技术网

Java 使用JNA获取/设置应用程序标识符

Java 使用JNA获取/设置应用程序标识符,java,windows-7,jna,utf-16,Java,Windows 7,Jna,Utf 16,接下来,我想诊断一下为什么Windows不承认我的应用程序独立于javaw.exe。我目前拥有以下JNA代码以获得: 应用程序的输出看起来乱七八糟: 1: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ& 2: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ& 3: ????????????????P??????????? 意识到输出可能是UTF-16,在(3)中,我尝试从UTF-16转换字节数组。老实说,我不知道我的方法是否正确,因为(a)我不知道aPWSTR的大小,(b)我不知

接下来,我想诊断一下为什么Windows不承认我的应用程序独立于
javaw.exe
。我目前拥有以下JNA代码以获得:

应用程序的输出看起来乱七八糟:

1: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
2: ‹ÿU‹ìƒìL¡¬Ÿv3ʼnEüSV‹uƒ&
3: ????????????????P???????????
意识到输出可能是UTF-16,在(3)中,我尝试从UTF-16转换字节数组。老实说,我不知道我的方法是否正确,因为(a)我不知道a
PWSTR
的大小,(b)我不知道是否确实返回了字节数组或字符串

我知道JSmooth将在一个包装器中运行GUI进程,该包装器模拟这种效果。Launch4j声称也会这样做,但似乎不起作用。我希望设置
AppUserModelID
,而不考虑Java包装器


这里出了什么问题?

我以前没有看到你的问题,否则即使没有赏金,我也会试一试

这是我想到的请注意,正如代码本身所述,我没有使用
CoTaskMemFree
函数(来自
Ole32.dll
)实现正确的内存清理。因此,我建议您只使用
setCurrentProcessExpliciticTappUserModelId()的实现。

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");
  }
}
对你有用吗

至少在这里它可以正确地打印回:

com.stackoverflow.AppIdTest.AppIdTest


如果您只需要设置AppUserModelId,那么上面的JNA代码就足够了。但是,如果您想利用Java应用程序中的新Windows 7功能,请查看提供Windows 7任务栏扩展的Java库


编辑:程序员指南中的更多信息

4.2. 设置AppUserModelID 要使用Windows 7的任何功能,应用程序必须明确 设置其流程标识符- 应用程序用户模型ID(
AppUserModelID
)。它只能有 128个字符,不能包含空格。每个部分都应该 骆驼壳,例如:

 CompanyName.ProductName.SubProduct.VersionInformation
此标识符 必须在显示任何GUI(窗口)之前设置。您可以通过调用以下命令进行设置:

4.3. 设置窗口属性 除非定义了Java应用程序的窗口属性,否则无法将其固定到Windows 7任务栏。这个 属性由四个字段组成:

  • AppUserModelID–与传递给
    AppUserModelID.setCurrentProcessId(字符串)
  • 重新启动DisplayName–应用程序的名称
  • RelaunchCommand–用于启动应用程序的完整命令。对于Java程序,它将是:
    -jar
  • 重新启动图标–应用程序图标的路径
重要信息
重新启动命令
重新启动显示名称
必须始终设置 在一起要设置这些属性,请使用简单的WindowProperties类

WindowProperties props=新的WindowProperties(myFrame);
props.setRelaunchCommand(“”);
setRelaunchDisplayName(“我的Java应用程序”);
props.setrelaunchon(“”);
setAppUserModelID(“StrixCode.J7Goodies.Appname”);
props.save();

下面是一个更简单的示例,介绍如何通过
JNA
调用
SetCurrentProcessExplicitAppUserModelID

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);

}

如果您使用UTF-8格式U???L???v3?E?SV?U?&…(实际上更长,因为字节数组长度为255),那么输出是什么。如果我返回字节值,它将显示负值:
-117-185-117-20-125-2076-95-84-971211851-59-11969-48386-117178-12538…
。它给我的印象是函数返回的不是字符串,太棒了!它就像一个符咒!我喜欢在没有任何进一步修改的情况下,我的应用程序名称和图标在固定应用程序中的显示方式。非常感谢你!我很高兴我帮了忙。我以前从未使用过JNA,所以我对你的问题很好奇。但是,直到今天我才能够访问Windows 7计算机。再说一次,不要在实际应用程序中读取该值,否则在将appID转换回Java后,需要增强实现以正确清理内存String@GregoryPakosz我已经成功地复制了这个示例代码的结果,然而,我不确定我应该看到什么。我创建了一个简单的应用程序,它执行示例代码并显示
JFrame
。然后,任务栏上会显示一个图标,但右键单击它并没有给我将图标“固定”到任务栏的选项(我只得到一个“关闭blabla”选项)。我错过了什么?或者这根本不试图回答OP的问题?@KohányiRóbert@kayahr你似乎正在经历的行为是。可能是
javaw
在您的系统上注册为IsHostApp,或者可能是Swing(因为您似乎正在使用它)以这种方式设置自己以防止锁定问题。您可能会在中找到更多信息。
// Remember to set AppUserModelID before creating any UI
AppUserModelId.setCurrentProcessId("StrixCode.J7Goodies.Appname");
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();
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);

}