JAVA技巧(手編寫(xiě)啟動(dòng)JAVA程序的EXE文件)

字號(hào):

有大多的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.