NO IMAGE

轉載請註明出處:http://blog.csdn.net/sunyujia/

 

有大多的Java人,在四處尋找能將jar打包成exe的工具,另我十分不解的是為什麼要打包呢,其實目的無非是想用exe啟動而已,其實打包真的沒什麼好處,一個5m的程式打包成exe還可以,如果一個100m的程式呢?如果這個100m的程式同時還要整合jre呢.打包後啟動速度應該不用我多說,而且目前幾乎所有打包程式都不是很完美,之所以這些打包程式還可以使用,是因為他們失效的情況,只在很特別的場景下才能遇到,這些工具我也用過一些,感覺不盡如人意.

其實我們平時使用的90%的程式都不是一個exe就能搞定的,而是很多個檔案,我們只是用一個exe檔案啟動程式而已,本這這個思想,我一直想寫個java 的exe啟動器,因為我還略懂點c 和delphi,當然只是皮毛了,好在完成這件事只用皮毛的知識應該足以.雖說做起來也遇到很多困難,不過最後還是完成了.

因為C 版本的國外已經有人寫過了http://download.csdn.net/source/528223

所以這次我寫了個Delphi版的

在放程式碼前,先介紹下這個工具,暫時我給它起的名字也叫javalauncher

使用方法:

檔案存放結構

Test.jar

javalauncher.ini

javalauncher.exe

jre

test.jar是要啟動的java程式,這個有點像廢話

jre是jre,還是廢話,不過這個jre可以選擇精簡版的,我選擇的這個精簡版只有15M

如果test.jar依賴了其他的jar包,可以放置在/jre/lib/ext裡面或者

修改test.jar中的META-INF/MANIFEST.MF檔案

新增如下行

Class-Path: swt.jar

稍後我提供的demo是將swt.jar放置在了jre/lib/ext中.因為我的demo是用swt寫的,因為用swt寫的話可以把jre中swing相關的類都刪掉.節省不少空間呢.

讓我們看看javalauncher.ini配置檔案是如何編寫的吧
[blog.csdn.net/sunyujia]
command=./jre/bin/javaw.exe
options= -jar Test.jar

command是指明javaw所在位置,可以用相對路徑,如果是使用系統中已經安裝的jre直接寫javaw.exe即可

options是javaw的引數

非常遺憾的是,我發現我們日常平時使用的命令java 包.類,這種寫法並不支援,也就是說想用這個工具啟動必須使用-jar

我目前尚未找到原因,初步分析,通過delphi的ShellExecute給javaw.exe傳遞引數時,javaw.exe只能識別-開頭的引數

好在javaw的所有引數都是-開頭的,只有上面說的那種情況不是.

我已經將工具和例子上傳到 http://download.csdn.net/source/743727

這個例子只有10m可在沒有安裝jre的機器上執行,例子是基於swt的寫的.

啟動這個例子的方法只要執行javalauncher.exe即可.想要給這個exe換圖示的話,大家可以使用ResHacker這個工具

大家以後可以通過例子中的javalauncher.exe來啟動java程式了,多麼美好的事情,^_^

告訴大家個祕密,這個exe的檔名是可以更改的,比如改成abc.exe,相映的修改javalauncher.ini為abc.ini即可

我相信此文的更多讀者希望看到的是java原始碼,對delphi一定是不感冒了,所以我還是先放這次用於測試的java例子的原始碼吧.

 

  1. package com.syj;
  2. import org.eclipse.swt.SWT;
  3. import org.eclipse.swt.events.SelectionAdapter;
  4. import org.eclipse.swt.events.SelectionEvent;
  5. import org.eclipse.swt.layout.FillLayout;
  6. import org.eclipse.swt.widgets.Button;
  7. import org.eclipse.swt.widgets.Display;
  8. import org.eclipse.swt.widgets.Shell;
  9. public class HelloSWT {
  10.     public static void main(String[] args) {
  11.         Display display = new Display();
  12.         Shell shell = new Shell(display);
  13.         shell.setSize(450, 100);
  14.         shell.setText(“所用JRE是:”   System.getProperty(“java.home”));
  15.         shell.setLayout(new FillLayout());
  16.         final Button button = new Button(shell, SWT.FLAT);
  17.         button.setText(“blog.csdn.net/”.concat(“sunyujia”));
  18.         button.addSelectionListener(new SelectionAdapter() {
  19.             public void widgetSelected(SelectionEvent arg0) {
  20.                 try {
  21.                     Runtime.getRuntime().exec(
  22.                             “rundll32 url.dll,FileProtocolHandler http://”
  23.                                       button.getText());
  24.                 } catch (Exception e) {
  25.                     e.printStackTrace();
  26.                 }
  27.             }
  28.         });
  29.         shell.open();
  30.         while (!shell.isDisposed())
  31.             if (!display.readAndDispatch())
  32.                 display.sleep();
  33.         display.dispose();
  34.     }
  35. }

下面是delphi原始碼

  1. unit Unit5;
  2. interface
  3. uses
  4.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5.   Dialogs, shellapi ,inifiles;
  6. type
  7.   TForm1 = class(TForm)
  8.     procedure FormCreate(Sender: TObject);
  9.   private
  10.     { Private declarations }
  11.   public
  12.     { Public declarations }
  13.   end;
  14. var
  15.   Form1: TForm1;
  16.   JvmConfig:TInifile;
  17.   command,options,ConfigFileName: String;
  18. implementation
  19. {$R *.dfm}
  20. procedure TForm1.FormCreate(Sender: TObject);
  21. begin
  22.   application.ShowMainForm:=false;//隱藏窗體
  23.   ConfigFileName:=ExtractFileName(Application.ExeName);//獲取當前程式檔名
  24.   ConfigFileName:=Copy(ConfigFileName,1,Length(ConfigFileName)-Length(ExtractFileExt(ConfigFileName)));//獲取去掉副檔名
  25.   ConfigFileName:=GetCurrentDir ‘/’ ConfigFileName ‘.ini’;//拼湊成與同當前exe檔案同名的ini檔案
  26.   //showmessage(ConfigFileName);//use debug
  27.   JvmConfig:=TIniFile.Create(ConfigFileName); //讀取ini檔案
  28.   command:=JvmConfig.ReadString(‘blog.csdn.net/sunyujia’,’command’,”);
  29.   options:=JvmConfig.ReadString(‘blog.csdn.net/sunyujia’,’options’,”);
  30.   //showmessage(command); //use debug command
  31.   //showmessage(options); //use debug options
  32.   JvmConfig.Free;
  33.   ShellExecute(Application.Handle, ‘open’, pchar(command), pchar(options),pchar(GetCurrentDir) , 1);
  34.   application.Terminate;
  35. end;
  36. end.

最後歡迎大家測試,並提出寶貴意見.