有大多的Java人,在四處尋找能將jar打包成exe的工具,另我十分不解的是為什么要打包呢,其實(shí)目的無(wú)非是想用exe啟動(dòng)而已,其實(shí)打包真的沒(méi)什么好處,一個(gè)5m的程序打包成exe還可以,如果一個(gè)100m的程序呢?如果這個(gè)100m的程序同時(shí)還要集成jre呢.打包后啟動(dòng)速度應(yīng)該不用我多說(shuō),而且目前幾乎所有打包程序都不是很完美,之所以這些打包程序還可以使用,是因?yàn)樗麄兪У那闆r,只在很特別的場(chǎng)景下才能遇到,這些工具我也用過(guò)一些,感覺(jué)不盡如人意.
其實(shí)我們平時(shí)使用的90%的程序都不是一個(gè)exe就能搞定的,而是很多個(gè)文件,我們只是用一個(gè)exe文件啟動(dòng)程序而已,本這這個(gè)思想,我一直想寫(xiě)個(gè)java 的exe啟動(dòng)器,因?yàn)槲疫€略懂點(diǎn)c++和delphi,當(dāng)然只是皮毛了,好在完成這件事只用皮毛的知識(shí)應(yīng)該足以.雖說(shuō)做起來(lái)也遇到很多困難,不過(guò)最后還是完成了.
所以這次考試大寫(xiě)了個(gè)Delphi版的
在放代碼前,先介紹下這個(gè)工具,暫時(shí)我給它起的名字也叫javalauncher
使用方法:
文件存放結(jié)構(gòu)
Test.jar
javalauncher.ini
javalauncher.exe
jre
test.jar是要啟動(dòng)的java程序,這個(gè)有點(diǎn)像廢話
jre是jre,還是廢話,不過(guò)這個(gè)jre可以選擇精簡(jiǎn)版的,我選擇的這個(gè)精簡(jiǎn)版只有15M
如果test.jar依賴(lài)了其他的jar包,可以放置在\jre\lib\ext里面或者
修改test.jar中的META-INF\MANIFEST.MF文件
添加如下行
Class-Path: swt.jar
稍后我提供的demo是將swt.jar放置在了jre\lib\ext中.因?yàn)槲业膁emo是用swt寫(xiě)的,因?yàn)橛胹wt寫(xiě)的話可以把jre中swing相關(guān)的類(lèi)都刪掉.節(jié)省不少空間呢.
讓我們看看javalauncher.ini配置文件是如何編寫(xiě)的吧
[blog.csdn.net/sunyujia]
command=./jre/bin/javaw.exe
options= -jar Test.jar
command是指明javaw所在位置,可以用相對(duì)路徑,如果是使用系統(tǒng)中已經(jīng)安裝的jre直接寫(xiě)javaw.exe即可
options是javaw的參數(shù)
非常遺憾的是,考試大發(fā)現(xiàn)我們?nèi)粘F綍r(shí)使用的命令java 包.類(lèi),這種寫(xiě)法并不支持,也就是說(shuō)想用這個(gè)工具啟動(dòng)必須使用-jar
我目前尚未找到原因,初步分析,通過(guò)delphi的ShellExecute給javaw.exe傳遞參數(shù)時(shí),javaw.exe只能識(shí)別-開(kāi)頭的參數(shù)
好在javaw的所有參數(shù)都是-開(kāi)頭的,只有上面說(shuō)的那種情況不是.
我已經(jīng)將工具和例子上傳到 http://download.csdn.net/source/743727
這個(gè)例子只有10m可在沒(méi)有安裝jre的機(jī)器上執(zhí)行,例子是基于swt的寫(xiě)的.
啟動(dòng)這個(gè)例子的方法只要運(yùn)行javalauncher.exe即可.想要給這個(gè)exe換圖標(biāo)的話,大家可以使用ResHacker這個(gè)工具
大家以后可以通過(guò)例子中的javalauncher.exe來(lái)啟動(dòng)java程序了,多么美好的事情,^_^
告訴大家個(gè)秘密,這個(gè)exe的文件名是可以更改的,比如改成abc.exe,相映的修改javalauncher.ini為abc.ini即可
考試大相信此文的更多讀者希望看到的是java源碼,對(duì)delphi一定是不感冒了,所以我還是先放這次用于測(cè)試的java例子的源碼吧.
package com.syj;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class HelloSWT {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(450, 100);
shell.setText("所用JRE是:" + System.getProperty("java.home"));
shell.setLayout(new FillLayout());
final Button button = new Button(shell, SWT.FLAT);
button.setText("blog.csdn.net/".concat("sunyujia"));
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent arg0) {
try {
Runtime.getRuntime().exec(
"rundll32 url.dll,FileProtocolHandler http://"
+ button.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
});
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
}
下面是delphi源碼
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, shellapi ,inifiles;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
JvmConfig:TInifile;
command,options,ConfigFileName: String;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
application.ShowMainForm:=false;//隱藏窗體
ConfigFileName:=ExtractFileName(Application.ExeName);//獲取當(dāng)前程序文件名
ConfigFileName:=Copy(ConfigFileName,1,Length(ConfigFileName)-Length(ExtractFileExt(ConfigFileName)));//獲取去掉擴(kuò)展名
ConfigFileName:=GetCurrentDir+'\'+ConfigFileName+'.ini';//拼湊成與同當(dāng)前exe文件同名的ini文件
//showmessage(ConfigFileName);//use debug
JvmConfig:=TIniFile.Create(ConfigFileName); //讀取ini文件
command:=JvmConfig.ReadString('blog.csdn.net/sunyujia','command','');
options:=JvmConfig.ReadString('blog.csdn.net/sunyujia','options','');
//showmessage(command); //use debug command
//showmessage(options); //use debug options
JvmConfig.Free;
ShellExecute(Application.Handle, 'open', pchar(command), pchar(options),pchar(GetCurrentDir) , 1);
application.Terminate;
end;
end.
其實(shí)我們平時(shí)使用的90%的程序都不是一個(gè)exe就能搞定的,而是很多個(gè)文件,我們只是用一個(gè)exe文件啟動(dòng)程序而已,本這這個(gè)思想,我一直想寫(xiě)個(gè)java 的exe啟動(dòng)器,因?yàn)槲疫€略懂點(diǎn)c++和delphi,當(dāng)然只是皮毛了,好在完成這件事只用皮毛的知識(shí)應(yīng)該足以.雖說(shuō)做起來(lái)也遇到很多困難,不過(guò)最后還是完成了.
所以這次考試大寫(xiě)了個(gè)Delphi版的
在放代碼前,先介紹下這個(gè)工具,暫時(shí)我給它起的名字也叫javalauncher
使用方法:
文件存放結(jié)構(gòu)
Test.jar
javalauncher.ini
javalauncher.exe
jre
test.jar是要啟動(dòng)的java程序,這個(gè)有點(diǎn)像廢話
jre是jre,還是廢話,不過(guò)這個(gè)jre可以選擇精簡(jiǎn)版的,我選擇的這個(gè)精簡(jiǎn)版只有15M
如果test.jar依賴(lài)了其他的jar包,可以放置在\jre\lib\ext里面或者
修改test.jar中的META-INF\MANIFEST.MF文件
添加如下行
Class-Path: swt.jar
稍后我提供的demo是將swt.jar放置在了jre\lib\ext中.因?yàn)槲业膁emo是用swt寫(xiě)的,因?yàn)橛胹wt寫(xiě)的話可以把jre中swing相關(guān)的類(lèi)都刪掉.節(jié)省不少空間呢.
讓我們看看javalauncher.ini配置文件是如何編寫(xiě)的吧
[blog.csdn.net/sunyujia]
command=./jre/bin/javaw.exe
options= -jar Test.jar
command是指明javaw所在位置,可以用相對(duì)路徑,如果是使用系統(tǒng)中已經(jīng)安裝的jre直接寫(xiě)javaw.exe即可
options是javaw的參數(shù)
非常遺憾的是,考試大發(fā)現(xiàn)我們?nèi)粘F綍r(shí)使用的命令java 包.類(lèi),這種寫(xiě)法并不支持,也就是說(shuō)想用這個(gè)工具啟動(dòng)必須使用-jar
我目前尚未找到原因,初步分析,通過(guò)delphi的ShellExecute給javaw.exe傳遞參數(shù)時(shí),javaw.exe只能識(shí)別-開(kāi)頭的參數(shù)
好在javaw的所有參數(shù)都是-開(kāi)頭的,只有上面說(shuō)的那種情況不是.
我已經(jīng)將工具和例子上傳到 http://download.csdn.net/source/743727
這個(gè)例子只有10m可在沒(méi)有安裝jre的機(jī)器上執(zhí)行,例子是基于swt的寫(xiě)的.
啟動(dòng)這個(gè)例子的方法只要運(yùn)行javalauncher.exe即可.想要給這個(gè)exe換圖標(biāo)的話,大家可以使用ResHacker這個(gè)工具
大家以后可以通過(guò)例子中的javalauncher.exe來(lái)啟動(dòng)java程序了,多么美好的事情,^_^
告訴大家個(gè)秘密,這個(gè)exe的文件名是可以更改的,比如改成abc.exe,相映的修改javalauncher.ini為abc.ini即可
考試大相信此文的更多讀者希望看到的是java源碼,對(duì)delphi一定是不感冒了,所以我還是先放這次用于測(cè)試的java例子的源碼吧.
package com.syj;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class HelloSWT {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(450, 100);
shell.setText("所用JRE是:" + System.getProperty("java.home"));
shell.setLayout(new FillLayout());
final Button button = new Button(shell, SWT.FLAT);
button.setText("blog.csdn.net/".concat("sunyujia"));
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent arg0) {
try {
Runtime.getRuntime().exec(
"rundll32 url.dll,FileProtocolHandler http://"
+ button.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
});
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
}
下面是delphi源碼
unit Unit5;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, shellapi ,inifiles;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
JvmConfig:TInifile;
command,options,ConfigFileName: String;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
application.ShowMainForm:=false;//隱藏窗體
ConfigFileName:=ExtractFileName(Application.ExeName);//獲取當(dāng)前程序文件名
ConfigFileName:=Copy(ConfigFileName,1,Length(ConfigFileName)-Length(ExtractFileExt(ConfigFileName)));//獲取去掉擴(kuò)展名
ConfigFileName:=GetCurrentDir+'\'+ConfigFileName+'.ini';//拼湊成與同當(dāng)前exe文件同名的ini文件
//showmessage(ConfigFileName);//use debug
JvmConfig:=TIniFile.Create(ConfigFileName); //讀取ini文件
command:=JvmConfig.ReadString('blog.csdn.net/sunyujia','command','');
options:=JvmConfig.ReadString('blog.csdn.net/sunyujia','options','');
//showmessage(command); //use debug command
//showmessage(options); //use debug options
JvmConfig.Free;
ShellExecute(Application.Handle, 'open', pchar(command), pchar(options),pchar(GetCurrentDir) , 1);
application.Terminate;
end;
end.

