通过exe启动class
本方法通过jni方式实现。
/**
* 直接通过exe启动class(免外部配置)
*
* project:loonframework
* author:chenpeng
* email:ceponline@yahoo.com.cn
*/
// PS:好长时间不写C/C++,已然快不会用了,顺便复习一下……有错大家提,大家帮忙优化……
#include "stdafx.h"
#include "jni.h"
//用于提示框显示
void MessageBox(LPCTSTR text);
//用于路径过滤
char* DirPath(char * path);
//MessageBox标题名称。
static const char MessageBoxTitle[] = "Loonframework提供";
//本程序默认的jvm.dll相对路径位置。
const static char _DEFAULT_JVM[]="//jre//bin//client//jvm.dll";
//主函数名,也可改为其他名称,JVM以此查询启动接口。
const char MainName[] ="main";
//虚拟机启动参数总数。
const int JVMOptionCount = 5;
//JVM编译器设定,none为使用默认编译器。
static char Compiler[] = "-Djava.compiler=NONE";
//最小内存
static char MinMB[] = "-Xms256M";
//最大内存
static char MaxMB[] = "-Xmx512M";
//jar包中主函数class所在路径。
static char AppClass[] = "org/loon/framework/game/Main";
//需要执行的jar包所在路径,'./'为当前路径简写,多jar包以';'分割。
static char ClassPath[] = "-Djava.class.path=./loonlangrisser0.01.jar";
static char LibraryPath[] = "-Djava.library.path=./";
typedef jint (WINAPI* JNICreateJavaVM)(JavaVM**, JNIEnv**, void *);
/**
* Win主函数
**/
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
//JVM路径(PS:本写法不支持中文路径)。
char JVMPath[MAX_PATH];
/**
*本程序通过注册表查找JVM.DLL位置。如未注册安装虚拟机,本程序将在执行文件相对路径下直接获得。)
*/
//设定空间大小
char SubKey[MAX_PATH * 2];
//将注册表路径字符串拷贝到SubKey
lstrcpy(SubKey, "Software//JavaSoft//Java Runtime Environment");
HKEY hk;
//查询注册表,并返回结果
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SubKey, 0, KEY_READ, &hk);
//承载JVM.DLL句柄
HMODULE JVM_DLL;
//当注册表中不存在Software//JavaSoft//Java Runtime Environment时,则从本地读取JVM.DLL
if (result != ERROR_SUCCESS) {
//PS:此处用于从本地路径直接获得JVM.DLL时的其他处理。
//获得文件所在绝对路径,PathLength为返回的路径长度
int PathLength = GetModuleFileName(NULL, JVMPath, MAX_PATH);
//拼装实际路径
lstrcat(DirPath(JVMPath),_DEFAULT_JVM);
//MessageBox("Software//JavaSoft//Java Runtime Environment不存在!");
// return -1;
//注册表中已存在时
}else{
char feedback[MAX_PATH];
//获得空间大小
DWORD feedback_Length = sizeof(feedback) * sizeof(feedback[0]);
result = RegQueryValueEx(hk, "CurrentVersion", NULL, NULL, (LPBYTE)feedback, &feedback_Length);
//关闭注册表
RegCloseKey(hk);
if (result != ERROR_SUCCESS) {
MessageBox("Software//JavaSoft//Java Runtime Environment中CurrentVersion读取失败!");
return -1;
}
//获得路径(lstrcat用于将第二个串和第一个连起来赋值给第一个字符串)
lstrcat(SubKey, "//");
lstrcat(SubKey, feedback);
//查询注册表
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, SubKey, 0, KEY_READ, &hk);
if (result != ERROR_SUCCESS) {
lstrcat(SubKey, "未找到!");
MessageBox(SubKey);
return -1;
}
feedback_Length = sizeof(feedback) * sizeof(feedback[0]);
result = RegQueryValueEx(hk, "RuntimeLib", NULL, NULL, (LPBYTE)feedback, &feedback_Length);
RegCloseKey(hk);
if (result != ERROR_SUCCESS) {
lstrcat(SubKey, "Runtime Lib读取失败!");
MessageBox(SubKey);
return -1;
}
//获得JVM.DLL路径
lstrcpy(JVMPath, feedback);
}
//获得JVM.DLL启动实体
JVM_DLL = LoadLibrary(JVMPath);
if (JVM_DLL == NULL) {
lstrcpy(SubKey, JVMPath);
lstrcat(SubKey, "载入失败!");
MessageBox(SubKey);
return -1;
}
//JVM内部函数JNI_CreateJavaVM读取
JNICreateJavaVM createJavaVM = (JNICreateJavaVM)GetProcAddress(JVM_DLL, "JNI_CreateJavaVM");
if (createJavaVM == NULL) {
MessageBox("JNI_CreateJavaVM函数读取失败!");
return -1;
}
//指向本地方法调用接口
JNIEnv* env;
//表示Java虚拟机
JavaVM* jvm;
//设定JVM启动参数
JavaVMInitArgs vm_args;
JavaVMOption options[JVMOptionCount];
/**
*jtl(Java Tools Language)设定:JVM的缺省行为是用“即时”编译器(或JIT[字节代码编译器])执行字节码。
*当加载类时,JIT将类字节码转换成本机代码。使用JIT会导致在每个类加载后有短暂延迟,
*但可提高程序的总体性能。在某些情况下,执行时间可缩短十分之一。
*可用Compiler指定jtl,如将Compiler=foo后,该例中虚拟机将查找名为foo.dll的JIT编译器。
*搜索其它编译器是在jre/bin目录中和系统的PATH上进行的。
*若找不到这样的编译器,虚拟机将缺省使用解释器。
*/
options[0].optionString = Compiler;
//类地址
options[1].optionString = ClassPath;
//lib地址
options[2].optionString = LibraryPath;
//最小内存
options[3].optionString = MinMB;
//最大内存
options[4].optionString = MaxMB;
//PS:此参数用于设定跟踪运行时的信息,暂不需要。
//options[3].optionString = "-verbose:jni";
//使用的jni版本,目前最高为JNI_VERSION_1_6。
vm_args.version = JNI_VERSION_1_4;
vm_args.options = options;
vm_args.nOptions = JVMOptionCount;
vm_args.ignoreUnrecognized = JNI_TRUE;
//启动JVM,并返回结果
int res = createJavaVM(&jvm, &env, &vm_args);
if (res < 0) {
MessageBox("JVM启动失败!");
return -1;
}
//查找目的类
jclass clazz = env->FindClass(AppClass);
if (clazz == 0) {
lstrcpy(SubKey, AppClass);
lstrcat(SubKey, "类没有找到!");
MessageBox(SubKey);
return -1;
}
//取得入口主函数序列号
jmethodID mid = env->GetStaticMethodID(clazz, MainName, "([Ljava/lang/String;)V");
if (mid == 0) {
lstrcpy(SubKey, AppClass);
lstrcat(SubKey, "没有找到主函数!");
MessageBox(SubKey);
return -1;
}
//main启动
env->CallStaticVoidMethod(clazz, mid, NULL);
//JVM释放
jvm->DestroyJavaVM();
return 0;
}
/**
* 提示框,封装原有MessageBox
*/
void MessageBox(LPCTSTR text) {
MessageBox(NULL, text, MessageBoxTitle, MB_ICONEXCLAMATION | MB_APPLMODAL | MB_OK | MB_SETFOREGROUND);
}
/**
* 过滤文件所在绝对路径,去掉最后'/'后字符。
*/
char* DirPath(char * path)
{
char *ph = path;
char *tag = ph;
while (*ph)
{
if ( (*ph) == '//' )
tag = ph;
++ph;
}
*tag = '/0';
return path;
}
运行效果图如下:
源码如下,请该后缀为.rar
转载于:https://www.cnblogs.com/cping1982/archive/2007/10/27/2258098.html
通过exe启动class相关推荐
- MFC的exe启动时提示应用程序配置不正确,应用程序未能启动错误
MFC的exe启动时提示应用程序配置不正确,应用程序未能启动错误 老姐笔记本中毒太深于病入膏肓,无奈迫写一程序"曲线救国".刚启动自己写的程序就出现应用程序配置不正确,应用程序未能 ...
- 外部开发:部件属性 外部exe启动UG NX
NX支持外部读取修改部件属性,修改后注意需要保存,UF_PART_save(); 外部exe启动UG NX 1 用.net2003建立一个控制台应用程序 2 将目录ugii\managed下除Ma ...
- svchost.exe启动服务原理
svchost.exe本身只是作为服务宿主,并不实现任何服务功能,需要svchost.exe启动的服务以动态链接库形式实现,在安装这些服务时,把服务的可执行程序指向svchost.exe,启动这些服务 ...
- 无法使用tomcat6.exe启动服务
无法使用tomcat6.exe启动服务, 错误信息: [2019-07-19 11:04:58] [warn] The system cannot find the Registry key for ...
- tomcat.exe java home,tomcat.exe启动和startup.bat启动的不同
一.tomcat7.exe与startup.bat的区别: 1.这两个都可以启动tomcat,但tomcat7.exe必须安装了服务才能启动,而startup.bat不需要 2.另外一个区别是它们启动 ...
- Windows下rocketmq mqnamesrv.exe 启动成功,但是mqbroker.exe启动失败
1.mqnamesrv.exe启动成功 2.启动mqbroker.exe失败 解决办法,删除C:\Users\"当前系统用户名"\store下的所有文件,就可以了 转载于:http ...
- mysql按照设置向导mysqlinstanceconfig.exe启动失败
因为应用程序的并行配置不正确,导致mysql按照设置向导mysqlinstanceconfig.exe启动失败, 原因:是exe执行权限的问题. 解决方法: 下载 rescource hacker 在 ...
- tomcat7w.exe启动失败,未注册成服务,以及配置Tomcat系统环境变量
今天弄了个绿色解压版的Tomcat,结果 tomcat7w.exe 启动失败, 提示我没有将Tomcat注册成服务,我想这可能是因为直接解压缩的原因吧,先把 Tomcat 注册一下吧, 1. 找到解压 ...
- svchost.exe启动服务原理(如何查看系统服务究竟启动了哪个文件)
引言: 本来是不想研究这些东西的,但是米老大指示要求禁用网上邻居,顺便研究一下. 其实禁用网上邻居,可以简单的从注册表禁用,不过这样太苍白无力了,既然做,就做强悍点,直接从服务入手,彻底kill网上邻 ...
最新文章
- VC++ 剪贴板编程
- logisim设计alu设计报告_【新】PowerBI 报告设计思想 结构布局篇
- 为什么不推荐使用存储过程
- thymeleaf 异常:SpelEvaluationException: EL1008E: Property or field ‘url‘ cannot be found
- LeetCode MySQL 1126. 查询活跃业务
- Redis的常用JavaAPI(Jedis)实现
- Ambari--服务管理
- 2019 谷歌年度搜索关键词揭晓,技术宅的英雄梦!
- bash的快捷键、特殊参数、历史命令、相关文件
- G502使用计算机配置,Logitech G502,G402游戏鼠标宏设置教程一目了然
- 计算机的硬件软件组成
- 【爬虫实战】起点中文网小说的爬取
- 百度收录如何API提交(java、python)
- 计算机二级考试C语言编程解读:统计N名学生的成绩
- Learning a Proposal Classifier for Multiple Object Tracking
- Parallel Scavenge无法和CMS共同使用
- 牛客网练习2-《网络基础》
- 搜狗Sogou拼音输入法,搜狗高速浏览器(IE浏览器内核)
- 人民币为什么 不继续升值
- Jmeter-----保存到响应文件