JIntellitype热键异常退出

我写一个程序需要全局监听键盘,设置一个热键,用的JIntellitype
包:JIntellitype-1.3.9.jar
文件:JIntellitype.dll JIntellitype64.dll

我在eclipse里可以运行,找得到JIntellitype64.dll,并且热键也生效了,但是把项目打成可运行的jar包,模拟生产环境运行时找不到JIntellitype64.dll,运行就闪退,有没有解决方案,请专业人士帮助

img

这是JAR包

img

因为在打包成可执行的jar包后,JIntellitype64.dll并没有被正确加载导致程序闪退。可以尝试以下方法解决该问题:
1、将JIntellitype64.dll文件放在可执行的jar包所在的目录下,并修改程序代码,使用绝对路径来加载JIntellitype.dll文件,例如:

String dllPath = System.getProperty("user.dir") + File.separator + "JIntellitype64.dll";
JIntellitype.setLibraryPath(dllPath);

2、将JIntellitype.dll和JIntellitype64.dll文件打包进可执行的jar包中,并在程序代码中将这两个文件提取出来并加载,例如:

// 提取JIntellitype.dll文件
InputStream dllStream = getClass().getResourceAsStream("/JIntellitype.dll");
File dllFile = new File(System.getProperty("java.io.tmpdir") + "/JIntellitype.dll");
OutputStream dllOutStream = new FileOutputStream(dllFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = dllStream.read(buffer)) != -1) {
    dllOutStream.write(buffer, 0, bytesRead);
}
dllOutStream.close();
dllStream.close();

// 提取JIntellitype64.dll文件
InputStream dll64Stream = getClass().getResourceAsStream("/JIntellitype64.dll");
File dll64File = new File(System.getProperty("java.io.tmpdir") + "/JIntellitype64.dll");
OutputStream dll64OutStream = new FileOutputStream(dll64File);
buffer = new byte[4096];
bytesRead = -1;
while ((bytesRead = dll64Stream.read(buffer)) != -1) {
    dll64OutStream.write(buffer, 0, bytesRead);
}
dll64OutStream.close();
dll64Stream.close();

// 加载JIntellitype.dll和JIntellitype64.dll文件
String dllPath = System.getProperty("java.io.tmpdir") + File.separator + "JIntellitype.dll";
String dll64Path = System.getProperty("java.io.tmpdir") + File.separator + "JIntellitype64.dll";
JIntellitype.setLibraryPath(dllPath + ";" + dll64Path);

以上两种方法都可以解决找不到JIntellitype64.dll文件的问题,根据具体情况选择一种即可。

根据您的描述,您在使用JIntellitype包编写程序时遇到了问题。在Eclipse中可以正常运行,但将项目打包成可执行的JAR文件后,在模拟生产环境中找不到JIntellitype64.dll文件,导致程序闪退。

这个问题可能是由于JAR文件无法找到JIntellitype64.dll文件所致。通常,JAR文件只包含Java代码和相关的资源文件,无法直接引用本地库文件。您可以尝试以下解决方案来解决这个问题:

  1. 将JIntellitype64.dll文件放置在与JAR文件相同的目录下。这样,当您运行JAR文件时,它将能够找到并加载所需的本地库文件。

  2. 在程序中动态加载本地库文件。您可以使用Java的System.load()方法来加载本地库文件。在代码中指定本地库文件的完整路径,这样程序将能够加载它。

例如,您可以使用以下代码来加载JIntellitype64.dll文件:

System.load("path/to/JIntellitype64.dll");

确保将实际的文件路径替换为JIntellitype64.dll文件的正确路径。

请注意,如果您的程序在不同的操作系统上运行,可能需要针对每个操作系统提供适当的本地库文件,并根据当前操作系统加载正确的文件。

当将Java项目打包为可执行的JAR文件时,与本地文件相关的问题可能会导致找不到动态链接库(DLL)文件。这可能是因为JAR文件中未包含所需的DLL文件,或者在运行JAR文件时,系统无法正确地找到DLL文件。

要解决这个问题,可以尝试以下方法:

  1. 确保DLL文件位于正确的位置:将JIntellitype64.dll文件与JAR文件放在同一目录下,确保两者在相同的目录结构中。

  2. 使用Java的System.load()方法手动加载DLL文件:在Java代码中,使用System.load()方法手动加载DLL文件。这将告诉Java运行时系统去指定的路径查找并加载DLL文件。例如:

    System.load("path/to/JIntellitype64.dll");
    

    将上述代码添加到程序的入口点或需要使用JIntellitype的地方,以确保DLL文件被正确加载。

  3. 使用java.library.path系统属性指定DLL文件路径:在命令行或脚本中运行JAR文件时,可以使用java.library.path系统属性来指定DLL文件的路径。例如:

    java -Djava.library.path="path/to/dll" -jar yourjarfile.jar
    

    将上述命令中的"path/to/dll"替换为实际的DLL文件路径。

  4. 将DLL文件打包到JAR文件中:使用构建工具(如Maven或Gradle)的相应插件或配置,将DLL文件打包到JAR文件中,以便在运行时能够从JAR文件中访问它。这样可以确保DLL文件与Java代码一起分发,并且无需手动处理DLL文件路径。

    如果使用Maven构建项目,可以将DLL文件放在src/main/resources目录下,并将其配置为构建路径中的资源文件。这样,Maven会自动将DLL文件打包到JAR文件中。

    如果使用Gradle构建项目,可以使用from方法将DLL文件添加到JAR文件中。例如:

    from('src/main/resources') {
        include 'JIntellitype64.dll'
    }
    

    这将把JIntellitype64.dll文件添加到生成的JAR文件中。

请根据你的项目和构建工具选择适合的方法来解决问题。如果仍然遇到困难,请确保查阅JIntellitype文档或与JIntellitype的开发者社区联系,以获取更详细的帮助和支持。

相信其他答友也给了你不错的提示,这边我的思路是:
1、项目中是否存在多个相同的文件,例如不同版本的JIntellitype64.dll
2、热键冲突是我们常见的一种现象,排查下该热键是否与其他应用程序相同
3、环境不同,导致缺少关键依赖项,需要确保你前面环境运行的这些库或模块已经正确安装并添加到了你项目中,最好是在统一的运行目录下。


package createglobalhotkey;

import com.melloware.jintellitype.HotkeyListener;
import com.melloware.jintellitype.IntellitypeListener;
import com.melloware.jintellitype.JIntellitype;

import java.util.Scanner;


public class TestMethod {
    public static void main(String[] args) {
        JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_CONTROL,66);//k
        System.out.println("热键注册成功!你可以使用了!");
        JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
            public void onHotKey(int markCode) {
                if (markCode==1){
                    System.out.println("ctl+b 起作用了...");
                }
            }
        });
        System.out.println("要取消热键,请输入1:");
        Scanner sc=new Scanner(System.in);
        int i = sc.nextInt();
        if (i==1) {
            HotKeyThread hotKeyThread=new HotKeyThread();
            hotKeyThread.start();
        }
    }

}


这个问题你需要从两个方面来排查:
1.路径问题,也就是说,在loaddll的路径是否正确,这个必须看到你的代码才能给出修改建议。
2.32位/64位的问题,你需要知道当前环境中jdk的版本是32位还是64位,不同的版本调用不同的dll。当然,这个判断通常是在代码中进行的。
你没有贴出loaddll相关的代码,也没有贴出报错的错误信息,所以只能提出这两个建议。

取消热键

package createglobalhotkey;

import com.melloware.jintellitype.JIntellitype;

public class HotKeyThread extends Thread {
    @Override
    public void run(){
        JIntellitype.getInstance().unregisterHotKey(1);
        System.out.println("热键已取消!");
        JIntellitype.getInstance().cleanUp();
    }
}



在代码中,确保在加载 JIntellitype 库之前设置系统属性 jna.library.path,指向包含 JIntellitype.dll 和 JIntellitype64.dll 文件的目录。例如:

System.setProperty("jna.library.path", "path/to/dll/files");

请确保将 “path/to/dll/files” 替换为 JIntellitype.dll 和 JIntellitype64.dll 文件所在的实际路径。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题的原因是JIntellitype.dll 和 JIntellitype64.dll 没有被正确地打包进可执行JAR文件中。这是因为这样的DLL文件是外部文件,需要在代码中使用特别的方式进行调用,在将项目打包成JAR文件时,只有JAR文件被保留在内部,而这些DLL文件未被包含在内,因此导致问题的出现。要解决这个问题,我们需要做以下几件事情:

  1. 将JIntellitype.dll 和 JIntellitype64.dll文件加入到项目中,放到与src和bin相同的层级目录下。

  2. 修改你的“运行配置”,将VM参数设置为:-Djava.library.path=./

  3. 将JIntellitype.jar也加入到项目依赖中。

接下来我会详细解释这些步骤的具体细节。

第一步:将JIntellitype.dll 和 JIntellitype64.dll文件加入到项目中

将JIntellitype.dll 和 JIntellitype64.dll文件拷贝到你的项目根目录下,放到与src和bin相同的层级目录中。例如:

- YourProject
  - src
  - bin
  - JIntellitype.dll
  - JIntellitype64.dll
  - ...

注意:在执行程序时,根据系统的位数,JIntellitype.dll或者JIntellitype64.dll会被加载。如果是32位系统,那么就使用JIntellitype.dll,如果是64位系统,则使用JIntellitype64.dll。这意味着你需要把这两个文件都放到与src和bin相同的目录中。

第二步:修改你的“运行配置”

在Eclipse中,右键单击你的项目,选择“Run As -> Run Configurations…”,然后选择“Arguments”选项卡。在VM arguments中加入:-Djava.library.path=./

这将告诉Java运行时,它可以在当前目录下寻找JIntellitype.dll或者JIntellitype64.dll文件。

第三步:将JIntellitype.jar加入到项目依赖中

将JIntellitype.jar文件也加入到你的Java项目依赖中,这样你就可以使用JIntellitype的API来调用全局热键监听。

参考代码:

import com.melloware.jintellitype.*;

public class App implements HotkeyListener {
  
  public static void main(String[] args) {
  
    // 处理热键
    JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_ALT, (int) 'T');
    JIntellitype.getInstance().addHotKeyListener(new App());
    
    // 保持程序运行
    while(true) {
      try {
        Thread.sleep(1000L);
      } catch(InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
  
  @Override
  public void onHotKey(int identifier) {
    System.out.println("Hotkey pressed: " + identifier);
  }
}

这段代码将监控按下ALT + T组合键事件,并在控制台输出相应内容。你可以根据自己的需要修改代码和热键。

希望这个解答可以帮到你。
如果我的回答解决了您的问题,请采纳!

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

JIntellitype是一个Java实现的热键管理工具,可以为Java应用程序添加全局热键功能。出现热键异常退出通常有以下几个原因:

  1. 热键冲突。如果为两个组件设置了同一个热键组合,会导致JIntellitype异常退出。需要检查代码,避免为不同组件设置重复的热键。
  2. Java版本过高。JIntellitype仅支持Java 6及以下版本,如果使用Java 7+版本会出现异常。需要使用兼容的Java版本。
  3. 安全管理器拦截。如果启用了Java安全管理器,它可能会阻止JIntellitype访问所需的功能,导致异常退出。可以尝试禁用安全管理器。
  4. 没有找到AWT库。JIntellitype依赖AWT库提供全局热键功能,如果找不到AWT库会退出。需要确保项目中引入了AWT库。
  5. 系统热键冲突。JIntellitype注册的热键与某些系统组件的热键冲突,这会导致退出。需要避开这些系统热键。
  6. 其它原因。如内存溢出、插件冲突等也可能导致问题。

一些解决方法如下:

  1. 检查并解除热键冲突。
  2. 使用Java 6或更低版本。
  3. 禁用Java安全管理器。
  4. 确保项目中引入AWT库。
  5. 避开系统热键,使用少用的热键组合。
  6. 增加内存限制,禁用其他插件。
  7. 升级JIntellitype版本,有可能新版本修复了此问题。