去年也大概是这个时候写了第一个Java2EXE,之后又加了写特性,但是每次我看代码都感觉惨不忍睹,很混乱,而且编译,链接的过程也有点绕。
现在又过了一年了,如果说上次版本的Load过程主要是靠Java(Java加密,解压),那么这次基本把这些费时的操作全交给CPP了。
好了,总结一下这次的改动
1)Loader以及Starter完全是CPP代码,结构很清晰了。
2)加密以及解压交给CPP,速度比以前快了。
3)整合了
JNative,这个是重点,下文详述。
4)生成工具用MFC写,一个简单的向导。
OK,那么JNative是干什么的呢?
官方的描述是 “
JNative, Java framework for DLL access for Windows and Linux”
就是说,有了这个框架,你访问DLL里的方法就不再需要写DLL了,只需要写Java Code了,可能有人问它是怎么做到的呢?
假如说你要访问Kernel32.dll里的某个方法A,你首先需要这个方法的句柄,这个句柄就是通过new一个org.xvolks.jnative.JNative实例来保持的,
类似如:
org.xvolks.jnative.Native methodA=new org.xvolks.jnative.JNative("Kernel32.dll","A");
有了这个句柄,你只要在上面设置参数,返回值,以及类型就可以调用它了。每个调用它上面的JNI里的本地方法就会自动来进行参数解析,解码,调用到目标DLL方法,这个过程基本不可避免需要少量的汇编代码。
JNative为了可移植性,代码是在Cygwin下可编译的,没有MSVC可编译的版本。
对此,本人改了部分代码用于直接一起链接(主要是把GCC嵌入汇编改为对应的MSVC的嵌入汇编代码),而不是让JNative生成一个动态链接库。
如上,由于JNative改成了静态库,程序发布的时候,只要是通过Java2EXE Builder来创建成EXE的话,你就不需要那个JNativeCpp.dll文件了,只有一个EXE.
你调试的时候可以用官方的版本,发布就只要你的代码(JNative的class也都在集成在生成工具里,不需要你自己添加进来)。
来看个简单的例子,我们从Java代码里取得当前进程的全路径名:
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.HeapMemoryBlock;
/**
* DWORD GetModuleFileName(
* HMODULE hModule,
* LPTSTR lpFilename,
* DWORD nSize
*);
* @author yovn
*
*/
public class TestReadProcessPath {
/**
*
* @param args
* @throws NativeException
* @throws IllegalAccessException
*/
public static void main(String[] args) throws NativeException, IllegalAccessException {
JNative v=new JNative("Kernel32.dll","GetModuleFileNameA");
int i = 0;
v.setRetVal(Type.INT);
Pointer pName = new Pointer(new HeapMemoryBlock(1024));
v.setParameter(i++, 0);//module handle
v.setParameter(i++, pName);//pFileName
v.setParameter(i++, 1024);//nSize
v.setRetVal(Type.INT);
v.invoke();
int ret = Integer.parseInt(v.getRetVal());
if (ret == 0) {
// return "null";
System.err.println(
"GetModuleFileName failed!");
} else {
String path = pName.getAsString().substring(0,
ret);
pName.dispose();
v.dispose();
System.out.println("current process's path is:"+path);
}
}
}
编译,把这个文件单独打包成一个jar文件,下面是个用这个工具生成EXE的截图:
生成EXE向导第一步
生成 EXE向导第二步
请从这里下载
Java2EXE Builder Platform