Compare commits

...

56 Commits

Author SHA1 Message Date
37c44ca462 Removed focus from upgrade button 2020-05-23 20:21:55 +01:00
19bf57143c Added RMS and clipping alert in tree view 2020-05-23 20:18:49 +01:00
1005619211 Released 0.4.1 2020-05-19 14:33:33 +01:00
af31ba91a4 Fixed loss of sentence settings on window resize 2020-05-19 14:33:00 +01:00
0e9ae7cc91 Improved gain curve editing 2020-05-18 14:11:36 +01:00
702160c1df Added sentence gain envelopes 2020-05-04 16:45:58 +01:00
b57c1b5753 Change time display to show chapter runtime not sentence runtime 2020-03-05 10:48:51 +00:00
e22a1ce84a Fixed bad array construction in options 2020-02-17 15:56:34 +00:00
83c728e7c8 Optimized record deny and keyboard intercept 2020-02-17 14:25:47 +00:00
ed75718d34 Moved opengl to CLI option 2020-02-17 11:48:13 +00:00
75873b9e8c Fixed mixer list to show more than one device 2020-02-16 12:21:43 +00:00
1416f6d632 Reenabled editing of tree 2020-02-13 10:13:38 +00:00
8a7e070f46 Disable notes areas when nothing relevent selected 2020-02-10 14:42:28 +00:00
1c953dbf1f Fix notes saving and colour 2020-02-10 14:38:32 +00:00
da3b88e083 Added old book importer 2020-02-10 13:49:13 +00:00
13d8dc4612 Add refresh data button 2020-02-10 11:45:23 +00:00
785a4f1b7b Add book length 2020-02-09 15:02:12 +00:00
43b0ccd96d Completely remove book and tools menus 2020-02-09 12:05:26 +00:00
f6af5ce2e7 Add import wav file 2020-02-08 23:32:33 +00:00
577ff9c1eb Move addChapter 2020-02-08 22:24:33 +00:00
f0ae69d610 Clean up tools and book menus a little 2020-02-08 22:09:40 +00:00
7e6a08d64b Move purge to book context menu 2020-02-08 21:31:02 +00:00
5f34c57b23 Change order of tree line entries 2020-02-08 21:09:59 +00:00
356d95191b Fixed auto expansion of books at startup 2020-02-08 20:53:40 +00:00
903f8eaa91 Don't copy sentence files if moving within book 2020-02-08 20:01:31 +00:00
1b7dd7dfb1 Copy files while merging books 2020-02-08 20:00:17 +00:00
ca0a15ba09 Added insert below 2020-02-08 19:49:49 +00:00
c52422247c Added merge book to book context menu 2020-02-08 19:36:35 +00:00
c9b65cb315 Reimplemented book merge 2020-02-08 19:19:10 +00:00
fc3365af62 Implemented multiple open books 2020-02-08 17:16:11 +00:00
7c7cd58963 Auto naming of new chapters 2020-02-07 19:42:29 +00:00
aea5a58691 Moving code out of AudiobookRecorder.java 2020-02-07 19:28:20 +00:00
fab7f1a91c Cleanup of debugging 2020-02-05 20:22:37 +00:00
9b23eb56ce Cleanup 2020-02-05 20:03:23 +00:00
450e80ad21 Added manual link to readme 2020-02-04 23:46:10 +00:00
21d7d9d597 Removed debugging cruft 2020-02-03 21:12:01 +00:00
746f47a5fa Added release version checker 2020-02-03 20:27:15 +00:00
c67e6d6abc Remove orphan chapter if empty 2020-02-03 16:13:17 +00:00
1f722f5df3 Move effects reloading into worker thread 2020-02-03 15:51:23 +00:00
df4eae1d66 Add cancel button to queue monitor 2020-02-03 11:24:22 +00:00
4d435b4fc1 Move external processing to worker threads 2020-02-03 10:22:20 +00:00
f95ae10d03 Fix new chapter adding at top of tree 2020-02-02 19:07:23 +00:00
423d840d83 Release 0.3.8 2020-02-02 17:13:12 +00:00
1997b0bf9b Fix tree collapse on recording finish 2020-02-02 17:09:06 +00:00
b206fb33aa Added deepspeech wrapper example to readme 2020-02-02 15:08:55 +00:00
11b26e396c Minor improvements to readme 2020-02-02 15:01:39 +00:00
94139e6ac6 Released 0.3.7 2020-02-02 14:28:26 +00:00
c0cc2432ff Moved some batch processes to thread worker queue and improved tree view; 2020-02-02 14:02:25 +00:00
f86aaa3782 Delay and batch waveform updates 2020-02-02 00:36:29 +00:00
690a8f0c3b Released 0.3.6 2020-02-01 21:18:47 +00:00
1de0ca8d60 Cleaned up imports 2020-02-01 21:16:32 +00:00
de149c5d85 Added options tooltips 2020-02-01 17:05:02 +00:00
7d2b11473b Improved recognition display 2020-02-01 01:03:02 +00:00
4c25fccc86 Moved speech recognition to configrable external command with worther thread pool 2020-01-31 17:29:00 +00:00
5e310b0224 Updated copyright date 2020-01-31 15:02:06 +00:00
169802ccaf Improved book rendering in tree 2020-01-31 14:57:18 +00:00
150 changed files with 6990 additions and 2938 deletions

1
.gitignore vendored
View File

@@ -5,3 +5,4 @@ AudiobookRecorder.jar
AudiobookRecorder-linux
AudiobookRecorder-osx.dmg
AudiobookRecorder-win.exe
.*.swp

View File

@@ -10,6 +10,8 @@ A system for easing the task of recording and editing audiobooks.
* Chapter management
* Audio effect chains (biquad, delay line, etc)
# [Manual and Tutorial](https://majenkoprojects.github.io/AudiobookRecorder)
Usage
-----
@@ -29,12 +31,13 @@ From here on much is controlled by key presses.
appended to the currently selected chapter, or to the last chapter if none is selected.
* Press and hold "T" to record a new phrase that is the start of a new paragraph. This adds the "post paragraph" gap to the previous sentence. Otherwise it does the same as "R".
* Press and hold "F" to record a "continuation" phrase. This sets the previous phrase's post-gap to be the "short" gap instead of the normal length gap.
* Press and hold "Y" to record a new phrase that is the start of a new section. This add the "post section" gap to the previous sentence. Otherwise it does the same as "R".
* Press "D" to delete the last phrase you recorded.
* Press "E" to re-record the currently selected phrase.
Each phrase you record will be briefly analysed using FFT to find the start and end of the audio and set
Each phrase you record can be automatically analysed to find the start and end of the audio and set
crop marks appropriately. These can be adjusted in the waveform display when a phrase is selected. You can also
re-run the analysis using either the default FFT method or using a peak detector method (finding the first and last points
re-run the analysis using either FFT or a peak detector method (finding the first and last points
where the audio amplitude rises above the backround noise).
The phrases also have a "post gap" associated with them. This is the amount of room noise (in milliseconds) to place between
@@ -53,18 +56,14 @@ edit the text of this ID to identify the recordings. You
may, for instance, change it to have the same text as the
audio contains.
To help with this the Haven On-Demand online speech recognition
service is integrated with the system and can be used to try and convert the
audio into text. Right clicking on a recording brings
up a menu which includes the option to try and convert
the audio into text. The detected text is then used to
replace the current recording ID / text.
The audio can also be automatically converted to text if you have an suitable command-line
executable that will work. One example is (on Linux) [DeepSpeech](https://github.com/mozilla/DeepSpeech) by Mozilla.
File layout
-----------
All data is stored in your "storage" directory (specified in Options). Each book (which is a directory named after the
title of the book) has an associated XML file (audiobook.abk) and a directory "files" where all the audio (stored as WAV
title of the book) has an associated XML file (audiobook.abx) and a directory "files" where all the audio (stored as WAV
files) is placed.
When you export the book as MP3 a new folder "export" is created within the book's folder where the MP3 files are placed.
@@ -81,3 +80,26 @@ Building
5. Build with `ant build`
6. Run with `java -jar ./AudiobookRecorder.jar`
----
Extra Resources
===============
* DeepSpeech wrapper script
This is a small script that will convert the audio into a format DeepSpeech likes and call the `deepspeech` executable, removing any extra rubbish from the output. It
also requires `sox` to be installed for the audio conversion.
```
#!/bin/bash
ID=$$
FILE=$1
BINPATH=${HOME}/local/bin
MODELS=${HOME}/ds/deepspeech-0.6.1-models
sox "$FILE" -r 16000 -c 1 -b 16 "/tmp/ds-${ID}.wav"
${BINPATH}/deepspeech --model ${MODELS}/output_graph.pbmm --lm ${MODELS}/lm.binary --trie ${MODELS}/trie --audio "/tmp/ds-${ID}.wav" 2>/dev/null
rm /tmp/ds-${ID}.wav
```

BIN
deps/commons-lang3.jar LFS vendored Normal file

Binary file not shown.

BIN
deps/commons-text.jar LFS vendored Normal file

Binary file not shown.

BIN
deps/json-20190722.jar LFS vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,133 +0,0 @@
/*
* Copyright (C) 2002-2006 Felipe Rivera <liebremx at users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* Coefficient stuff
*
* $Id: iir_cfs.c,v 1.2 2006/01/15 00:17:46 liebremx Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
static const double band_f031[] =
{ 20,25,31.5,40,50,63,80,100,125,160,200,250,315,400,500,630,800,
1000,1250,1600,2000,2500,3150,4000,5000,6300,8000,10000,12500,16000,20000
};
#define GAIN_F0 1.0
#define GAIN_F1 GAIN_F0 / M_SQRT2
#define SAMPLING_FREQ 44100.0
#define TETA(f) (2*M_PI*(double)f/sample_frequency)
#define TWOPOWER(value) (value * value)
#define BETA2(tf0, tf) \
(TWOPOWER(GAIN_F1)*TWOPOWER(cos(tf0)) \
- 2.0 * TWOPOWER(GAIN_F1) * cos(tf) * cos(tf0) \
+ TWOPOWER(GAIN_F1) \
- TWOPOWER(GAIN_F0) * TWOPOWER(sin(tf)))
#define BETA1(tf0, tf) \
(2.0 * TWOPOWER(GAIN_F1) * TWOPOWER(cos(tf)) \
+ TWOPOWER(GAIN_F1) * TWOPOWER(cos(tf0)) \
- 2.0 * TWOPOWER(GAIN_F1) * cos(tf) * cos(tf0) \
- TWOPOWER(GAIN_F1) + TWOPOWER(GAIN_F0) * TWOPOWER(sin(tf)))
#define BETA0(tf0, tf) \
(0.25 * TWOPOWER(GAIN_F1) * TWOPOWER(cos(tf0)) \
- 0.5 * TWOPOWER(GAIN_F1) * cos(tf) * cos(tf0) \
+ 0.25 * TWOPOWER(GAIN_F1) \
- 0.25 * TWOPOWER(GAIN_F0) * TWOPOWER(sin(tf)))
#define GAMMA(beta, tf0) ((0.5 + beta) * cos(tf0))
#define ALPHA(beta) ((0.5 - beta)/2.0)
/*************
* Functions *
*************/
/* Get the band_f031 at both sides of F0. These will be cut at -3dB */
static void find_f1_and_f2(double f0, double octave_percent, double *f1, double *f2)
{
double octave_factor = pow(2.0, octave_percent/2.0);
*f1 = f0/octave_factor;
*f2 = f0*octave_factor;
}
/* Find the quadratic root
* Always return the smallest root */
static int find_root(double a, double b, double c, double *x0) {
double k = c-((b*b)/(4.*a));
double h = -(b/(2.*a));
double x1 = 0.;
if (-(k/a) < 0.)
return -1;
*x0 = h - sqrt(-(k/a));
x1 = h + sqrt(-(k/a));
if (x1 < *x0)
*x0 = x1;
return 0;
}
void calc_coeffs(double sample_frequency)
{
int i, n;
double f1, f2;
double x0;
printf(" public final static IIRCoefficients iir_cf31_%d[] = {\n", (int)sample_frequency);
for (i = 0; i < 31; i++) {
/* Find -3dB frequencies for the center freq */
find_f1_and_f2(band_f031[i], 1.0/3.0, &f1, &f2);
/* Find Beta */
if ( find_root(
BETA2(TETA(band_f031[i]), TETA(f1)),
BETA1(TETA(band_f031[i]), TETA(f1)),
BETA0(TETA(band_f031[i]), TETA(f1)),
&x0) == 0)
{
/* Got a solution, now calculate the rest of the factors */
/* Take the smallest root always (find_root returns the smallest one)
*
* NOTE: The IIR equation is
* y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2])
* Now the 2 factor has been distributed in the coefficients
*/
/* Now store the coefficients */
printf(" /* %.1f Hz */\n", band_f031[i]);
printf(" new IIRCoefficients(%.10e, %010e, %.10e),\n",
(double)(2.0 * x0),
(double)(2.0 * ALPHA(x0)),
(double)(2.0 * GAMMA(x0, TETA(band_f031[i])))
);
} else {
printf(" **** Where are the roots?\n");
}
}// for i
printf(" };\n");
}
int main(int argc, char **argv) {
if (argc != 2) {
printf("Usage: iircoeff <sample frequency>\n");
return -1;
}
double f = strtod(argv[1], NULL);
calc_coeffs(f);
}

View File

@@ -1,76 +0,0 @@
#!/usr/bin/perl
use Math::Trig;
my $fs = 48000;
my $q = 1.414;
printCo(20, $fs, $q);
printCo(25, $fs, $q);
printCo(31.5, $fs, $q);
printCo(40, $fs, $q);
printCo(50, $fs, $q);
printCo(63, $fs, $q);
printCo(80, $fs, $q);
printCo(100, $fs, $q);
printCo(125, $fs, $q);
printCo(160, $fs, $q);
printCo(200, $fs, $q);
printCo(250, $fs, $q);
printCo(315, $fs, $q);
printCo(400, $fs, $q);
printCo(500, $fs, $q);
printCo(630, $fs, $q);
printCo(800, $fs, $q);
printCo(1000, $fs, $q);
printCo(1250, $fs, $q);
printCo(1600, $fs, $q);
printCo(2000, $fs, $q);
printCo(2500, $fs, $q);
printCo(3150, $fs, $q);
printCo(4000, $fs, $q);
printCo(5000, $fs, $q);
printCo(6300, $fs, $q);
printCo(8000, $fs, $q);
printCo(10000, $fs, $q);
printCo(12500, $fs, $q);
printCo(16000, $fs, $q);
printCo(20000, $fs, $q);
sub printCo($$$$) {
my $f0 = shift;
my $fs = shift;
my $q = shift;
@coeff = coefficient($f0, $fs, $q);
print "/* $f0 Hz */\n";
printf("new IIRCoefficients(%.10e, %.10e, %.10e),\n" , $coeff[1] * 2, $coeff[0] * 2, $coeff[2] * 2);
}
sub coefficient($$$$) {
my $f0 = shift;
my $fs = shift;
my $q = shift;
my $q2 = $q * $q;
my $f1 = $f0 * (sqrt(1 + (1 / (4 * $q2))) - (1 / (2 * $q)));
my $f2 = $f0 * (sqrt(1 + (1 / (4 * $q2))) + (1 / (2 * $q)));
my $pi = 3.141592653;
my $theta0 = 2 * $pi * ($f0 / $fs);
my $thetaOverTwoQ = $theta0 / (2 * $q);
my $beta = 0.5 * ((1 - tan($thetaOverTwoQ)) / (1 + tan($thetaOverTwoQ)));
my $gamma = (0.5 + $beta) * cos($theta0);
my $alpha = (0.5 - $beta) / 2;
return ($alpha, $beta, $gamma);
}

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" output="demo/ExitCodeApp/build" path="demo/ExitCodeApp/src"/>
<classpathentry kind="src" output="demo/SimpleApp/build" path="demo/SimpleApp/src"/>
<classpathentry kind="src" output="demo/ConsoleApp/build" path="demo/ConsoleApp/src"/>
<classpathentry kind="lib" path="lib/formsrt.jar"/>

1
launch4j/.gitignore vendored
View File

@@ -1 +1,2 @@
/build
/target

View File

@@ -1,7 +1,7 @@
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2015 Grzegorz Kowal
Copyright (c) 2004, 2017 Grzegorz Kowal
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

View File

@@ -4,6 +4,8 @@
<property name="build" location="build" />
<property name="jar" location="./${ant.project.name}.jar" />
<property name="launch4j.dir" location="." />
<property name="maven" location="maven" />
<property file="${src}/launch4j.properties"/>
<path id="dist.classpath">
<pathelement path="${build}" />
@@ -59,4 +61,17 @@
<ant dir="./demo/ConsoleApp" target="clean" inheritAll="false" />
<ant dir="./demo/SimpleApp" target="clean" inheritAll="false" />
</target>
<target name="switch-to-maven" description="switch project to maven">
<copy todir="." overwrite="true">
<fileset dir="${maven}">
<include name="**/*" />
</fileset>
</copy>
<replace file="./pom.xml">
<replacefilter token="$${launch4j.version}" value="${version}"/>
</replace>
<delete dir="${lib}" />
<mkdir dir="./target" />
</target>
</project>

Binary file not shown.

View File

@@ -42,7 +42,7 @@
<taskdef name="launch4j" classname="net.sf.launch4j.ant.Launch4jTask" classpath="${launch4j.dir}/launch4j.jar
:${launch4j.dir}/lib/xstream.jar" />
<launch4j>
<config headerType="console" jar="ConsoleApp.jar" outfile="ConsoleApp.exe" errTitle="ConsoleApp" chdir="." icon="l4j/ConsoleApp.ico">
<config headerType="console" jarPath="ConsoleApp.jar" dontWrapJar="true" outfile="ConsoleApp.exe" errTitle="ConsoleApp" chdir="." icon="l4j/ConsoleApp.ico">
<singleInstance mutexName="net.sf.launch4j.example.ConsoleApp" />
<jre minVersion="1.6.0" />
</config>

2
launch4j/demo/ExitCodeApp/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/build
/target

View File

@@ -0,0 +1,72 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sf.launch4j.example</groupId>
<artifactId>ExitCodeApp</artifactId>
<version>1.0</version>
<name>ExitCodeApp</name>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<artifactId>launch4j-maven-plugin</artifactId>
<version>1.7.6</version>
<executions>
<execution>
<id>l4j</id>
<phase>package</phase>
<goals><goal>launch4j</goal></goals>
<configuration>
<headerType>console</headerType>
<outfile>target/ExitCodeApp.exe</outfile>
<jar>target/ExitCodeApp-1.0.jar</jar>
<errTitle>ExitCodeApp</errTitle>
<classPath>
<mainClass>net.sf.launch4j.example.ExitCodeApp</mainClass>
<addDependencies>false</addDependencies>
<preCp>anything</preCp>
</classPath>
<jre>
<minVersion>1.5.0</minVersion>
</jre>
<versionInfo>
<fileVersion>1.0.0.0</fileVersion>
<txtFileVersion>1.0</txtFileVersion>
<fileDescription>Simple app for testing exit code.</fileDescription>
<copyright>Copyright (C) 2015 GK</copyright>
<productVersion>3.9.0.0</productVersion>
<txtProductVersion>3.9</txtProductVersion>
<productName>ExitCodeApp</productName>
<internalName>ExitCodeApp</internalName>
<originalFilename>ExitCodeApp.exe</originalFilename>
</versionInfo>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,47 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2015 Grzegorz Kowal
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.sf.launch4j.example;
public class ExitCodeApp {
public static void main(String[] args) {
int exitCode = 0;
if (args.length > 0) {
exitCode = Integer.parseInt(args[0]);
}
System.out.println("Exit code: " + String.valueOf(exitCode));
System.exit(exitCode);
}
}

Binary file not shown.

View File

@@ -1,6 +1,7 @@
<launch4jConfig>
<headerType>gui</headerType>
<jar>../SimpleApp.jar</jar>
<jar>SimpleApp.jar</jar>
<dontWrapJar>true</dontWrapJar>
<outfile>../SimpleApp.exe</outfile>
<errTitle>SimpleApp</errTitle>
<chdir>.</chdir>

View File

@@ -34,31 +34,63 @@
package net.sf.launch4j.example;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
public class SimpleApp extends JFrame {
public SimpleApp(String[] args) {
super("Java Application");
public SimpleApp(String[] args) {
super("Java Application");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if (args.length == 1 && "throw".equals(args[0])) {
throw new IllegalStateException("Exception thrown from SimpleApp.");
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
setBounds (screenSize.width / 4, screenSize.height / 4, screenSize.width / 2, screenSize.height / 2);
JMenu menu = new JMenu("File");
menu.add(new JMenuItem("Open"));
menu.add(new JMenuItem("Save"));
menu.addSeparator();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}});
initializeMenu();
initializeTextArea(args);
setVisible(true);
}
public static void setLAF() {
JFrame.setDefaultLookAndFeelDecorated(true);
Toolkit.getDefaultToolkit().setDynamicLayout(true);
System.setProperty("sun.awt.noerasebackground","true");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
System.err.println("Failed to set LookAndFeel");
}
}
public static void main(String[] args) {
setLAF();
new SimpleApp(args);
}
private final void initializeMenu() {
JMenu menu = new JMenu("Exit with code");
menu.add(new JMenuItem(new AbstractAction("Exit with code 0") {
@Override
@@ -78,45 +110,86 @@ public class SimpleApp extends JFrame {
mb.setOpaque(true);
mb.add(menu);
setJMenuBar(mb);
}
private final void initializeTextArea(String[] args) {
JTextArea textArea = new JTextArea();
textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
textArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
getContentPane().add(scrollPane);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}});
setVisible(true);
textArea.setText(getMainProperties(args));
textArea.append(getAllProperties());
textArea.append(getEnvironmentVariables());
}
private final String getMainProperties(String[] args) {
StringBuffer sb = new StringBuffer("Java version: ");
sb.append(System.getProperty("java.version"));
sb.append("\nJava home: ");
sb.append(System.getProperty("java.home"));
sb.append("\nCurrent dir: ");
sb.append(System.getProperty("user.dir"));
if (args.length > 0) {
sb.append("\nArgs: ");
for (int i = 0; i < args.length; i++) {
sb.append(args[i]);
sb.append("\nCommand line args: {");
for (int i = 0; i < args.length; i++) {
if (i > 0)
{
sb.append(' ');
}
sb.append(args[i]);
}
JOptionPane.showMessageDialog(this,
sb.toString(),
"Info",
JOptionPane.INFORMATION_MESSAGE);
}
public static void setLAF() {
JFrame.setDefaultLookAndFeelDecorated(true);
Toolkit.getDefaultToolkit().setDynamicLayout(true);
System.setProperty("sun.awt.noerasebackground","true");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception e) {
System.err.println("Failed to set LookAndFeel");
}
sb.append("}\n");
final int mb = 1024 * 1024;
sb.append("Free memory (MB): ");
sb.append(Runtime.getRuntime().freeMemory() / mb);
sb.append("\nTotal memory (MB): ");
sb.append(Runtime.getRuntime().totalMemory() / mb);
sb.append("\nMax memory (MB): ");
sb.append(Runtime.getRuntime().maxMemory() / mb);
sb.append("\n");
return sb.toString();
}
private final String getAllProperties() {
StringBuffer sb = new StringBuffer("\n========== All properties ==========\n");
public static void main(String[] args) {
setLAF();
new SimpleApp(args);
List<String> keys = new ArrayList<String>();
keys.addAll(System.getProperties().stringPropertyNames());
Collections.sort(keys);
for (String key : keys) {
sb.append(key);
sb.append(": ");
sb.append(System.getProperty(key));
sb.append("\n");
}
return sb.toString();
}
private final String getEnvironmentVariables() {
StringBuffer sb = new StringBuffer("\n========== Environment variables ==========\n");
List<String> keys = new ArrayList<String>();
keys.addAll(System.getenv().keySet());
Collections.sort(keys);
for (String key : keys) {
sb.append(key);
sb.append(": ");
sb.append(System.getenv(key));
sb.append("\n");
}
return sb.toString();
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,26 @@
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2015 Grzegorz Kowal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -91,6 +91,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
splashTimeout = DEFAULT_SPLASH_TIMEOUT;
}
}
splashTimeout = splashTimeout * 1000; // to millis
splashTimeoutErr = loadBool(SPLASH_TIMEOUT_ERR)
&& strstr(lpCmdLine, "--l4j-no-splash-err") == NULL;
waitForWindow = loadBool(SPLASH_WAITS_FOR_WINDOW);
@@ -120,7 +121,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
{
if (splash || stayAlive)
{
if (!SetTimer (hWnd, ID_TIMER, 1000 /* 1s */, TimerProc))
if (!SetTimer (hWnd, ID_TIMER, TIMER_PROC_INTERVAL, TimerProc))
{
signalError();
return 1;
@@ -222,7 +223,7 @@ VOID CALLBACK TimerProc(
}
else
{
splashTimeout--;
splashTimeout -= TIMER_PROC_INTERVAL;
if (waitForWindow)
{
EnumWindows(enumwndfn, 0);

View File

@@ -30,6 +30,7 @@
#define ID_TIMER 1
#define DEFAULT_SPLASH_TIMEOUT 60 /* 60 seconds */
#define MAX_SPLASH_TIMEOUT 60 * 15 /* 15 minutes */
#define TIMER_PROC_INTERVAL 100 /* interval in ms between calls to EnumWindows */
HWND getInstanceWindow();

View File

@@ -55,6 +55,8 @@ struct
int foundJava;
BOOL bundledJreAsFallback;
BOOL corruptedJreFound;
char originalJavaMinVer[STR];
char originalJavaMaxVer[STR];
char javaMinVer[STR];
char javaMaxVer[STR];
char foundJavaVer[STR];
@@ -64,6 +66,7 @@ struct
struct
{
char mainClass[_MAX_PATH];
char cmd[_MAX_PATH];
char args[MAX_ARGS];
} launcher;
@@ -150,7 +153,14 @@ void msgBox(const char* text)
{
if (console)
{
printf("%s: %s\n", error.title, text);
if (*error.title)
{
printf("%s: %s\n", error.title, text);
}
else
{
printf("%s\n", text);
}
}
else
{
@@ -197,6 +207,7 @@ BOOL loadString(const int resID, char* buffer)
HRSRC hResource;
HGLOBAL hResourceLoaded;
LPBYTE lpBuffer;
debugAll("Resource %d:\t", resID);
hResource = FindResourceEx(hModule, RT_RCDATA, MAKEINTRESOURCE(resID),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
@@ -214,10 +225,7 @@ BOOL loadString(const int resID, char* buffer)
buffer[x] = (char) lpBuffer[x];
} while (buffer[x++] != 0);
if (debugAll)
{
debug("Resource %d:\t%s\n", resID, buffer);
}
debugAll("%s\n", buffer);
return TRUE;
}
}
@@ -227,6 +235,8 @@ BOOL loadString(const int resID, char* buffer)
SetLastError(0);
buffer[0] = 0;
}
debugAll("<NULL>\n");
return FALSE;
}
@@ -302,6 +312,120 @@ BOOL regQueryValue(const char* regPath, unsigned char* buffer,
return result;
}
int findNextVersionPart(const char* startAt)
{
if (startAt == NULL || strlen(startAt) == 0)
{
return 0;
}
char* firstSeparatorA = strchr(startAt, '.');
char* firstSeparatorB = strchr(startAt, '_');
char* firstSeparator;
if (firstSeparatorA == NULL)
{
firstSeparator = firstSeparatorB;
}
else if (firstSeparatorB == NULL)
{
firstSeparator = firstSeparatorA;
}
else
{
firstSeparator = min(firstSeparatorA, firstSeparatorB);
}
if (firstSeparator == NULL)
{
return strlen(startAt);
}
return firstSeparator - startAt;
}
/**
* This method will take java version from `originalVersion` string and convert/format it
* into `version` string that can be used for string comparison with other versions.
*
* Due to different version schemas <=8 vs. >=9 it will "normalize" versions to 1 format
* so we can directly compare old and new versions.
*/
void formatJavaVersion(char* version, const char* originalVersion)
{
strcpy(version, "");
if (originalVersion == NULL || strlen(originalVersion) == 0)
{
return;
}
int partsAdded = 0;
int i;
char* pos = (char*) originalVersion;
int curPartLen;
while ((curPartLen = findNextVersionPart(pos)) > 0)
{
char number[curPartLen + 1];
memset(number, 0, curPartLen + 1);
strncpy(number, pos, curPartLen);
if (partsAdded == 0 && (curPartLen != 1 || number[0] != '1'))
{
// NOTE: When it's java 9+ we'll add "1" as the first part of the version
strcpy(version, "1");
partsAdded++;
}
if (partsAdded < 3)
{
if (partsAdded > 0)
{
strcat(version, ".");
}
for (i = 0;
(partsAdded > 0)
&& (i < JRE_VER_MAX_DIGITS_PER_PART - strlen(number));
i++)
{
strcat(version, "0");
}
strcat(version, number);
}
else if (partsAdded == 3)
{
// add as an update
strcat(version, "_");
for (i = 0; i < JRE_VER_MAX_DIGITS_PER_PART - strlen(number); i++)
{
strcat(version, "0");
}
strcat(version, number);
}
else if (partsAdded >= 4)
{
debug("Warning:\tformatJavaVersion() too many parts added.\n");
break;
}
partsAdded++;
pos += curPartLen + 1;
if (pos >= originalVersion + strlen(originalVersion))
{
break;
}
}
for (i = partsAdded; i < 3; i++)
{
strcat(version, ".");
int j;
for (j = 0; j < JRE_VER_MAX_DIGITS_PER_PART; j++)
{
strcat(version, "0");
}
}
}
void regSearch(const char* keyName, const int searchType)
{
HKEY hKey;
@@ -322,12 +446,13 @@ void regSearch(const char* keyName, const int searchType)
unsigned long versionSize = _MAX_PATH;
FILETIME time;
char fullKeyName[_MAX_PATH] = {0};
char originalVersion[_MAX_PATH] = {0};
char version[_MAX_PATH] = {0};
while (RegEnumKeyEx(
hKey, // handle to key to enumerate
x++, // index of subkey to enumerate
version, // address of buffer for subkey name
originalVersion,// address of buffer for subkey name
&versionSize, // address for size of subkey buffer
NULL, // reserved
NULL, // address of buffer for class string
@@ -335,8 +460,9 @@ void regSearch(const char* keyName, const int searchType)
&time) == ERROR_SUCCESS)
{
strcpy(fullKeyName, keyName);
appendPath(fullKeyName, version);
appendPath(fullKeyName, originalVersion);
debug("Check:\t\t%s\n", fullKeyName);
formatJavaVersion(version, originalVersion);
if (strcmp(version, search.javaMinVer) >= 0
&& (!*search.javaMaxVer || strcmp(version, search.javaMaxVer) <= 0)
@@ -384,10 +510,6 @@ BOOL isJavaHomeValid(const char* keyName, const int searchType)
path[i] = buffer[i];
} while (path[i++] != 0);
if (searchType & FOUND_SDK)
{
appendPath(path, "jre");
}
valid = isLauncherPathValid(path);
}
RegCloseKey(hKey);
@@ -476,6 +598,10 @@ void regSearchWow(const char* keyName, const int searchType)
case USE_32_BIT_RUNTIME:
regSearch(keyName, searchType);
break;
default:
debug("Runtime bits:\tFailed to load.\n");
break;
}
}
@@ -503,10 +629,25 @@ void regSearchJreSdk(const char* jreKeyName, const char* sdkKeyName,
BOOL findJavaHome(char* path, const int jdkPreference)
{
debugAll("findJavaHome()\n");
regSearchJreSdk("SOFTWARE\\JavaSoft\\Java Runtime Environment",
"SOFTWARE\\JavaSoft\\Java Development Kit",
jdkPreference);
// Java 9 support
regSearchJreSdk("SOFTWARE\\JavaSoft\\JRE",
"SOFTWARE\\JavaSoft\\JDK",
jdkPreference);
// IBM Java 1.8
if (search.foundJava == NO_JAVA_FOUND)
{
regSearchJreSdk("SOFTWARE\\IBM\\Java Runtime Environment",
"SOFTWARE\\IBM\\Java Development Kit",
jdkPreference);
}
// IBM Java 1.7 and earlier
if (search.foundJava == NO_JAVA_FOUND)
{
regSearchJreSdk("SOFTWARE\\IBM\\Java2 Runtime Environment",
@@ -613,6 +754,10 @@ BOOL expandVars(char *dst, const char *src, const char *exePath, const int pathL
else if (strstr(varName, HKEY_STR) == varName)
{
regQueryValue(varName, dst + strlen(dst), BIG_STR);
}
else if (strcmp(varName, "") == 0)
{
strcat(dst, "%");
}
else if (GetEnvironmentVariable(varName, varValue, MAX_VAR_SIZE) > 0)
{
@@ -733,6 +878,7 @@ BOOL createMutex()
if (*mutexName)
{
debug("Create mutex:\t%s\n", mutexName);
SECURITY_ATTRIBUTES security;
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = TRUE;
@@ -767,8 +913,16 @@ void setWorkingDirectory(const char *exePath, const int pathLen)
BOOL bundledJreSearch(const char *exePath, const int pathLen)
{
debugAll("bundledJreSearch()\n");
char tmpPath[_MAX_PATH] = {0};
BOOL is64BitJre = loadBool(BUNDLED_JRE_64_BIT);
if (!wow64 && is64BitJre)
{
debug("Bundled JRE:\tCannot use 64-bit runtime on 32-bit OS.\n");
return FALSE;
}
if (loadString(JRE_PATH, tmpPath))
{
char jrePath[MAX_ARGS] = {0};
@@ -789,9 +943,7 @@ BOOL bundledJreSearch(const char *exePath, const int pathLen)
if (isLauncherPathValid(launcher.cmd))
{
search.foundJava = (wow64 && loadBool(BUNDLED_JRE_64_BIT))
? FOUND_BUNDLED | KEY_WOW64_64KEY
: FOUND_BUNDLED;
search.foundJava = is64BitJre ? FOUND_BUNDLED | KEY_WOW64_64KEY : FOUND_BUNDLED;
strcpy(search.foundJavaHome, launcher.cmd);
return TRUE;
}
@@ -802,6 +954,7 @@ BOOL bundledJreSearch(const char *exePath, const int pathLen)
BOOL installedJreSearch()
{
debugAll("installedJreSearch()\n");
return *search.javaMinVer && findJavaHome(launcher.cmd, loadInt(JDK_PREFERENCE));
}
@@ -811,12 +964,12 @@ void createJreSearchError()
{
loadString(JRE_VERSION_ERR, error.msg);
strcat(error.msg, " ");
strcat(error.msg, search.javaMinVer);
strcat(error.msg, search.originalJavaMinVer);
if (*search.javaMaxVer)
{
strcat(error.msg, " - ");
strcat(error.msg, search.javaMaxVer);
strcat(error.msg, search.originalJavaMaxVer);
}
if (search.runtimeBits == USE_64_BIT_RUNTIME
@@ -848,11 +1001,16 @@ void createJreSearchError()
BOOL jreSearch(const char *exePath, const int pathLen)
{
debugAll("jreSearch()\n");
BOOL result = TRUE;
search.bundledJreAsFallback = loadBool(BUNDLED_JRE_AS_FALLBACK);
loadString(JAVA_MIN_VER, search.javaMinVer);
loadString(JAVA_MAX_VER, search.javaMaxVer);
loadString(JAVA_MIN_VER, search.originalJavaMinVer);
formatJavaVersion(search.javaMinVer, search.originalJavaMinVer);
debug("Java min ver:\t%s\n", search.javaMinVer);
loadString(JAVA_MAX_VER, search.originalJavaMaxVer);
formatJavaVersion(search.javaMaxVer, search.originalJavaMaxVer);
debug("Java max ver:\t%s\n", search.javaMaxVer);
if (search.bundledJreAsFallback)
{
@@ -934,14 +1092,15 @@ void setMainClassAndClassPath(const char *exePath, const int pathLen)
{
char classPath[MAX_ARGS] = {0};
char expandedClassPath[MAX_ARGS] = {0};
char mainClass[STR] = {0};
char jar[_MAX_PATH] = {0};
char fullFileName[_MAX_PATH] = {0};
const BOOL wrapper = loadBool(WRAPPER);
loadString(JAR, jar);
if (loadString(MAIN_CLASS, mainClass))
if (loadString(MAIN_CLASS, launcher.mainClass))
{
debug("Main class:\t%s\n", launcher.mainClass);
if (!loadString(CLASSPATH, classPath))
{
debug("Info:\t\tClasspath not defined.\n");
@@ -997,7 +1156,7 @@ void setMainClassAndClassPath(const char *exePath, const int pathLen)
*(launcher.args + strlen(launcher.args) - 1) = 0;
strcat(launcher.args, "\" ");
strcat(launcher.args, mainClass);
strcat(launcher.args, launcher.mainClass);
}
else if (wrapper)
{
@@ -1158,3 +1317,19 @@ BOOL execute(const BOOL wait, DWORD *dwExitCode)
*dwExitCode = -1;
return FALSE;
}
const char* getJavaHome()
{
return search.foundJavaHome;
}
const char* getMainClass()
{
return launcher.mainClass;
}
const char* getLauncherArgs()
{
return launcher.args;
}

View File

@@ -28,10 +28,13 @@
THE SOFTWARE.
*/
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif // _WIN32_WINNT
#ifndef _LAUNCH4J_HEAD__INCLUDED_
#define _LAUNCH4J_HEAD__INCLUDED_
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN // VC - Exclude rarely-used stuff from Windows headers
// Windows Header Files:
@@ -51,7 +54,9 @@
#include <process.h>
#define LAUNCH4j "Launch4j"
#define VERSION "3.7"
#define VERSION "3.12"
#define JRE_VER_MAX_DIGITS_PER_PART 3
#define NO_JAVA_FOUND 0
#define FOUND_JRE 1
@@ -88,6 +93,7 @@
#define ERROR_FORMAT "Error:\t\t%s\n"
#define debug(args...) if (hLog != NULL) fprintf(hLog, ## args);
#define debugAll(args...) if (debugAll && hLog != NULL) fprintf(hLog, ## args);
typedef void (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
@@ -102,6 +108,7 @@ BOOL loadBool(const int resID);
int loadInt(const int resID);
BOOL regQueryValue(const char* regPath, unsigned char* buffer,
unsigned long bufferLength);
void formatJavaVersion(char* version, const char* originalVersion);
void regSearch(const char* keyName, const int searchType);
BOOL isJavaHomeValid(const char* keyName, const int searchType);
BOOL isLauncherPathValid(const char* path);
@@ -132,5 +139,8 @@ void setCommandLineArgs(const char *lpCmdLine);
int prepare(const char *lpCmdLine);
void closeProcessHandles();
BOOL execute(const BOOL wait, DWORD *dwExitCode);
const char* getJavaHome();
const char* getMainClass();
const char* getLauncherArgs();
#endif // _LAUNCH4J_HEAD__INCLUDED_

View File

@@ -0,0 +1,2 @@
/jniconsolehead.exe
/jniconsolehead.layout

View File

@@ -0,0 +1,34 @@
# Project: jniconsolehead
# Makefile created by Dev-C++ 5.7.1
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = ../../head_jni_BETA/jniconsolehead.o ../../head_jni_BETA/head.o ../../head_jni_BETA/jnihead.o
LINKOBJ = ../../head_jni_BETA/jniconsolehead.o ../../head_jni_BETA/head.o ../../head_jni_BETA/jnihead.o
LIBS = -L"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib" -L"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/lib" -static-libstdc++ -static-libgcc -n -s
INCS = -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include/win32"
CXXINCS = -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include/c++" -I"C:/Program Files (x86)/Java/jdk 1.4/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include/win32"
BIN = jniconsolehead.exe
CXXFLAGS = $(CXXINCS) -Os
CFLAGS = $(INCS) -Os
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
../../head_jni_BETA/jniconsolehead.o: jniconsolehead.c
$(CC) -c jniconsolehead.c -o ../../head_jni_BETA/jniconsolehead.o $(CFLAGS)
../../head_jni_BETA/head.o: ../head.c
$(CC) -c ../head.c -o ../../head_jni_BETA/head.o $(CFLAGS)
../../head_jni_BETA/jnihead.o: ../jnihead.c
$(CC) -c ../jnihead.c -o ../../head_jni_BETA/jnihead.o $(CFLAGS)

View File

@@ -0,0 +1,99 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2007 Grzegorz Kowal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "../resource.h"
#include "../head.h"
#include "../jnihead.h"
extern FILE* hLog;
BOOL restartOnCrash = FALSE;
int main(int argc, char* argv[])
{
setConsoleFlag();
LPTSTR cmdLine = GetCommandLine();
if (*cmdLine == '"')
{
if (*(cmdLine = strchr(cmdLine + 1, '"') + 1))
{
cmdLine++;
}
}
else if ((cmdLine = strchr(cmdLine, ' ')) != NULL)
{
cmdLine++;
}
else
{
cmdLine = "";
}
int result = prepare(cmdLine);
if (result == ERROR_ALREADY_EXISTS)
{
char errMsg[BIG_STR] = {0};
loadString(INSTANCE_ALREADY_EXISTS_MSG, errMsg);
msgBox(errMsg);
closeLogFile();
return 2;
}
if (result != TRUE)
{
signalError();
return 1;
}
restartOnCrash = loadBool(RESTART_ON_CRASH);
DWORD dwExitCode;
do
{
dwExitCode = 0;
saveJvmOptions(getJavaHome(), getMainClass(), getLauncherArgs());
if (!executeVm(&dwExitCode))
{
signalError();
break;
}
if (restartOnCrash && dwExitCode != 0)
{
debug("Exit code:\t%d, restarting the application!\n", dwExitCode);
}
} while (restartOnCrash && dwExitCode != 0);
debug("Exit code:\t%d\n", dwExitCode);
closeLogFile();
return (int) dwExitCode;
}

View File

@@ -0,0 +1,112 @@
[Project]
FileName=jniconsolehead.dev
Name=jniconsolehead
UnitCount=6
Type=1
Ver=2
ObjFiles=
Includes="C:\Program Files (x86)\Java\jdk 1.4\include";"C:\Program Files (x86)\Java\jdk 1.4\include\win32"
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=-n_@@_
IsCpp=0
Icon=
ExeOutput=
ObjectOutput=..\..\head_jni_BETA
OverrideOutput=0
OverrideOutputName=jniconsolehead.exe
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=Makefile.win
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=000000d000000000000001000
LogOutput=
LogOutputEnabled=0
[Unit1]
FileName=jniconsolehead.c
CompileCpp=0
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1.1.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
SyncProduct=0
[Unit2]
FileName=..\resource.h
CompileCpp=0
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=..\head.c
CompileCpp=0
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit4]
FileName=..\head.h
CompileCpp=0
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit5]
FileName=..\jnihead.h
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
CompileCpp=0
[Unit6]
FileName=..\jnihead.c
CompileCpp=0
Folder=jniconsolehead
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@@ -0,0 +1,2 @@
/jniguihead.exe
/jniguihead.layout

View File

@@ -0,0 +1,34 @@
# Project: jniguihead
# Makefile created by Dev-C++ 5.7.1
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
OBJ = ../../head_jni_BETA/jniguihead.o ../../head_jni_BETA/head.o ../../head_jni_BETA/jnihead.o
LINKOBJ = ../../head_jni_BETA/jniguihead.o ../../head_jni_BETA/head.o ../../head_jni_BETA/jnihead.o
LIBS = -L"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib" -L"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/lib" -static-libstdc++ -static-libgcc -mwindows -n -s
INCS = -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include/win32"
CXXINCS = -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/mingw32/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include" -I"C:/Users/GMan/Dev-Cpp 5.7.1/MinGW32/lib/gcc/mingw32/4.8.1/include/c++" -I"C:/Program Files (x86)/Java/jdk 1.4/include" -I"C:/Program Files (x86)/Java/jdk 1.4/include/win32"
BIN = jniguihead.exe
CXXFLAGS = $(CXXINCS) -Os
CFLAGS = $(INCS) -Os
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS)
../../head_jni_BETA/jniguihead.o: jniguihead.c
$(CC) -c jniguihead.c -o ../../head_jni_BETA/jniguihead.o $(CFLAGS)
../../head_jni_BETA/head.o: ../head.c
$(CC) -c ../head.c -o ../../head_jni_BETA/head.o $(CFLAGS)
../../head_jni_BETA/jnihead.o: ../jnihead.c
$(CC) -c ../jnihead.c -o ../../head_jni_BETA/jnihead.o $(CFLAGS)

View File

@@ -0,0 +1,244 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2015 Grzegorz Kowal
Sylvain Mina (single instance patch)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "../resource.h"
#include "../head.h"
#include "../jnihead.h"
#include "jniguihead.h"
extern FILE* hLog;
extern PROCESS_INFORMATION processInformation;
HWND hWnd;
DWORD dwExitCode = 0;
BOOL stayAlive = FALSE;
BOOL splash = FALSE;
BOOL splashTimeoutErr;
BOOL waitForWindow;
BOOL restartOnCrash = FALSE;
int splashTimeout = DEFAULT_SPLASH_TIMEOUT;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
int result = prepare(lpCmdLine);
if (result == ERROR_ALREADY_EXISTS)
{
HWND handle = getInstanceWindow();
ShowWindow(handle, SW_SHOW);
SetForegroundWindow(handle);
closeLogFile();
return 2;
}
if (result != TRUE)
{
signalError();
return 1;
}
splash = loadBool(SHOW_SPLASH)
&& strstr(lpCmdLine, "--l4j-no-splash") == NULL;
restartOnCrash = loadBool(RESTART_ON_CRASH);
// if we should restart on crash, we must also stay alive to check for crashes
stayAlive = restartOnCrash ||
(loadBool(GUI_HEADER_STAYS_ALIVE)
&& strstr(lpCmdLine, "--l4j-dont-wait") == NULL);
if (splash || stayAlive)
{
hWnd = CreateWindowEx(WS_EX_TOOLWINDOW, "STATIC", "",
WS_POPUP | SS_BITMAP,
0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (splash)
{
char timeout[10] = {0};
if (loadString(SPLASH_TIMEOUT, timeout))
{
splashTimeout = atoi(timeout);
if (splashTimeout <= 0 || splashTimeout > MAX_SPLASH_TIMEOUT)
{
splashTimeout = DEFAULT_SPLASH_TIMEOUT;
}
}
splashTimeoutErr = loadBool(SPLASH_TIMEOUT_ERR)
&& strstr(lpCmdLine, "--l4j-no-splash-err") == NULL;
waitForWindow = loadBool(SPLASH_WAITS_FOR_WINDOW);
HANDLE hImage = LoadImage(hInstance, // handle of the instance containing the image
MAKEINTRESOURCE(SPLASH_BITMAP), // name or identifier of image
IMAGE_BITMAP, // type of image
0, // desired width
0, // desired height
LR_DEFAULTSIZE);
if (hImage == NULL)
{
signalError();
return 1;
}
SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hImage);
RECT rect;
GetWindowRect(hWnd, &rect);
int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
SetWindowPos(hWnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
ShowWindow(hWnd, nCmdShow);
UpdateWindow (hWnd);
}
}
do
{
if (splash || stayAlive)
{
if (!SetTimer (hWnd, ID_TIMER, 1000 /* 1s */, TimerProc))
{
signalError();
return 1;
}
}
debug(getJavaHome());
saveJvmOptions(getJavaHome(), getMainClass(), getLauncherArgs());
if (!executeVm(&dwExitCode))
{
signalError();
return 1;
}
if (!(splash || stayAlive))
{
debug("Exit code:\t0\n");
closeProcessHandles();
closeLogFile();
return 0;
}
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (restartOnCrash && dwExitCode != 0)
{
debug("Exit code:\t%d, restarting the application!\n", dwExitCode);
}
closeProcessHandles();
} while (restartOnCrash && dwExitCode != 0);
debug("Exit code:\t%d\n", dwExitCode);
closeLogFile();
return dwExitCode;
}
HWND getInstanceWindow()
{
char windowTitle[STR];
char instWindowTitle[STR] = {0};
if (loadString(INSTANCE_WINDOW_TITLE, instWindowTitle))
{
HWND handle = FindWindowEx(NULL, NULL, NULL, NULL);
while (handle != NULL)
{
GetWindowText(handle, windowTitle, STR - 1);
if (strstr(windowTitle, instWindowTitle) != NULL)
{
return handle;
}
else
{
handle = FindWindowEx(NULL, handle, NULL, NULL);
}
}
}
return NULL;
}
BOOL CALLBACK enumwndfn(HWND hwnd, LPARAM lParam)
{
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if (processInformation.dwProcessId == processId)
{
LONG styles = GetWindowLong(hwnd, GWL_STYLE);
if ((styles & WS_VISIBLE) != 0)
{
splash = FALSE;
ShowWindow(hWnd, SW_HIDE);
return FALSE;
}
}
return TRUE;
}
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime) // current system time
{
if (splash)
{
if (splashTimeout == 0)
{
splash = FALSE;
ShowWindow(hWnd, SW_HIDE);
if (waitForWindow && splashTimeoutErr)
{
KillTimer(hwnd, ID_TIMER);
signalError();
PostQuitMessage(0);
}
}
else
{
splashTimeout--;
if (waitForWindow)
{
EnumWindows(enumwndfn, 0);
}
}
}
GetExitCodeProcess(processInformation.hProcess, &dwExitCode);
if (dwExitCode != STILL_ACTIVE
|| !(splash || stayAlive))
{
KillTimer(hWnd, ID_TIMER);
PostQuitMessage(0);
}
}

View File

@@ -0,0 +1,122 @@
[Project]
FileName=jniguihead.dev
Name=jniguihead
UnitCount=7
Type=0
Ver=2
ObjFiles=
Includes="C:\Program Files (x86)\Java\jdk 1.4\include";"C:\Program Files (x86)\Java\jdk 1.4\include\win32"
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=-n_@@_
IsCpp=0
Icon=
ExeOutput=
ObjectOutput=..\..\head_jni_BETA
OverrideOutput=0
OverrideOutputName=jniguihead.exe
HostApplication=
Folders=
CommandLine=
UseCustomMakefile=0
CustomMakefile=Makefile.win
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=000000d000000000000001000
LogOutput=
LogOutputEnabled=0
[Unit1]
FileName=jniguihead.c
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c jniguihead.c -o ../../head_jni_BETA/jniguihead.o $(CFLAGS)
[Unit2]
FileName=jniguihead.h
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=0.1.1.1
FileDescription=Developed using the Dev-C++ IDE
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0
SyncProduct=0
[Unit4]
FileName=..\head.h
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit6]
FileName=..\jnihead.c
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit3]
FileName=..\head.c
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=$(CC) -c head.c -o ../../head/head.o $(CFLAGS)
[Unit5]
FileName=..\resource.h
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[Unit7]
FileName=..\jnihead.h
CompileCpp=0
Folder=jniguihead_BETA
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=

View File

@@ -0,0 +1,43 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2007 Grzegorz Kowal
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define ID_TIMER 1
#define DEFAULT_SPLASH_TIMEOUT 60 /* 60 seconds */
#define MAX_SPLASH_TIMEOUT 60 * 15 /* 15 minutes */
HWND getInstanceWindow();
BOOL CALLBACK enumwndfn(HWND hwnd, LPARAM lParam);
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);

284
launch4j/head_src/jnihead.c Normal file
View File

@@ -0,0 +1,284 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2007 Ryan Rusaw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "jnihead.h"
/* Java Invocation API stuff */
typedef jint (JNICALL CreateJavaVM_t)(JavaVM **pvm, void **env, void *args);
JavaVM* g_pJavaVM = NULL;
JNIEnv* g_pJNIEnv = NULL;
JavaVMInitArgs g_sJavaVMInitArgs;
char g_rgcMnClsArgs[MAX_ARGS] = {0};
char g_rgcMnCls[_MAX_PATH] = {0};
char g_rgcCurrJrePth[_MAX_PATH] = {0};
HINSTANCE g_hInstance;
const char* g_pcSep = " \t\f\r\n\v";
int getArgCount(const char* pcArgStr)
{
const char *pCopy;
int iArgCnt= 0;
int bInWtSpc = 1;
for(pCopy = pcArgStr; *pCopy; pCopy++)
{
if (!isspace(*pCopy) && bInWtSpc)
{
iArgCnt++;
}
bInWtSpc = isspace(*pCopy);
}
return iArgCnt;
}
void saveJvmOptions(const char *jrePath, const char *mainClass, const char *pcOpts)
{
strcpy(g_rgcCurrJrePth, jrePath);
strcpy(g_rgcMnCls, mainClass);
char rgcOptCpy[MAX_ARGS] = {0};
int iArgCnt = 0, iCurrArg = 0, iSkipArgCnt = 0;
char *pcCurrOpt;
char **prgcVmArgs = NULL;
strncpy(rgcOptCpy, pcOpts, MAX_ARGS - 1);
iArgCnt = getArgCount(rgcOptCpy);
if (iArgCnt > 0)
{
/* Allocate iArgCnt char pointers */
prgcVmArgs = malloc(iArgCnt * sizeof(char *));
for (pcCurrOpt = strtok(rgcOptCpy, g_pcSep); pcCurrOpt; pcCurrOpt = strtok(NULL, g_pcSep), iCurrArg++)
{
/* Use the allocated pointers to make an array of substrings */
prgcVmArgs[iCurrArg] = pcCurrOpt;
}
/* Allocat iArgCnt JavaVMOptions for the g_sJavaVMInitArgs struct */
g_sJavaVMInitArgs.options = malloc(iArgCnt * sizeof(JavaVMOption));
memset(g_sJavaVMInitArgs.options, 0, iArgCnt * sizeof(JavaVMOption));
char* rgcClsPth = 0;
/* Copy the tokenized array into the allocated JavaVMOption array,
* with some special handling for classpath related arguments */
for (iCurrArg = 0; iCurrArg < iArgCnt; iCurrArg++)
{
if ((strcmp(prgcVmArgs[iCurrArg], "-classpath") == 0) ||
(strcmp(prgcVmArgs[iCurrArg], "-jar") == 0))
{
iCurrArg++;
iSkipArgCnt++;
if (iCurrArg < iArgCnt)
{
int iOffset = *prgcVmArgs[iCurrArg] == '"' ? 1 : 0;
char rgcTmp[MAX_ARGS] = {0};
/* Remove leading and trailing "'s */\
strncpy(rgcTmp, prgcVmArgs[iCurrArg] + iOffset,
strlen(prgcVmArgs[iCurrArg]) - iOffset);
if (rgcTmp[strlen(rgcTmp)-1] == '"')
rgcTmp[strlen(rgcTmp)-1] = '\0';
/* If we haven't defined a classpath yet start one, otherwise
* we just append the this classpath to it */
if (!rgcClsPth)
{
rgcClsPth = malloc(MAX_ARGS * sizeof(char));
memset(rgcClsPth, 0, MAX_ARGS * sizeof(char));
sprintf(rgcClsPth,"-Djava.class.path=%s", rgcTmp);
g_sJavaVMInitArgs.options[iCurrArg - iSkipArgCnt].optionString = rgcClsPth;
}
else
{
iSkipArgCnt++;
strcat(rgcClsPth,";");
strcat(rgcClsPth,rgcTmp);
}
}
}
else
{
g_sJavaVMInitArgs.options[iCurrArg - iSkipArgCnt].optionString
= malloc(strlen(prgcVmArgs[iCurrArg]) + 1);
strcpy(g_sJavaVMInitArgs.options[iCurrArg - iSkipArgCnt].optionString,
prgcVmArgs[iCurrArg]);
}
}
g_sJavaVMInitArgs.nOptions = iArgCnt - iSkipArgCnt;
/* Free the malloc'd memory, we dont want to leak */
free(prgcVmArgs);
}
}
JNIEnv* createVm()
{
int iRetVal;
CreateJavaVM_t *pfnCreateJavaVM;
char rgcLibPth[_MAX_PATH + 18];
// sprintf(rgcLibPth, "%s\\bin\\client\\jvm.dll", g_rgcCurrJrePth); // TODO - could be client or server
sprintf(rgcLibPth, "%s\\bin\\client\\jvm.dll", g_rgcCurrJrePth);
/* Get a handle to the jvm dll */
if ((g_hInstance = LoadLibrary(rgcLibPth)) == NULL)
{
return NULL;
}
/* Get the CreateJavaVM() function */
pfnCreateJavaVM = (CreateJavaVM_t *)GetProcAddress(g_hInstance, "JNI_CreateJavaVM");
if (pfnCreateJavaVM == NULL)
{
return NULL;
}
g_sJavaVMInitArgs.version = JNI_VERSION_1_2;
g_sJavaVMInitArgs.ignoreUnrecognized = JNI_TRUE;
/* Start the VM */
iRetVal = pfnCreateJavaVM(&g_pJavaVM, (void **)&g_pJNIEnv, &g_sJavaVMInitArgs);
if (iRetVal != 0)
{
return NULL;
}
return g_pJNIEnv;
}
int invokeMainClass(JNIEnv* psJNIEnv)
{
jclass jcMnCls;
jmethodID jmMnMthd;
jobjectArray joAppArgs;
jstring jsAppArg;
jthrowable jtExcptn;
char *pcCurrArg;
int iArgCnt= 0, iOption = -1;
char rgcMnClsCpy[MAX_ARGS] = {0};
/* Ensure Java JNI Env is set up */
if(psJNIEnv == NULL)
{
return -1;
}
/* We need a class name */
if (g_rgcMnCls[0] == '\0')
{
return -1;
}
else
{
/* Replace . with / in fully qualified class name */
char *pClsNm;
for(pClsNm = g_rgcMnCls; *pClsNm; pClsNm++)
{
if(*pClsNm == '.')
*pClsNm = '/';
}
}
/* Find the class */
jcMnCls = (*psJNIEnv)->FindClass(psJNIEnv, g_rgcMnCls);
jtExcptn = (*psJNIEnv)->ExceptionOccurred(psJNIEnv);
if (jtExcptn != NULL)
{
(*psJNIEnv)->ExceptionDescribe(psJNIEnv);
return -1;
}
if (jcMnCls == NULL)
{
return -1;
}
/* Get the static main method */
jmMnMthd = (*psJNIEnv)->GetStaticMethodID(psJNIEnv, jcMnCls, "main", "([Ljava/lang/String;)V");
jtExcptn = (*psJNIEnv)->ExceptionOccurred(psJNIEnv);
if (jtExcptn != NULL)
{
(*psJNIEnv)->ExceptionDescribe(psJNIEnv);
}
if (jmMnMthd == NULL)
{
return -1;
}
/* Build the String[] array if we need one */
strncpy(rgcMnClsCpy, g_rgcMnClsArgs, MAX_ARGS);
iArgCnt = getArgCount(rgcMnClsCpy);
joAppArgs = (jobjectArray)(*psJNIEnv)->NewObjectArray(psJNIEnv, iArgCnt,
(*psJNIEnv)->FindClass(psJNIEnv, "java/lang/String"), NULL);
jtExcptn = (*psJNIEnv)->ExceptionOccurred(psJNIEnv);
if (jtExcptn != NULL)
{
(*psJNIEnv)->ExceptionDescribe(psJNIEnv);
return -1;
}
for (pcCurrArg = strtok(rgcMnClsCpy, g_pcSep); pcCurrArg; pcCurrArg = strtok(NULL, g_pcSep))
{
iOption++;
jsAppArg = (*psJNIEnv)->NewStringUTF(psJNIEnv, pcCurrArg);
(*psJNIEnv)->SetObjectArrayElement(psJNIEnv, joAppArgs, iOption, jsAppArg);
jtExcptn = (*psJNIEnv)->ExceptionOccurred(psJNIEnv);
if(jtExcptn != NULL)
{
(*psJNIEnv)->ExceptionDescribe(psJNIEnv);
return -1;
}
}
/* Execute the class */
(*psJNIEnv)->CallStaticVoidMethod(psJNIEnv, jcMnCls, jmMnMthd, joAppArgs);
return 0;
}
void cleanupVm()
{
/* Destroy the VM */
(*g_pJavaVM)->DestroyJavaVM(g_pJavaVM);
}
BOOL executeVm(DWORD *dwExitCode)
{
BOOL result = TRUE;
*dwExitCode = -1;
int iIdx;
/* Use Invocation API */
if (createVm())
{
*dwExitCode = invokeMainClass(g_pJNIEnv);
cleanupVm();
}
else
{
result = FALSE;
}
/* Free the allocated memory */
for (iIdx = 0; iIdx < g_sJavaVMInitArgs.nOptions; iIdx++)
{
free(g_sJavaVMInitArgs.options[iIdx].optionString);
}
free(g_sJavaVMInitArgs.options);
return result;
}

View File

@@ -0,0 +1,41 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2007 Ryan Rusaw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <jni.h>
#include <ctype.h>
#include "head.h"
int getArgCount(const char* pcArgStr);
void saveJvmOptions(const char *jrePath, const char *mainClass, const char *pcOpts);
JNIEnv* createVm();
int invokeMainClass(JNIEnv* psJNIEnv);
void cleanupVm();
BOOL executeVm(DWORD *dwExitCode);

Binary file not shown.

Binary file not shown.

24
launch4j/maven/.classpath Normal file
View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry including="**/*.java" kind="src" output="target/classes" path="src">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="demo/SimpleApp/build" path="demo/SimpleApp/src"/>
<classpathentry kind="src" output="demo/ConsoleApp/build" path="demo/ConsoleApp/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

23
launch4j/maven/.project Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>launch4j</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -0,0 +1,14 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>distribution-libs</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes></includes>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Maven Launch4j Plugin
Copyright (c) 2006 Paul Jungwirth
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<assembly>
<id>workdir-linux</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>bin/bin-linux</directory>
<outputDirectory>${finalName}-workdir-linux/bin</outputDirectory>
</fileSet>
<fileSet>
<outputDirectory>${finalName}-workdir-linux</outputDirectory>
<includes>
<include>w32api/**/*</include>
<include>w32api_jni/**/*</include>
<include>head/**/*</include>
<include>head_jni_BETA/**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Maven Launch4j Plugin
Copyright (c) 2006 Paul Jungwirth
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<assembly>
<id>workdir-linux64</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>bin/bin-linux64</directory>
<outputDirectory>${finalName}-workdir-linux64/bin</outputDirectory>
</fileSet>
<fileSet>
<outputDirectory>${finalName}-workdir-linux64</outputDirectory>
<includes>
<include>w32api/**/*</include>
<include>w32api_jni/**/*</include>
<include>head/**/*</include>
<include>head_jni_BETA/**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Maven Launch4j Plugin
Copyright (c) 2006 Paul Jungwirth
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<assembly>
<id>workdir-mac</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>bin/bin-macosx-x86</directory>
<outputDirectory>${finalName}-workdir-mac/bin</outputDirectory>
</fileSet>
<fileSet>
<outputDirectory>${finalName}-workdir-mac</outputDirectory>
<includes>
<include>w32api/**/*</include>
<include>w32api_jni/**/*</include>
<include>head/**/*</include>
<include>head_jni_BETA/**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Maven Launch4j Plugin
Copyright (c) 2006 Paul Jungwirth
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<assembly>
<id>workdir-win32</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>bin/bin-win32</directory>
<outputDirectory>${finalName}-workdir-win32/bin</outputDirectory>
</fileSet>
<fileSet>
<outputDirectory>${finalName}-workdir-win32</outputDirectory>
<includes>
<include>w32api/**/*</include>
<include>w32api_jni/**/*</include>
<include>head/**/*</include>
<include>head_jni_BETA/**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Maven Launch4j Plugin
Copyright (c) 2006 Paul Jungwirth
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<assembly>
<id>src</id>
<formats>
<format>tar.gz</format>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
<include>TODO</include>
<include>pom.xml</include>
</includes>
</fileSet>
<fileSet>
<directory>src</directory>
<excludes>
<exclude>**/.*.swp</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>

View File

@@ -0,0 +1,8 @@
Run once the Ant target switch-to-maven, it will reconfigure the project to use maven.
*** Creation of Distribution Release ***
Windows: mvn -P dist,win32 clean package
Linux: mvn -P dist,linux clean package
MacOsX: mvn -P dist,macosx-x86 clean package

512
launch4j/maven/pom.xml Normal file
View File

@@ -0,0 +1,512 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sf.launch4j</groupId>
<artifactId>launch4j</artifactId>
<version>${launch4j.version}</version>
<name>Launch4j</name>
<description>Cross-platform Java executable wrapper for creating lightweight Windows native EXEs. Provides advanced JRE search, application startup configuration and better user experience.</description>
<url>http://sourceforge.net/projects/launch4j/</url>
<licenses>
<license>
<name>BSD 3-Clause License</name>
<url>http://opensource.org/licenses/BSD-3-Clause</url>
<comments>Launch4j is licensed under the BSD 3-Clause License.</comments>
</license>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
<comments>Launch4j code (head) which is attached to the wrapped jars is licensed under the MIT License.</comments>
</license>
</licenses>
<developers>
<developer>
<name>Grzegorz Kowal</name>
<url>http://sourceforge.net/u/grzegok/profile/</url>
</developer>
</developers>
<scm>
<connection>scm:git:http://git.code.sf.net/p/launch4j/git</connection>
<developerConnection>scm:git:http://git.code.sf.net/p/launch4j/git</developerConnection>
<url>http://sourceforge.net/p/launch4j/git/ci/master/tree/</url>
</scm>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<versionNumber>${launch4j.version}.0.0</versionNumber>
<version>${launch4j.version}</version>
</properties>
<dependencies>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-collections</artifactId>
<groupId>commons-collections</groupId>
</exclusion>
</exclusions>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>net.java.abeille</groupId>
<artifactId>abeille</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<artifactId>colt</artifactId>
<groupId>colt</groupId>
</exclusion>
<exclusion>
<artifactId>
com.springsource.org.apache.batik.ext.awt
</artifactId>
<groupId>org.apache.batik</groupId>
</exclusion>
<exclusion>
<artifactId>
com.springsource.org.apache.batik.util
</artifactId>
<groupId>org.apache.batik</groupId>
</exclusion>
<exclusion>
<artifactId>dom4j</artifactId>
<groupId>dom4j</groupId>
</exclusion>
<exclusion>
<artifactId>dsol-xml</artifactId>
<groupId>dsol</groupId>
</exclusion>
<exclusion>
<artifactId>javahelp</artifactId>
<groupId>javax.help</groupId>
</exclusion>
<exclusion>
<artifactId>jfreechart</artifactId>
<groupId>jfree</groupId>
</exclusion>
<exclusion>
<artifactId>jcommon</artifactId>
<groupId>jfree</groupId>
</exclusion>
<exclusion>
<artifactId>mahout-collections</artifactId>
<groupId>org.apache.mahout</groupId>
</exclusion>
<exclusion>
<artifactId>optimization</artifactId>
<groupId>com.github.rwl</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>foxtrot</groupId>
<artifactId>foxtrot</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.jgoodies</groupId>
<artifactId>jgoodies-common</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>com.jgoodies</groupId>
<artifactId>forms</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.jgoodies</groupId>
<artifactId>looks</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.8</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.2</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>com.github.taxone.plugins</groupId>
<artifactId>classpath-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>set-classpath-property</id>
<phase>prepare-package</phase>
<goals>
<goal>setClassPath</goal>
</goals>
<configuration>
<classpathPrefix>lib/</classpathPrefix>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>net.sf.launch4j.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>. ${taxone.classpath.propertyName}</Class-Path>
</manifestEntries>
</archive>
</configuration>
</execution>
<execution>
<id>core-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<finalName>${project.build.finalName}</finalName>
<excludes>
<exclude>net/sf/launch4j/form/</exclude>
<exclude>net/sf/launch4j/formimpl</exclude>
</excludes>
<classifier>core</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>assemble-workdir</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly/assemble-linux.xml</descriptor>
<descriptor>assembly/assemble-linux64.xml</descriptor>
<descriptor>assembly/assemble-win32.xml</descriptor>
<descriptor>assembly/assemble-mac.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>assemble-distrib</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>lib</finalName>
<outputDirectory>${basedir}</outputDirectory>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly/assemble-dist.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}</outputDirectory>
<resources>
<resource>
<directory>target</directory>
<includes>
<include>${project.build.finalName}.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6</version>
<configuration>
<filesets>
<fileset>
<directory>${basedir}</directory>
<includes>
<include>${project.build.finalName}.jar</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>full-release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.2</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<!-- Release has to be executed manually -->
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<!-- Macosx-x86 Profile -->
<profile>
<id>macosx-x86</id>
<properties>
<bin.dir>bin-macosx-x86</bin.dir>
</properties>
</profile>
<!-- Linux Profile -->
<profile>
<id>linux</id>
<properties>
<bin.dir>bin-linux</bin.dir>
</properties>
</profile>
<!-- Windows Profile -->
<profile>
<id>win32</id>
<properties>
<bin.dir>bin-win32</bin.dir>
</properties>
<build>
<plugins>
<!-- Creates Launch4j executable -->
<plugin>
<groupId>com.akathist.maven.plugins.launch4j</groupId>
<artifactId>launch4j-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>launch4j</id>
<phase>package</phase>
<goals>
<goal>launch4j</goal>
</goals>
<configuration>
<headerType>gui</headerType>
<dontWrapJar>true</dontWrapJar>
<jar>${project.build.finalName}.jar</jar>
<outfile>launch4j.exe</outfile>
<errTitle>launch4j</errTitle>
<chdir>.</chdir>
<stayAlive>false</stayAlive>
<jre>
<minVersion>1.6.0</minVersion>
</jre>
<versionInfo>
<fileVersion>${versionNumber}</fileVersion>
<txtFileVersion>${version}</txtFileVersion>
<productVersion>${versionNumber}</productVersion>
<txtProductVersion>${version}</txtProductVersion>
<fileDescription>Cross-platform Java application wrapper</fileDescription>
<copyright>Copyright (C) 2004, 2017 Grzegorz Kowal</copyright>
<productName>launch4j</productName>
<companyName>http://launch4j.sourceforge.net/</companyName>
<internalName>GUI launcher</internalName>
<originalFilename>launch4j.exe</originalFilename>
</versionInfo>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- Generic distribution profile -->
<profile>
<id>dist</id>
<build>
<plugins>
<!-- Clean -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6</version>
<configuration>
<filesets>
<fileset>
<directory>${basedir}/bin</directory>
<includes>
<incude>*</incude>
</includes>
<excludes>
<exclude>COPYING</exclude>
</excludes>
</fileset>
<fileset>
<directory>${basedir}</directory>
<includes>
<incude>launch4j.exe</incude>
</includes>
</fileset>
<fileset>
<directory>${basedir}</directory>
<includes>
<incude>lib/</incude>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>
<!-- Copies executables to "bin" directory -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-binutils</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/bin</outputDirectory>
<resources>
<resource>
<directory>${basedir}/bin/${bin.dir}</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Change Permissions -->
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<chmod file="launch4j" perm="+x" />
<chmod file="bin/windres" perm="+x" />
<chmod file="bin/ld" perm="+x" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -33,8 +33,13 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#else
#include <sys/io.h>
#include <sys/fcntl.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -45,6 +50,14 @@
#define TEST_FILE_NAME "sign4j_temporary.exe"
#define SIGN4J_VERSION "3.0"
#ifndef _WIN32
#define O_BINARY 0
#define _O_SHORT_LIVED 0
#define _S_IREAD S_IREAD
#define _S_IWRITE S_IWRITE
#define stricmp strcasecmp
#endif
typedef unsigned char byte;
char command[4096];
@@ -127,7 +140,12 @@ int main (int argc, char* argv[])
trg = outf;
close (fd);
#ifdef _WIN32
strcpy (command, "\" ");
#else
strcpy (command, "");
#endif
for (i = j; i < argc; i++)
{
p = (argv[i] == outf ? trg : argv[i]);
@@ -139,9 +157,18 @@ int main (int argc, char* argv[])
strcat (command, "\"");
strcat (command, " ");
}
#ifdef _WIN32
strcat (command, "\"");
#endif
if (! vrb)
#ifdef _WIN32
strcat (command, " > NUL");
#else
strcat (command, " > /dev/null");
#endif
system (command);
if ((td = open (trg, O_RDONLY | O_BINARY)) < 0)
@@ -168,7 +195,12 @@ int main (int argc, char* argv[])
printf ("You don't need sign4j to sign this file\n");
}
#ifdef _WIN32
strcpy (command, "\" ");
#else
strcpy (command, "");
#endif
for (i = j; i < argc; i++)
{
p = argv[i];
@@ -180,7 +212,11 @@ int main (int argc, char* argv[])
strcat (command, "\"");
strcat (command, " ");
}
#ifdef _WIN32
strcat (command, "\"");
#endif
return system (command);
}

30
launch4j/src/LICENSE.txt Normal file
View File

@@ -0,0 +1,30 @@
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2004, 2017 Grzegorz Kowal
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,2 +1,2 @@
versionNumber=3.7.0.0
version=3.7
versionNumber=3.12.0.0
version=3.12

View File

@@ -82,6 +82,10 @@ public class Builder {
FileOutputStream os = null;
final RcBuilder rcb = new RcBuilder();
try {
if (c.isJniApplication()) {
_log.append("WARNING: Some features are not implemented in JNI headers, see documentation.");
}
rc = rcb.build(c);
ro = Util.createTempFile("o");
outfile = ConfigPersister.getInstance().getOutputFile();
@@ -102,8 +106,7 @@ public class Builder {
.add("--dynamicbase")
.add("--nxcompat")
.add("--no-seh")
.add((c.getHeaderType().equals(Config.GUI_HEADER))
? "--subsystem windows" : "--subsystem console")
.add(c.isGuiApplication() ? "--subsystem windows" : "--subsystem console")
.add("-s") // strip symbols
.addFiles(c.getHeaderObjects())
.addAbsFile(ro)

View File

@@ -68,6 +68,7 @@ public class Main {
}
} catch (Exception e) {
Log.getConsoleLog().append(e.getMessage());
System.exit(1);
}
}
@@ -85,7 +86,7 @@ public class Main {
" (http://launch4j.sourceforge.net/)\n" +
"Cross-platform Java application wrapper" +
" for creating Windows native executables.\n\n" +
"Copyright (C) 2004, 2015 Grzegorz Kowal\n\n" +
"Copyright (C) 2004, 2018 Grzegorz Kowal\n\n" +
"Launch4j comes with ABSOLUTELY NO WARRANTY.\n" +
"This is free software, licensed under the BSD License.\n" +
"This product includes software developed by the Apache Software Foundation" +

View File

@@ -44,6 +44,7 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.List;
import net.sf.launch4j.config.CharsetID;
import net.sf.launch4j.config.Config;
import net.sf.launch4j.config.ConfigPersister;
import net.sf.launch4j.config.Jre;
@@ -111,7 +112,7 @@ public class RcBuilder {
public static final int INSTANCE_ALREADY_EXISTS_MSG = 105;
private final StringBuffer _sb = new StringBuffer();
public String getContent() {
return _sb.toString();
}
@@ -176,13 +177,19 @@ public class RcBuilder {
}
private void writeResourceFile(File file) throws IOException {
FileOutputStream os = null;
OutputStreamWriter osw = null;
BufferedWriter w = null;
try {
w = new BufferedWriter(new FileWriter(file));
os = new FileOutputStream(file);
osw = new OutputStreamWriter(os, "ISO-8859-1");
w = new BufferedWriter(osw);
w.write(_sb.toString());
} finally {
Util.close(w);
Util.close(osw);
Util.close(os);
}
}
@@ -225,7 +232,9 @@ public class RcBuilder {
"{\n" +
" BLOCK \"StringFileInfo\"\n" +
" {\n" +
" BLOCK \"040904E4\"\n" + // English
" BLOCK \"");
_sb.append(String.format("%04X%04X", v.getLanguage().getId(), CharsetID.MULTILINGUAL.getId()));
_sb.append("\"\n" +
" {\n");
addVerBlockValue("CompanyName", v.getCompanyName());
@@ -233,10 +242,13 @@ public class RcBuilder {
addVerBlockValue("FileVersion", v.getTxtFileVersion());
addVerBlockValue("InternalName", v.getInternalName());
addVerBlockValue("LegalCopyright", v.getCopyright());
addVerBlockValue("LegalTrademarks", v.getTrademarks());
addVerBlockValue("OriginalFilename", v.getOriginalFilename());
addVerBlockValue("ProductName", v.getProductName());
addVerBlockValue("ProductVersion", v.getTxtProductVersion());
_sb.append(" }\n }\nBLOCK \"VarFileInfo\"\n{\nVALUE \"Translation\", 0x0409, 0x04E4\n}\n}");
_sb.append(" }\n }\nBLOCK \"VarFileInfo\"\n{\nVALUE \"Translation\", ");
_sb.append(String.format("0x%04X, 0x%04X", v.getLanguage().getId(), CharsetID.MULTILINGUAL.getId()));
_sb.append("\n}\n}");
}
private void addJre(Jre jre) {

View File

@@ -0,0 +1,110 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2015 Sebastian Bögl
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.sf.launch4j.config;
import java.util.Arrays;
/**
* @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058%28v=vs.85%29.aspx">VERSIONINFO resource</a>
* @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa381057%28v=vs.85%29.aspx">VarFileInfo BLOCK</a>
*/
public enum CharsetID implements Describable {
/** 0x0000 */
ASCII(0, Messages.getString("Charset.ascii")),
/** 0x04E8 */
ARABIC(1256, Messages.getString("Language.arabic")),
/** 0x04E3 */
CYRILLIC(1251, Messages.getString("Charset.cyrillic")),
/** 0x04E5 */
GREEK(1253, Messages.getString("Language.greek")),
/** 0x04E7 */
HEBREW(1255, Messages.getString("Language.hebrew")),
/** 0x03A4 */
SHIFT_JIS(932, Messages.getString("Charset.shift.jis")),
/** 0x03B5 */
SHIFT_KSC(949, Messages.getString("Charset.shift.ksc")),
/** 0x04E2 */
LATIN2(1250, Messages.getString("Charset.latin2")),
/** 0x04E4 */
MULTILINGUAL(1252, Messages.getString("Charset.multilingual")),
/** 0x0B63 */
BIG5(950, Messages.getString("Charset.big5")),
/** 0x04E6 */
TURKISH(1254, Messages.getString("Language.turkish")),
/** 0x04B0 */
UNICODE(1200, Messages.getString("Charset.unicode")),
;
private static final CharsetID[] VALUES = CharsetID.values();
static {
Arrays.sort(VALUES, new DescribableComparator());
}
private final int id;
private final String description;
CharsetID(int id, String description) {
this.id = id;
this.description = description;
}
public int getId() {
return id;
}
@Override
public String toString() {
return description;
}
@Override
public String getDescription() {
return description;
}
@Override
public int getIndex() {
for (int i = 0; i < VALUES.length; i++) {
if (VALUES[i] == this) {
return i;
}
}
// should never happen
return -1;
}
public static CharsetID[] sortedValues() {
return VALUES;
}
}

View File

@@ -53,7 +53,7 @@ public class ClassPath implements IValidatable {
Messages.getString("ClassPath.mainClass"));
Validator.checkOptStrings(paths,
Validator.MAX_PATH,
Validator.MAX_BIG_STR,
Validator.MAX_ARGS,
"paths",
Messages.getString("ClassPath.path"));
}

View File

@@ -63,9 +63,13 @@ public class Config implements IValidatable {
public static final String GUI_HEADER = "gui";
public static final String CONSOLE_HEADER = "console";
public static final String JNI_GUI_HEADER_32 = "jniGui32";
public static final String JNI_CONSOLE_HEADER_32 = "jniConsole32";
private static final String[] HEADER_TYPES = new String[] { GUI_HEADER,
CONSOLE_HEADER };
CONSOLE_HEADER,
JNI_GUI_HEADER_32,
JNI_CONSOLE_HEADER_32 };
private static final String[] PRIORITY_CLASS_NAMES = new String[] { "normal",
"idle",
@@ -119,7 +123,7 @@ public class Config implements IValidatable {
if (!Validator.isEmpty(chdir)) {
Validator.checkRelativeWinPath(chdir, "chdir",
Messages.getString("Config.chdir.relative"));
Validator.checkFalse(chdir.toLowerCase().equals("true")
Validator.checkFalse(chdir.toLowerCase().equals("true")
|| chdir.toLowerCase().equals("false"),
"chdir", Messages.getString("Config.chdir.path"));
}
@@ -135,7 +139,7 @@ public class Config implements IValidatable {
"supportUrl", Messages.getString("Config.support.url"));
Validator.checkIn(getHeaderType(), HEADER_TYPES, "headerType",
Messages.getString("Config.header.type"));
Validator.checkFalse(getHeaderType().equals(CONSOLE_HEADER) && splash != null,
Validator.checkFalse(!isGuiApplication() && splash != null,
"headerType",
Messages.getString("Config.splash.not.impl.by.console.hdr"));
Validator.checkOptStrings(variables,
@@ -147,9 +151,31 @@ public class Config implements IValidatable {
Messages.getString("Config.variables.err"));
Validator.checkIn(getPriority(), PRIORITY_CLASS_NAMES, "priority",
Messages.getString("Config.priority"));
checkJniInvariants();
jre.checkInvariants();
}
private void checkJniInvariants() {
// TODO: Remove once JNI is fully implemented.
if (isJniApplication()) {
Validator.checkTrue(".".equals(chdir), "chdir",
"Only '.' is allowed in change directory.");
Validator.checkTrue(Validator.isEmpty(cmdLine), "cmdLine",
"Constant command line arguments not supported.");
Validator.checkFalse(stayAlive, "stayAlive",
"Stay alive option is not used in JNI, this is the default behavior.");
Validator.checkFalse(restartOnCrash, "restartOnCrash",
"Restart on crash not supported.");
Validator.checkIn(getPriority(), new String[] { "normal" }, "priority",
"Process priority is not supported,");
Validator.checkNotNull(classPath, "classpath", "classpath");
Validator.checkFalse(jre.getBundledJre64Bit(), "jre.bundledJre64Bit",
"64-bit bundled JRE not supported.");
Validator.checkTrue(Jre.RUNTIME_BITS_32.equals(jre.getRuntimeBits()), "jre.runtimeBits",
"64-bit JRE not supported.");
}
}
public void validate() {
checkInvariants();
if (classPath != null) {
@@ -189,10 +215,19 @@ public class Config implements IValidatable {
public void setErrTitle(String errTitle) {
this.errTitle = errTitle;
}
public boolean isGuiApplication() {
return GUI_HEADER.equals(headerType) || JNI_GUI_HEADER_32.equals(headerType);
}
public boolean isJniApplication() {
return JNI_GUI_HEADER_32.equals(headerType)
|| JNI_CONSOLE_HEADER_32.equals(headerType);
}
/** launch4j header file. */
public String getHeaderType() {
return headerType.toLowerCase();
return headerType;
}
public void setHeaderType(String headerType) {
@@ -215,9 +250,7 @@ public class Config implements IValidatable {
public List<String> getHeaderObjects() {
return isCustomHeaderObjects() ? headerObjects
: getHeaderType().equals(GUI_HEADER)
? LdDefaults.GUI_HEADER_OBJECTS
: LdDefaults.CONSOLE_HEADER_OBJECTS;
: LdDefaults.getHeaderObjects(getHeaderTypeIndex());
}
public void setHeaderObjects(List<String> headerObjects) {
@@ -229,7 +262,7 @@ public class Config implements IValidatable {
}
public List<String> getLibs() {
return isCustomLibs() ? libs : LdDefaults.LIBS;
return isCustomLibs() ? libs : LdDefaults.getLibs(headerType);
}
public void setLibs(List<String> libs) {

View File

@@ -0,0 +1,18 @@
package net.sf.launch4j.config;
import java.util.Comparator;
public interface Describable {
String getDescription();
int getIndex();
class DescribableComparator implements Comparator<Describable> {
@Override
public int compare(Describable o1, Describable o2) {
return o1.getDescription().compareTo(o2.getDescription());
}
}
}

View File

@@ -54,8 +54,8 @@ public class Jre implements IValidatable {
public static final String ARGS = "jvmArgs";
// __________________________________________________________________________________
public static final String VERSION_PATTERN = "(\\d\\.){2}\\d(_\\d+)?";
public static final String VERSION_PATTERN = "(1\\.\\d\\.\\d(_\\d{1,3})?)|[1-9][0-9]{0,2}(\\.\\d{1,3}){0,2}";
public static final String JDK_PREFERENCE_JRE_ONLY = "jreOnly";
public static final String JDK_PREFERENCE_PREFER_JRE = "preferJre";
public static final String JDK_PREFERENCE_PREFER_JDK = "preferJdk";
@@ -98,9 +98,9 @@ public class Jre implements IValidatable {
private List<String> options;
public void checkInvariants() {
Validator.checkOptString(minVersion, 10, VERSION_PATTERN,
Validator.checkOptString(minVersion, 20, VERSION_PATTERN,
"jre.minVersion", Messages.getString("Jre.min.version"));
Validator.checkOptString(maxVersion, 10, VERSION_PATTERN,
Validator.checkOptString(maxVersion, 20, VERSION_PATTERN,
"jre.maxVersion", Messages.getString("Jre.max.version"));
if (Validator.isEmpty(path)) {
Validator.checkFalse(bundledJre64Bit, "jre.bundledJre64Bit",
@@ -116,7 +116,7 @@ public class Jre implements IValidatable {
if (!Validator.isEmpty(maxVersion)) {
Validator.checkFalse(Validator.isEmpty(minVersion),
"jre.minVersion", Messages.getString("Jre.specify.min.version"));
Validator.checkTrue(minVersion.compareTo(maxVersion) < 0,
Validator.checkTrue(JreVersion.parseString(minVersion).compareTo(JreVersion.parseString(maxVersion)) < 0,
"jre.maxVersion", Messages.getString("Jre.max.greater.than.min"));
}
Validator.checkTrue(initialHeapSize == null || maxHeapSize != null,
@@ -155,7 +155,7 @@ public class Jre implements IValidatable {
Validator.checkOptStrings(options,
Validator.MAX_ARGS,
Validator.MAX_ARGS,
"[^%]*|([^%]*([^%]*%[^%]+%[^%]*)+[^%]*)*",
"[^%]*|([^%]*([^%]*%[^%]*%[^%]*)+[^%]*)*",
"jre.options",
Messages.getString("Jre.jvm.options"),
Messages.getString("Jre.jvm.options.variable"));

View File

@@ -0,0 +1,124 @@
package net.sf.launch4j.config;
/**
* This class will abstract application from JRE versioning schema and provide
* comparing capabilities
*
* @author sergeyk
*
*/
public class JreVersion implements Comparable<JreVersion> {
private int x1;
private int x2;
private int x3;
private int x4;
public static JreVersion parseString(String versionStr) {
JreVersion ret = new JreVersion();
if (versionStr == null || versionStr.trim().length() == 0) {
return ret;
}
if (!versionStr.matches(Jre.VERSION_PATTERN)) {
// NOTE: This is actually shouldn't happen because version format had to be
// checked by Jre#checkInvariants BEFORE calling this method
throw new IllegalArgumentException("JRE version is not in a right format.");
}
String[] parts = versionStr.split("[\\._]");
int first = Integer.parseInt(parts[0]);
if (first > 1) {
// java 9+ version schema
ret.x1 = 1;
ret.x2 = first;
if (parts.length >= 2) {
ret.x3 = Integer.parseInt(parts[1]);
if (parts.length >= 3) {
ret.x4 = Integer.parseInt(parts[2]);
}
}
} else {
// java <= 1.8 version schema
ret.x1 = first;
if (parts.length >= 2) {
ret.x2 = Integer.parseInt(parts[1]);
if (parts.length >= 3) {
ret.x3 = Integer.parseInt(parts[2]);
if (parts.length == 4) {
ret.x4 = Integer.parseInt(parts[3]);
}
}
}
}
return ret;
}
@Override
public String toString() {
if (x2 >= 9) {
return x2 + "." + x3 + "." + x4;
}
return x1 + "." + x2 + "." + x3 + (x4 > 0 ? "_" + x4 : "");
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x1;
result = prime * result + x2;
result = prime * result + x3;
result = prime * result + x4;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
JreVersion other = (JreVersion) obj;
if (x1 != other.x1) {
return false;
}
if (x2 != other.x2) {
return false;
}
if (x3 != other.x3) {
return false;
}
if (x4 != other.x4) {
return false;
}
return true;
}
@Override
public int compareTo(JreVersion o) {
if (this.equals(o)) {
return 0;
}
if (x1 != o.x1) {
return x1 - o.x1;
}
if (x2 != o.x2) {
return x2 - o.x2;
}
if (x3 != o.x3) {
return x3 - o.x3;
}
if (x4 != o.x4) {
return x4 - o.x4;
}
throw new IllegalStateException("If you see this exception it means JreVersion::equals() method is buggy");
}
}

View File

@@ -0,0 +1,132 @@
/*
Launch4j (http://launch4j.sourceforge.net/)
Cross-platform Java application wrapper for creating Windows native executables.
Copyright (c) 2015 Sebastian Bögl
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.sf.launch4j.config;
import java.util.Arrays;
/**
* @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058%28v=vs.85%29.aspx">VERSIONINFO resource</a>
* @see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa381057%28v=vs.85%29.aspx">VarFileInfo BLOCK</a>
*/
public enum LanguageID implements Describable {
ALBANIAN(0x041C, Messages.getString("Language.albanian")),
ARABIC(0x0401, Messages.getString("Language.arabic")),
BAHASA(0x0421, Messages.getString("Language.bahasa")),
DUTCH_BELGIAN(0x0813, Messages.getString("Language.belgian.dutch")),
FRENCH_BELGIAN(0x080C, Messages.getString("Language.belgian.french")),
BULGARIAN(0x0402, Messages.getString("Language.bulgarian")),
FRENCH_CANADIAN(0x0C0C, Messages.getString("Language.canadian.french")),
CASTILIAN_SPANISH(0x040A, Messages.getString("Language.spanish.castilian")),
CATALAN(0x0403, Messages.getString("Language.catalan")),
CROATO_SERBIAN_LATIN(0x041A, Messages.getString("Language.croato.serbian.latin")),
CZECH(0x0405, Messages.getString("Language.czech")),
DANISH(0x0406, Messages.getString("Language.danish")),
DUTCH(0x0413, Messages.getString("Language.dutch")),
ENGLISH_UK(0x0809, Messages.getString("Language.english.uk")),
ENGLISH_US(0x0409, Messages.getString("Language.english.us")),
FINNISH(0x040B, Messages.getString("Language.finnish")),
FRENCH(0x040C, Messages.getString("Language.french")),
GERMAN(0x0407, Messages.getString("Language.german")),
GREEK(0x0408, Messages.getString("Language.greek")),
HEBREW(0x040D, Messages.getString("Language.hebrew")),
HUNGARIAN(0x040E, Messages.getString("Language.hungarian")),
ICELANDIC(0x040F, Messages.getString("Language.icelandic")),
ITALIAN(0x0410, Messages.getString("Language.italian")),
JAPANESE(0x0411, Messages.getString("Language.japanese")),
KOREAN(0x0412, Messages.getString("Language.korean")),
NORWEGIAN_BOKMAL(0x0414, Messages.getString("Language.norwegian.bokmal")),
NORWEGIAN_NYNORSK(0x0814, Messages.getString("Language.norwegian.nynorsk")),
POLISH(0x0415, Messages.getString("Language.polish")),
PORTUGUESE_BRAZIL(0x0416, Messages.getString("Language.portuguese.brazil")),
PORTUGUESE_PORTUGAL(0x0816, Messages.getString("Language.portuguese.portugal")),
RHAETO_ROMANIC(0x0417, Messages.getString("Language.rhaeto.romanic")),
ROMANIAN(0x0418, Messages.getString("Language.romanian")),
RUSSIAN(0x0419, Messages.getString("Language.russian")),
SERBO_CROATIAN_CYRILLIC(0x081A, Messages.getString("Language.serbo.croatian.cyrillic")),
SIMPLIFIED_CHINESE(0x0804, Messages.getString("Language.chinese.simplified")),
SLOVAK(0x041B, Messages.getString("Language.slovak")),
SPANISH_MEXICO(0x080A, Messages.getString("Language.spanish.mexico")),
SWEDISH(0x041D, Messages.getString("Language.swedish")),
FRENCH_SWISS(0x100C, Messages.getString("Language.swiss.french")),
GERMAN_SWISS(0x0807, Messages.getString("Language.swiss.german")),
ITALIAN_SWISS(0x0810, Messages.getString("Language.swiss.italian")),
THAI(0x041E, Messages.getString("Language.thai")),
TRADITIONAL_CHINESE(0x0404, Messages.getString("Language.chinese.traditional")),
TURKISH(0x041F, Messages.getString("Language.turkish")),
URDU(0x0420, Messages.getString("Language.urdu")),
;
private static final LanguageID[] VALUES = LanguageID.values();
static {
Arrays.sort(VALUES, new DescribableComparator());
}
private final int id;
private final String description;
LanguageID(int id, String description) {
this.id = id;
this.description = description;
}
public int getId() {
return id;
}
@Override
public String getDescription() {
return description;
}
@Override
public String toString() {
return description;
}
@Override
public int getIndex() {
for (int i = 0; i < VALUES.length; i++) {
if (VALUES[i] == this) {
return i;
}
}
// should never happen
return -1;
}
public static LanguageID[] sortedValues() {
return VALUES;
}
}

View File

@@ -36,22 +36,36 @@
*/
package net.sf.launch4j.config;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class LdDefaults {
public static final List<String> GUI_HEADER_OBJECTS = Arrays.asList(new String[] {
private static final List<String> GUI_OBJECTS = Arrays.asList(new String[] {
"w32api/crt2.o",
"head/guihead.o",
"head/head.o" });
public static final List<String> CONSOLE_HEADER_OBJECTS = Arrays.asList(new String[] {
private static final List<String> CONSOLE_OBJECTS = Arrays.asList(new String[] {
"w32api/crt2.o",
"head/consolehead.o",
"head/head.o"});
"head/head.o" });
private static final List<String> JNI_GUI_32_OBJECTS = Arrays.asList(new String[] {
"w32api_jni/crt2.o",
"head_jni_BETA/jniguihead.o",
"head_jni_BETA/head.o",
"head_jni_BETA/jnihead.o" });
public static final List<String> LIBS = Arrays.asList(new String[] {
private static final List<String> JNI_CONSOLE_32_OBJECTS = Arrays.asList(new String[] {
"w32api_jni/crt2.o",
"head_jni_BETA/jniconsolehead.o",
"head_jni_BETA/head.o",
"head_jni_BETA/jnihead.o" });
private static final List<List<String>> HEADER_OBJECTS;
private static final List<String> LIBS = Arrays.asList(new String[] {
"w32api/libmingw32.a",
"w32api/libgcc.a",
"w32api/libmsvcrt.a",
@@ -59,4 +73,45 @@ public class LdDefaults {
"w32api/libuser32.a",
"w32api/libadvapi32.a",
"w32api/libshell32.a" });
private static final List<String> JNI_LIBS = Arrays.asList(new String[] {
"w32api_jni/libmingw32.a",
"w32api_jni/libmingwex.a",
"w32api_jni/libgcc.a",
"w32api_jni/libmsvcrt.a",
"w32api_jni/libmoldname.a",
"w32api_jni/libkernel32.a",
"w32api_jni/libuser32.a",
"w32api_jni/libadvapi32.a",
"w32api_jni/libshell32.a" });
static {
HEADER_OBJECTS = new ArrayList<List<String>>();
HEADER_OBJECTS.add(GUI_OBJECTS);
HEADER_OBJECTS.add(CONSOLE_OBJECTS);
HEADER_OBJECTS.add(JNI_GUI_32_OBJECTS);
HEADER_OBJECTS.add(JNI_CONSOLE_32_OBJECTS);
}
public static List<String> getHeaderObjects(int headerTypeIndex) {
if (headerTypeIndex < 0 || headerTypeIndex > 3) {
throw new IllegalArgumentException("headerTypeIndex is out of range: " + headerTypeIndex);
}
return HEADER_OBJECTS.get(headerTypeIndex);
}
public static List<String> getLibs(String headerType) {
if (Config.GUI_HEADER.equals(headerType)
|| Config.CONSOLE_HEADER.equals(headerType)) {
return LIBS;
}
if (Config.JNI_GUI_HEADER_32.equals(headerType)
|| Config.JNI_CONSOLE_HEADER_32.equals(headerType)) {
return JNI_LIBS;
}
throw new IllegalArgumentException("Unknown headerType: " + headerType);
}
}

View File

@@ -44,6 +44,7 @@ import net.sf.launch4j.binding.Validator;
*/
public class VersionInfo implements IValidatable {
public static final String VERSION_PATTERN = "(\\d+\\.){3}\\d+";
public static final int DEFAULT_LANGUAGE_INDEX = LanguageID.ENGLISH_US.getIndex();
private String fileVersion;
private String txtFileVersion;
@@ -55,6 +56,8 @@ public class VersionInfo implements IValidatable {
private String companyName;
private String internalName;
private String originalFilename;
private String trademarks;
private LanguageID language;
public void checkInvariants() {
Validator.checkString(fileVersion, 20, VERSION_PATTERN,
@@ -77,6 +80,8 @@ public class VersionInfo implements IValidatable {
Messages.getString("VersionInfo.company.name"));
Validator.checkString(internalName, 50, "versionInfo.internalName",
Messages.getString("VersionInfo.internal.name"));
Validator.checkOptString(trademarks, 150, "versionInfo.trademarks",
Messages.getString("VersionInfo.trademarks"));
Validator.checkTrue(!internalName.endsWith(".exe"), "versionInfo.internalName",
Messages.getString("VersionInfo.internal.name.not.exe"));
Validator.checkString(originalFilename, 50, "versionInfo.originalFilename",
@@ -165,4 +170,28 @@ public class VersionInfo implements IValidatable {
public void setTxtProductVersion(String txtProductVersion) {
this.txtProductVersion = txtProductVersion;
}
public String getTrademarks() {
return trademarks;
}
public void setTrademarks(String trademarks) {
this.trademarks = trademarks;
}
public LanguageID getLanguage() {
return (language == null) ? LanguageID.sortedValues()[DEFAULT_LANGUAGE_INDEX] : language;
}
public void setLanguage(LanguageID language) {
this.language = language;
}
public int getLanguageIndex() {
return (language == null) ? DEFAULT_LANGUAGE_INDEX : language.getIndex();
}
public void setLanguageIndex(int index) {
language = LanguageID.sortedValues()[index];
}
}

View File

@@ -63,13 +63,14 @@ VersionInfo.product.version=Product version, should be 'x.x.x.x'
VersionInfo.txt.product.version=Free from product version
VersionInfo.product.name=Product name
VersionInfo.company.name=Company name
VersionInfo.trademarks=Trademarks
VersionInfo.internal.name=Internal name
VersionInfo.internal.name.not.exe=Internal name shouldn't have the .exe extension.
VersionInfo.original.filename=Original filename
VersionInfo.original.filename.exe=Original filename should end with the .exe extension.
Jre.min.version=Minimum JRE version should be x.x.x[_xx]
Jre.max.version=Maximum JRE version should be x.x.x[_xx]
Jre.min.version=Minimum JRE version should be 1.x.x[_xxx] or the Java 9 new version scheme xxx[.xxx[.xxx]], e.g., 1.5, 1.8.0_121, 10.0.1
Jre.max.version=Maximum JRE version should be 1.x.x[_xxx] or the Java 9 new version scheme xxx[.xxx[.xxx]], e.g., 1.5, 1.8.0_121, 10.0.1
Jre.specify.jre.min.version.or.path=Specify minimum JRE version and/or bundled JRE path.
Jre.bundled.path=Bundled JRE path
Jre.bundled.64bit.invalid=The bundled JRE 64-bit option can only be used if the JRE path is specified.
@@ -94,3 +95,57 @@ Msg.launcherErr=Launcher error message
SingleInstance.mutexName=Mutex name
SingleInstance.windowTitle=Window title
Charset.ascii=7-bit ASCII
Charset.unicode=Unicode
Charset.multilingual=Multilingual
Charset.shift.jis=Japan (Shift JIS X-0208)
Charset.shift.ksc=Korea (Shift KSC 5601)
Charset.big5=Taiwan (Big5)
Charset.latin2=Latin-2 (Eastern European)
Charset.cyrillic=Cyrillic
Language.arabic=Arabic
Language.bulgarian=Bulgarian
Language.catalan=Catalan
Language.chinese.traditional=Chinese (Traditional)
Language.czech=Czech
Language.danish=Danish
Language.german=German
Language.english.us=English U.S.
Language.greek=Greek
Language.hebrew=Hebrew
Language.polish=Polish
Language.portuguese.brazil=Portuguese (Brazil)
Language.rhaeto.romanic=Rhaeto Romanic
Language.romanian=Romanian
Language.russian=Russian
Language.spanish.castilian=Spanish (Castilian)
Language.finnish=Finnish
Language.french=French
Language.hungarian=Hungarian
Language.icelandic=Icelandic
Language.italian=Italian
Language.japanese=Japanese
Language.korean=Korean
Language.dutch=Dutch
Language.norwegian.bokmal=Norwegian Bokm\u00E5l
Language.croato.serbian.latin=Croato-Serbian (Latin)
Language.slovak=Slovak
Language.albanian=Albanian
Language.swedish=Swedish
Language.thai=Thai
Language.turkish=Turkish
Language.urdu=Urdu
Language.bahasa=Bahasa
Language.chinese.simplified=Chinese (Simplified)
Language.swiss.german=Swiss German
Language.english.uk=English U.K.
Language.spanish.mexico=Spanish (Mexico)
Language.belgian.french=Belgian French
Language.canadian.french=Canadian French
Language.swiss.italian=Swiss Italian
Language.belgian.dutch=Belgian Dutch
Language.norwegian.nynorsk=Norwegian Nynorsk
Language.portuguese.portugal=Portuguese (Portugal)
Language.serbo.croatian.cyrillic=Serbo-Croatian (Cyrillic)
Language.swiss.french=Swiss French

View File

@@ -229,7 +229,6 @@ public abstract class BasicForm extends JPanel
_errorTitleField.setToolTipText(Messages.getString("errorTitleTip"));
jpanel1.add(_errorTitleField,cc.xywh(4,24,7,1));
_downloadUrlLabel.setIcon(loadImage("images/asterix.gif"));
_downloadUrlLabel.setName("downloadUrlLabel");
_downloadUrlLabel.setText(Messages.getString("downloadUrl"));
jpanel1.add(_downloadUrlLabel,cc.xy(2,26));

View File

@@ -4,6 +4,7 @@ import com.jeta.forms.components.separator.TitledSeparator;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.Box;
@@ -27,6 +28,8 @@ public abstract class HeaderForm extends JPanel
protected final JCheckBox _headerObjectsCheck = new JCheckBox();
protected final JCheckBox _libsCheck = new JCheckBox();
protected final TitledSeparator _linkerOptionsSeparator = new TitledSeparator();
protected final JRadioButton _jniGuiHeaderRadio = new JRadioButton();
protected final JRadioButton _jniConsoleHeaderRadio = new JRadioButton();
/**
* Default constructor
@@ -106,7 +109,7 @@ public abstract class HeaderForm extends JPanel
public JPanel createPanel()
{
JPanel jpanel1 = new JPanel();
FormLayout formlayout1 = new FormLayout("FILL:7DLU:NONE,RIGHT:MAX(65DLU;DEFAULT):NONE,FILL:3DLU:NONE,FILL:DEFAULT:NONE,FILL:7DLU:NONE,FILL:DEFAULT:NONE,FILL:DEFAULT:GROW(1.0),FILL:7DLU:NONE","CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,FILL:DEFAULT:GROW(0.2),CENTER:3DLU:NONE,FILL:DEFAULT:GROW(1.0),CENTER:9DLU:NONE");
FormLayout formlayout1 = new FormLayout("FILL:7DLU:NONE,RIGHT:MAX(65DLU;DEFAULT):NONE,FILL:3DLU:NONE,FILL:DEFAULT:NONE,FILL:7DLU:NONE,FILL:DEFAULT:NONE,FILL:7DLU:NONE,FILL:DEFAULT:NONE,FILL:7DLU:NONE,FILL:DEFAULT:NONE,FILL:DEFAULT:GROW(1.0),FILL:7DLU:NONE","CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,FILL:DEFAULT:GROW(0.2),CENTER:3DLU:NONE,FILL:DEFAULT:GROW(1.0),CENTER:9DLU:NONE");
CellConstraints cc = new CellConstraints();
jpanel1.setLayout(formlayout1);
@@ -117,12 +120,14 @@ public abstract class HeaderForm extends JPanel
_guiHeaderRadio.setActionCommand("GUI");
_guiHeaderRadio.setName("guiHeaderRadio");
_guiHeaderRadio.setText(Messages.getString("gui"));
_guiHeaderRadio.setToolTipText(Messages.getString("guiTooltip"));
_headerButtonGroup.add(_guiHeaderRadio);
jpanel1.add(_guiHeaderRadio,cc.xy(4,2));
_consoleHeaderRadio.setActionCommand("Console");
_consoleHeaderRadio.setName("consoleHeaderRadio");
_consoleHeaderRadio.setText(Messages.getString("console"));
_consoleHeaderRadio.setToolTipText(Messages.getString("consoleTooltip"));
_headerButtonGroup.add(_consoleHeaderRadio);
jpanel1.add(_consoleHeaderRadio,cc.xy(6,2));
@@ -131,14 +136,14 @@ public abstract class HeaderForm extends JPanel
jscrollpane1.setViewportView(_headerObjectsTextArea);
jscrollpane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jscrollpane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jpanel1.add(jscrollpane1,cc.xywh(4,6,4,1));
jpanel1.add(jscrollpane1,cc.xywh(4,6,8,1));
_libsTextArea.setName("libsTextArea");
JScrollPane jscrollpane2 = new JScrollPane();
jscrollpane2.setViewportView(_libsTextArea);
jscrollpane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jscrollpane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jpanel1.add(jscrollpane2,cc.xywh(4,8,4,1));
jpanel1.add(jscrollpane2,cc.xywh(4,8,8,1));
_headerObjectsCheck.setActionCommand("Object files");
_headerObjectsCheck.setName("headerObjectsCheck");
@@ -152,9 +157,25 @@ public abstract class HeaderForm extends JPanel
_linkerOptionsSeparator.setName("linkerOptionsSeparator");
_linkerOptionsSeparator.setText(Messages.getString("linkerOptions"));
jpanel1.add(_linkerOptionsSeparator,cc.xywh(2,4,6,1));
jpanel1.add(_linkerOptionsSeparator,cc.xywh(2,4,10,1));
addFillComponents(jpanel1,new int[]{ 1,2,3,4,5,6,7,8 },new int[]{ 1,2,3,4,5,6,7,8,9 });
_jniGuiHeaderRadio.setActionCommand(Messages.getString("jniGui"));
_jniGuiHeaderRadio.setForeground(new Color(255,102,0));
_jniGuiHeaderRadio.setName("jniGuiHeaderRadio");
_jniGuiHeaderRadio.setText(Messages.getString("jniGui"));
_jniGuiHeaderRadio.setToolTipText(Messages.getString("jniGuiTooltip"));
_headerButtonGroup.add(_jniGuiHeaderRadio);
jpanel1.add(_jniGuiHeaderRadio,cc.xy(8,2));
_jniConsoleHeaderRadio.setActionCommand(Messages.getString("jniConsole"));
_jniConsoleHeaderRadio.setForeground(new Color(255,102,0));
_jniConsoleHeaderRadio.setName("jniConsoleHeaderRadio");
_jniConsoleHeaderRadio.setText(Messages.getString("jniConsole"));
_jniConsoleHeaderRadio.setToolTipText(Messages.getString("jniConsoleTooltip"));
_headerButtonGroup.add(_jniConsoleHeaderRadio);
jpanel1.add(_jniConsoleHeaderRadio,cc.xy(10,2));
addFillComponents(jpanel1,new int[]{ 1,2,3,4,5,6,7,8,9,10,11,12 },new int[]{ 1,2,3,4,5,6,7,8,9 });
return jpanel1;
}

View File

@@ -9,6 +9,7 @@ import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
@@ -37,6 +38,10 @@ public abstract class VersionInfoForm extends JPanel
protected final JTextField _internalNameField = new JTextField();
protected final JLabel _companyNameLabel = new JLabel();
protected final JTextField _companyNameField = new JTextField();
protected final JLabel _languageLabel = new JLabel();
protected final JComboBox _languageCombo = new JComboBox();
protected final JLabel _trademarksLabel = new JLabel();
protected final JTextField _trademarksField = new JTextField();
/**
* Default constructor
@@ -116,7 +121,7 @@ public abstract class VersionInfoForm extends JPanel
public JPanel createPanel()
{
JPanel jpanel1 = new JPanel();
FormLayout formlayout1 = new FormLayout("FILL:7DLU:NONE,RIGHT:MAX(65DLU;DEFAULT):NONE,FILL:3DLU:NONE,FILL:60DLU:NONE,FILL:7DLU:NONE,RIGHT:DEFAULT:NONE,FILL:3DLU:NONE,FILL:DEFAULT:GROW(1.0),FILL:7DLU:NONE","CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE");
FormLayout formlayout1 = new FormLayout("FILL:7DLU:NONE,RIGHT:MAX(65DLU;DEFAULT):NONE,FILL:3DLU:NONE,FILL:60DLU:NONE,FILL:7DLU:NONE,RIGHT:DEFAULT:NONE,FILL:3DLU:NONE,FILL:DEFAULT:GROW(1.0),FILL:7DLU:NONE","CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:3DLU:NONE,CENTER:DEFAULT:NONE,CENTER:9DLU:NONE");
CellConstraints cc = new CellConstraints();
jpanel1.setLayout(formlayout1);
@@ -215,7 +220,21 @@ public abstract class VersionInfoForm extends JPanel
_companyNameField.setName("companyNameField");
jpanel1.add(_companyNameField,cc.xywh(4,16,5,1));
addFillComponents(jpanel1,new int[]{ 1,2,3,4,5,6,7,8,9 },new int[]{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21 });
_languageLabel.setName("languageLabel");
_languageLabel.setText(Messages.getString("language"));
jpanel1.add(_languageLabel,cc.xy(2,24));
_languageCombo.setName("languageCombo");
jpanel1.add(_languageCombo,cc.xywh(4,24,3,1));
_trademarksLabel.setName("trademarksLabel");
_trademarksLabel.setText(Messages.getString("trademarks"));
jpanel1.add(_trademarksLabel,cc.xy(2,22));
_trademarksField.setName("trademarksField");
jpanel1.add(_trademarksField,cc.xywh(4,22,5,1));
addFillComponents(jpanel1,new int[]{ 1,2,3,4,5,6,7,8,9 },new int[]{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25 });
return jpanel1;
}

View File

@@ -71,7 +71,13 @@ importClassPath=Import attributes from a jar's manifest.
headerType=Header type:
gui=GUI
guiTooltip=Stable version of the GUI header which uses the javaw.exe launcher.
console=Console
consoleTooltip=Stable version of the console header which uses the java.exe launcher.
jniGui=JNI GUI (beta)
jniGuiTooltip=BETA version of the GUI header which launches the Java VM through JNI.
jniConsole=JNI Console (beta)
jniConsoleTooltip=BETA version of the console header which launches the Java VM through JNI.
objectFiles=Object files:
libs=w32api:
linkerOptions=Custom header - linker options
@@ -141,6 +147,9 @@ originalFilenameTip=Original name of the file without the path. Allows to determ
internalName=Internal name:
internalNameTip=Internal name without extension, original filename or module name for example.
companyName=Company name:
trademarks=Trademarks:
language=Language:
charset=Charset:
addMessages=Add custom messages
startupErr=Startup error:

View File

@@ -40,8 +40,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JRadioButton;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.sf.launch4j.binding.Binding;
import net.sf.launch4j.binding.Bindings;
@@ -58,24 +56,45 @@ public class HeaderFormImpl extends HeaderForm {
public HeaderFormImpl(Bindings bindings) {
_bindings = bindings;
_bindings.add("headerTypeIndex", new JRadioButton[] { _guiHeaderRadio,
_consoleHeaderRadio })
_consoleHeaderRadio,
_jniGuiHeaderRadio,
_jniConsoleHeaderRadio })
.add("headerObjects", "customHeaderObjects", _headerObjectsCheck,
_headerObjectsTextArea)
.add("libs", "customLibs", _libsCheck, _libsTextArea);
_guiHeaderRadio.addChangeListener(new HeaderTypeChangeListener());
_guiHeaderRadio.setActionCommand(Config.GUI_HEADER);
_consoleHeaderRadio.setActionCommand(Config.CONSOLE_HEADER);
_jniGuiHeaderRadio.setActionCommand(Config.JNI_GUI_HEADER_32);
_jniConsoleHeaderRadio.setActionCommand(Config.JNI_CONSOLE_HEADER_32);
ActionListener headerTypeActionListener = new HeaderTypeActionListener();
_guiHeaderRadio.addActionListener(headerTypeActionListener);
_consoleHeaderRadio.addActionListener(headerTypeActionListener);
_jniGuiHeaderRadio.addActionListener(headerTypeActionListener);
_jniConsoleHeaderRadio.addActionListener(headerTypeActionListener);
_headerObjectsCheck.addActionListener(new HeaderObjectsActionListener());
_libsCheck.addActionListener(new LibsActionListener());
}
private void updateLibs() {
if (!_libsCheck.isSelected()) {
ConfigPersister.getInstance().getConfig().setLibs(null);
Binding b = _bindings.getBinding("libs");
b.put(ConfigPersister.getInstance().getConfig());
}
}
private class HeaderTypeChangeListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
private class HeaderTypeActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Config c = ConfigPersister.getInstance().getConfig();
c.setHeaderType(_guiHeaderRadio.isSelected() ? Config.GUI_HEADER
: Config.CONSOLE_HEADER);
c.setHeaderType(e.getActionCommand());
if (!_headerObjectsCheck.isSelected()) {
Binding b = _bindings.getBinding("headerObjects");
b.put(c);
updateLibs();
}
}
}
@@ -92,11 +111,7 @@ public class HeaderFormImpl extends HeaderForm {
private class LibsActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (!_libsCheck.isSelected()) {
ConfigPersister.getInstance().getConfig().setLibs(null);
Binding b = _bindings.getBinding("libs");
b.put(ConfigPersister.getInstance().getConfig());
}
updateLibs();
}
}
}

View File

@@ -69,7 +69,6 @@ import net.sf.launch4j.Util;
import net.sf.launch4j.binding.Binding;
import net.sf.launch4j.binding.BindingException;
import net.sf.launch4j.binding.InvariantViolationException;
import net.sf.launch4j.config.Config;
import net.sf.launch4j.config.ConfigPersister;
import net.sf.launch4j.config.ConfigPersisterException;
@@ -226,7 +225,7 @@ public class MainFrame extends JFrame {
}
private void showConfigName(File config) {
setTitle(Main.getName() + " - " + (config != null ? config.getName()
setTitle(Main.getName() + " - " + (config != null ? config.getName()
: Messages.getString("MainFrame.untitled")));
}
@@ -309,8 +308,8 @@ public class MainFrame extends JFrame {
ConfigPersister.getInstance().getConfig().checkInvariants();
Builder b = new Builder(log);
_outfile = b.build();
setRunEnabled(ConfigPersister.getInstance().getConfig()
.getHeaderType() == Config.GUI_HEADER // TODO fix console app test
setRunEnabled(ConfigPersister.getInstance().getConfig().isGuiApplication()
// TODO fix console app test
&& (Util.WINDOWS_OS || !ConfigPersister.getInstance()
.getConfig().isDontWrapJar()));
} catch (InvariantViolationException ex) {

View File

@@ -36,9 +36,11 @@
*/
package net.sf.launch4j.formimpl;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFileChooser;
import net.sf.launch4j.binding.Bindings;
import net.sf.launch4j.config.LanguageID;
import net.sf.launch4j.config.VersionInfo;
import net.sf.launch4j.form.VersionInfoForm;
@@ -48,6 +50,7 @@ import net.sf.launch4j.form.VersionInfoForm;
public class VersionInfoFormImpl extends VersionInfoForm {
public VersionInfoFormImpl(Bindings bindings, JFileChooser fc) {
_languageCombo.setModel(new DefaultComboBoxModel(LanguageID.sortedValues()));
bindings.addOptComponent("versionInfo", VersionInfo.class, _versionInfoCheck)
.add("versionInfo.fileVersion", _fileVersionField)
.add("versionInfo.productVersion", _productVersionField)
@@ -58,6 +61,9 @@ public class VersionInfoFormImpl extends VersionInfoForm {
.add("versionInfo.txtFileVersion", _txtFileVersionField)
.add("versionInfo.txtProductVersion", _txtProductVersionField)
.add("versionInfo.companyName", _companyNameField)
.add("versionInfo.copyright", _copyrightField);
.add("versionInfo.copyright", _copyrightField)
.add("versionInfo.trademarks", _trademarksField)
.add("versionInfo.languageIndex", _languageCombo, VersionInfo.DEFAULT_LANGUAGE_INDEX)
;
}
}

View File

@@ -35,7 +35,7 @@ Main.usage=usage
Builder.compiling.resources=Compiling resources
Builder.linking=Linking
Builder.wrapping=Wrapping
Builder.wrapping=Wrapping\nWARNING: Sign the executable to minimize antivirus false positives or use launching instead of wrapping.
Builder.success=Successfully created
Builder.generated.resource.file=Generated resource file...\n
Builder.line.has.errors=Line {0} has errors...

View File

@@ -0,0 +1,25 @@
MinGW - Licensing Terms
Various pieces distributed with MinGW come with its own copyright and license:
Basic MinGW runtime
MinGW base runtime package is uncopyrighted and placed in the public domain.
This basically means that you can do what you want with the code.
w32api
You are free to use, modify and copy this package.
No restrictions are imposed on programs or object files compiled with this library.
You may not restrict the the usage of this library.
You may distribute this library as part of another package or as a modified package
if and only if you do not restrict the usage of the portions consisting
of this (optionally modified) library.
If distributed as a modified package then this file must be included.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
MinGW profiling code
MinGW profiling code is distributed under the GNU General Public License.
The development tools such as GCC, GDB, GNU Make, etc all covered by GNU General Public License.

BIN
launch4j/w32api_jni/crt2.o Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -11,7 +11,7 @@
<body>
<div id="container">
<div id="top">
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.7</span>
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.12</span>
</div>
<div id="leftnav">
<ul>
@@ -19,26 +19,63 @@
<li><a href="docs.html">Docs</a></li>
<li><a href="changelog.html">Changelog</a></li>
<li><a href="http://sourceforge.net/project/screenshots.php?group_id=95944">Screenshots</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.7">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.12">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/support">Support</a></li>
<li><a href="http://sourceforge.net/projects/launch4j">Project summary</a></li>
<li><a href="http://sourceforge.net/tracker/?atid=613100&amp;group_id=95944">Bug tracker</a></li>
<li><a href="links.html">Links</a></li>
</ul>
<!--
*** Spanish docs are outdated ***
<ul style="margin-top: 20px; font-size: 75%">
<li><a href="index.html">English</a></li>
<li><a href="index_es.html">Español</a></li>
</ul>
-->
<br />
<a class="button" href="https://sourceforge.net/projects/launch4j/files/launch4j-3/3.12" rel="nofollow"><img alt="Downloads" src="https://img.shields.io/sourceforge/dm/launch4j.svg"></a>
<a class="button" href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j" src="https://sourceforge.net/sflogo.php?type=10&group_id=95944"></a>
</div>
<div id="content">
<h2>Changelog</h2>
<h4>Changes in version 3.12 (17-05-2018)</h4>
<ul class="changes">
<li class="warn">Ticket #179, #183 The generated executable fully supports Java 9 and newer (Sergey Karpushin).</li>
<li>Ticket #161 Support of update version higher than 99 (Sergey Karpushin).</li>
<li>Ticket #177 Launching on Java 9 JDK and newer is now possible (not just JRE).</li>
<li>Known issue: launch4j itself does not support Java 9 Early Access, use a public release instead or Java 10.</li>
</ul>
<h4>Changes in version 3.11 (27-06-2017)</h4>
<ul class="changes">
<li>Log more regarding Java search and missing resources.</li>
<li>Log resource file during build.</li>
<li>Added basic Java 9 support (only major version is detected right now due to version scheme change).</li>
<li>Ticket #145 Allow literal use of % in JRE options and set environment variables, use %% (blueskyhigh).</li>
<li>Added Linux 64-bit binaries (Sebastian Bögl).</li>
<li>Added IBM Java 1.8 support.</li>
<li>JNI header: fixed a crash where launch4j would try to `free` non-heap memory (Alexander Floh).</li>
<li>Ticket #160 Removed old Mac OS X package which caused problems on newer versions of the system.</li>
</ul>
<h4>Changes in version 3.9 (20-07-2016)</h4>
<ul class="changes">
<li>Ticket #146 Fixed java version check where the update number was greater than 99 (e.g. 1.8.0_101).</li>
<li>Enlarged the total classpath length to 30KB.</li>
<li>Ticket #142 Unbound VersionInfo returns wrong LanguageID (Sebastian Bögl).</li>
<li>Ticket #141 Ensure encoding of resource file to be iso-8859-1 (Thomas Scheithauer).</li>
<li>More reactive splash screen response to main window appearance (Federico Fissore).</li>
<li>FR #95 Launch4j should return an exit value (Sebastian Bögl).</li>
<li>FR #94 Add the working directory classifier for OS X (Sebastian Bögl).</li>
<li>FR #39 Launch Java VM through JNI (Ryan Rusaw) - BETA!</li>
<li>FR #69 Configure the language property of generated executables (Sebastian Bögl).</li>
<li>FR #77 Add legal trademarks as an additional field in version info tab (Sebastian Bögl).</li>
<li>Added a simple example how to use the Maven plugin (demo/ExitCodeApp).</li>
</ul>
<h4>Changes in version 3.8 (09-05-2015)</h4>
<ul class="changes">
<li>FR #59 Mavenized launch4j (thanks to taxone, Paul Jungwirth, Lukasz Lenart).</li>
<li>Ticket #139 Sign4j compiles and works on Linux (Tim Angus).</li>
</ul>
<h4>Changes in version 3.7 (01-03-2015)</h4>
<ul class="changes">
<li>Fixed false positive virus warnings.</li>
<li>Fixed false positive virus warnings that appeared in version 3.6.</li>
</ul>
<h4>Changes in version 3.6 (06-01-2015)</h4>
@@ -46,8 +83,7 @@
<li>FR #86 The 32/64 bit search is fully configurable (64, 64/32, 32/64, 32) - added option 32/64.</li>
<li>FR #70 Java search sequence - bundled JRE can be used before or after the min/max version search (bundledJreAsFallback).</li>
<li>Fixed: Crash when classpath contained wildcard patterns where the dependency was in the same directory as the launcher.</li>
<li>Fixed Launch4j GUI application closing - the process was still running.</li>
<li style="text-decoration: line-through">Updated to Dev-Cpp 5.7.1, MinGW 4.8.1 (head_src and w32api files).</li>
<li>Fixed launch4j GUI application closing - the process was still running.</li>
</ul>
<h4>Changes in version 3.5 (09-10-2014)</h4>
@@ -62,7 +98,7 @@
<li>FR #61 Added a new special variable JREHOMEDIR (Stefan Knoefel).</li>
<li>Ticket #130 Removed ant from launch4j classpath to fix problems with other ant versions.</li>
<li>Updated JGoodies libraries.</li>
<li>Added logging based on Launch4j environment variable for file association launch testing.</li>
<li>Added logging based on launch4j environment variable for file association launch testing.</li>
</ul>
<h4>Changes in version 3.3 (02-04-2014)</h4>
@@ -422,9 +458,9 @@
</div>
<div class="footer">
All trademarks mentioned are properties of their respective owners.<br />
Copyright &copy; 2005-2015 Grzegorz Kowal
<p style="margin-top: 2em">
<a href="http://sourceforge.net"><img style="width: 125px; height: 37px; border: none" src="http://sourceforge.net/sflogo.php?group_id=95944&amp;type=4" alt="sf.net"></a>
Copyright &copy; 2005-2017 Grzegorz Kowal
<p style="margin-top: 0.5em">
<a href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j Executable Wrapper" src="https://sourceforge.net/sflogo.php?type=16&group_id=95944"></a>
</p>
</div>
</div>

View File

@@ -11,7 +11,7 @@
<body>
<div id="container">
<div id="top">
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.7</span>
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.12</span>
</div>
<div id="leftnav">
<ul>
@@ -19,19 +19,15 @@
<li><a href="docs.html">Docs</a></li>
<li><a href="changelog.html">Changelog</a></li>
<li><a href="http://sourceforge.net/project/screenshots.php?group_id=95944">Screenshots</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.7">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.12">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/support">Support</a></li>
<li><a href="http://sourceforge.net/projects/launch4j">Project summary</a></li>
<li><a href="http://sourceforge.net/tracker/?atid=613100&amp;group_id=95944">Bug tracker</a></li>
<li><a href="links.html">Links</a></li>
</ul>
<!--
*** Spanish docs are outdated ***
<ul style="margin-top: 20px; font-size: 75%">
<li><a href="index.html">English</a></li>
<li><a href="index_es.html">Español</a></li>
</ul>
-->
<br />
<a class="button" href="https://sourceforge.net/projects/launch4j/files/launch4j-3/3.12" rel="nofollow"><img alt="Downloads" src="https://img.shields.io/sourceforge/dm/launch4j.svg"></a>
<a class="button" href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j" src="https://sourceforge.net/sflogo.php?type=10&group_id=95944"></a>
</div>
<div id="content">
<a href="#Running_launch4j">Running launch4j</a><br>
@@ -65,14 +61,17 @@ all of the configuration parameters through the Ant task. All files
may be absolute paths or relative to the configuration file path.
<pre>
&lt;!-- <strong>Bold</strong> elements are required --&gt;
&lt;!-- %VAR% expands environment/special variables and registry keys --&gt;
&lt;!--
<strong>Bold</strong> elements are required.
<span class="codeword"><u>Underlined</u></span> values are the default when the element is not specified.
%VAR% expands environment/special variables and registry keys.
--&gt;
<strong>&lt;launch4jConfig&gt;</strong>
<strong>&lt;headerType&gt;</strong><span class="codeword">gui|console</span><strong>&lt;/headerType&gt;</strong>
<strong>&lt;headerType&gt;</strong><span class="codeword">gui|console|jniGui32|jniConsole32</span><strong>&lt;/headerType&gt;</strong>
<strong>&lt;outfile&gt;</strong><span class="codeword">file.exe</span><strong><span class="codeword"></span>&lt;/outfile&gt;</strong>
&lt;jar&gt;<span class="codeword">file</span><span class="codeword"></span>&lt;/jar&gt;
&lt;dontWrapJar&gt;<span class="codeword">true|<u>false</u></span>&lt;/dontWrapJar&gt;
&lt;errTitle&gt;<span class="codeword">text</span>&lt;/errTitle&gt;
&lt;errTitle&gt;<span class="codeword">application name</span>&lt;/errTitle&gt;
&lt;downloadUrl&gt;<span class="codeword"><u>http://java.com/download</u></span>&lt;/downloadUrl&gt;
&lt;supportUrl&gt;<span class="codeword">url</span>&lt;/supportUrl&gt;
&lt;cmdLine&gt;<span class="codeword">text</span>&lt;/cmdLine&gt;
@@ -97,15 +96,15 @@ may be absolute paths or relative to the configuration file path.
&lt;windowTitle&gt;<span class="codeword">text</span>&lt;/windowTitle&gt;
&lt;/singleInstance&gt;
<strong>&lt;jre&gt;</strong>
&lt;!-- Specify one of the following or both --&gt;
&lt;!-- Specify <strong>path</strong> or <strong>minVersion</strong> or both. --&gt;
<strong>&lt;path&gt;</strong><span class="codeword">bundled JRE path (%VAR%)</span><strong>&lt;/path&gt;</strong>
&lt;bundledJre64Bit&gt;<span class="codeword">true|<u>false</u></span>&lt;/bundledJre64Bit&gt;
&lt;bundledJreAsFallback&gt;<span class="codeword">true|<u>false</u></span>&lt;/bundledJreAsFallback&gt;
<strong>&lt;minVersion&gt;</strong><span class="codeword">x.x.x[_xx]</span><strong>&lt;/minVersion&gt;</strong>
&lt;maxVersion&gt;<span class="codeword">x.x.x[_xx]</span>&lt;/maxVersion&gt;
<strong>&lt;minVersion&gt;</strong><span class="codeword">1.x.x[_xxx]|xxx[.xxx[.xxx]]</span><strong>&lt;/minVersion&gt;</strong>
&lt;maxVersion&gt;<span class="codeword">1.x.x[_xxx]|xxx[.xxx[.xxx]]</span>&lt;/maxVersion&gt;
&lt;jdkPreference&gt;<span class="codeword">jreOnly|<u>preferJre</u>|preferJdk|jdkOnly</span>&lt;/jdkPreference&gt;
&lt;runtimeBits&gt;<span class="codeword">64|<u>64/32</u>|32/64|32</span>&lt;/runtimeBits&gt;
&lt;!-- Heap sizes in MB and % of available memory --&gt;
&lt;!-- Heap sizes in MB and % of available memory. --&gt;
&lt;initialHeapSize&gt;<span class="codeword">MB</span>&lt;/initialHeapSize&gt;
&lt;initialHeapPercent&gt;<span class="codeword">%</span>&lt;/initialHeapPercent&gt;
&lt;maxHeapSize&gt;<span class="codeword">MB</span>&lt;/maxHeapSize&gt;
@@ -130,13 +129,26 @@ may be absolute paths or relative to the configuration file path.
&lt;companyName&gt;<span class="codeword">text</span>&lt;/companyName&gt;
<strong>&lt;internalName&gt;</strong><span class="codeword">filename</span><strong>&lt;/internalName&gt;</strong>
<strong>&lt;originalFilename&gt;</strong><span class="codeword">filename.exe</span><strong>&lt;/originalFilename&gt;</strong>
&lt;trademarks&gt;<span class="codeword">text</span>&lt;/trademarks&gt;
&lt;language&gt;<span class="codeword">
ALBANIAN|ARABIC|BAHASA|DUTCH_BELGIAN|FRENCH_BELGIAN|BULGARIAN|
FRENCH_CANADIAN|CASTILIAN_SPANISH|CATALAN|CROATO_SERBIAN_LATIN|
CZECH|DANISH|DUTCH|ENGLISH_UK|<u>ENGLISH_US</u>|FINNISH|FRENCH|GERMAN|
GREEK|HEBREW|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|
NORWEGIAN_BOKMAL|NORWEGIAN_NYNORSK|POLISH|PORTUGUESE_BRAZIL|
PORTUGUESE_PORTUGAL|RHAETO_ROMANIC|ROMANIAN|RUSSIAN|
SERBO_CROATIAN_CYRILLIC|SIMPLIFIED_CHINESE|SLOVAK|SPANISH_MEXICO|
SWEDISH|FRENCH_SWISS|GERMAN_SWISS|ITALIAN_SWISS|THAI|
TRADITIONAL_CHINESE|TURKISH|URDU
</span>&lt;/language&gt;
&lt;/versionInfo&gt;
&lt;messages&gt;
<strong>&lt;startupErr&gt;</strong>text<strong>&lt;/startupErr&gt;</strong>
<strong>&lt;bundledJreErr&gt;</strong>text<strong>&lt;/bundledJreErr&gt;</strong>
<strong>&lt;jreVersionErr&gt;</strong>text<strong>&lt;/jreVersionErr&gt;</strong>
<strong>&lt;launcherErr&gt;</strong>text<strong>&lt;/launcherErr&gt;</strong>
<strong>&lt;instanceAlreadyExistsMsg&gt;</strong>text (used by console header only)<strong>&lt;/instanceAlreadyExistsMsg&gt;</strong>
&lt;!-- Used by console header only. --&gt;
<strong>&lt;instanceAlreadyExistsMsg&gt;</strong>text<strong>&lt;/instanceAlreadyExistsMsg&gt;</strong>
&lt;/messages&gt;
<strong>&lt;/launch4jConfig&gt;</strong>
</pre>
@@ -170,8 +182,37 @@ may be absolute paths or relative to the configuration file path.
<td>no</td>
<td class="description">always waits and returns application's exit code.</td>
</tr>
<tr>
<td>jniGui32 <strong style="color: red">(beta)</strong></td>
<td>launch4j</td>
<td>yes</td>
<td class="description">always waits and returns application's exit code.</td>
</tr>
<tr>
<td>jniConsole32 <strong style="color: red">(beta)</strong></td>
<td>launch4j</td>
<td>no</td>
<td class="description">always waits and returns application's exit code.</td>
</tr>
</tbody>
</table>
<br />
When JNI headers are used the JVM is created directly by the launch4j wrapper executable instead of running java/javaw launchers.
The process name will be the same as the wrapper. The JNI headers are in BETA and some features are not available which is signaled
during wrapper build based on the configuration.
For production use consider the classic gui/console headers.
<br />
Missing features:
<ul>
<li>Only '.' is allowed in change directory (chdir).</li>
<li>Command line arguments cannot be passed to the executable.</li>
<li>Constant command line arguments (cmdLine).</li>
<li>stayAlive should be ignored by JNI headers.</li>
<li>Restart of appplication based on exit code (restartOnCrash).</li>
<li>Process priority - only normal is supported (priority).</li>
<li>Jar manifest is ignored, mainclass and classpath must be defined.</li>
<li>64-bit JRE are not supported.</li>
</ul>
</dd>
</dl>
<dl>
@@ -280,7 +321,7 @@ may be absolute paths or relative to the configuration file path.
use the <em>&lt;minVersion&gt;</em> property, you may also specify
the <em>&lt;maxVersion&gt;</em> to prevent it from using higher Java versions.
Launch4j will always use the highest version available (in the min/max range of course).
If a Sun's JRE is not available or does not satisfy the search criteria,
If an Oracle's JRE is not available or does not satisfy the search criteria,
the search will be repeated on IBM runtimes.
You can also combine these properties to change the startup process...
</dd>
@@ -300,6 +341,30 @@ may be absolute paths or relative to the configuration file path.
</dl>
</blockquote>
</blockquote>
<blockquote>
<dl>
<dt>&lt;minVersion&gt;, &lt;maxVersion&gt; format - Java < 9</dt>
<dd>The traditional version scheme supported by launch4j is 1.x.x[_xxx] and requires at least 3 parts, for example:
<pre>
1.6.0
1.7.0_51
1.8.0_121
</pre>
</dd>
</dl>
</blockquote>
<blockquote>
<dl>
<dt>&lt;minVersion&gt;, &lt;maxVersion&gt; format - Java >= 9</dt>
<dd>The new version format is xxx[.xxx[.xxx]] where only 1 part is required and the update version after the underscore is not allowed.
<pre>
1.6
9
10.0.1
</pre>
</dd>
</dl>
</blockquote>
<blockquote>
<dl>
<dt>&lt;bundledJre64Bit&gt;</dt>
@@ -442,7 +507,8 @@ may be absolute paths or relative to the configuration file path.
<dl>
<dt>&lt;versionInfo&gt;</dt>
<dd>Optional, version information to be displayed by the Windows Explorer.</dd>
<dd>Optional, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa381058%28v=vs.85%29.aspx">version information</a>
to be displayed by the Windows Explorer.</dd>
</dl>
<blockquote>
<dl>
@@ -487,6 +553,14 @@ may be absolute paths or relative to the configuration file path.
whether a file has been renamed by a user.
</dd>
</dl>
<dl>
<dt>&lt;trademarks&gt;</dt>
<dd>Trademarks that apply to the file.</dd>
</dl>
<dl>
<dt>&lt;language&gt;</dt>
<dd>One of the language codes.</dd>
</dl>
</blockquote>
<h2 id="Importing_1.x_configuration">Importing 1.x configuration</h2>
@@ -643,6 +717,7 @@ They are substitued during runtime, so for example the EXEDIR is the directory w
</dl>
<h2 id="Settings">Settings</h2>
These settings are only used during building of the launcher or wrapper, not during their execution.
<dl>
<dt>Alternate bin directory: launch4j.bindir</dt>
<dd>
@@ -657,9 +732,9 @@ They are substitued during runtime, so for example the EXEDIR is the directory w
</div>
<div class="footer">
All trademarks mentioned are properties of their respective owners.<br />
Copyright &copy; 2005-2015 Grzegorz Kowal
<p style="margin-top: 2em">
<a href="http://sourceforge.net"><img style="width: 125px; height: 37px; border: none" src="http://sourceforge.net/sflogo.php?group_id=95944&amp;type=4" alt="sf.net"></a>
Copyright &copy; 2005-2017 Grzegorz Kowal
<p style="margin-top: 0.5em">
<a href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j Executable Wrapper" src="https://sourceforge.net/sflogo.php?type=16&group_id=95944"></a>
</p>
</div>
</div>

View File

@@ -11,7 +11,7 @@
<body>
<div id="container">
<div id="top">
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.7</span>
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.12</span>
</div>
<div id="leftnav">
<ul>
@@ -19,19 +19,15 @@
<li><a href="docs.html">Docs</a></li>
<li><a href="changelog.html">Changelog</a></li>
<li><a href="http://sourceforge.net/project/screenshots.php?group_id=95944">Screenshots</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.7">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.12">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/support">Support</a></li>
<li><a href="http://sourceforge.net/projects/launch4j">Project summary</a></li>
<li><a href="http://sourceforge.net/tracker/?atid=613100&amp;group_id=95944">Bug tracker</a></li>
<li><a href="links.html">Links</a></li>
</ul>
<!--
*** Spanish docs are outdated ***
<ul style="margin-top: 20px; font-size: 75%">
<li><a href="index.html">English</a></li>
<li><a href="index_es.html">Español</a></li>
</ul>
-->
<br />
<a class="button" href="https://sourceforge.net/projects/launch4j/files/launch4j-3/3.12" rel="nofollow"><img alt="Downloads" src="https://img.shields.io/sourceforge/dm/launch4j.svg"></a>
<a class="button" href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j" src="https://sourceforge.net/sflogo.php?type=10&group_id=95944"></a>
</div>
<div id="content">
<h2>Cross-platform Java executable wrapper</h2>
@@ -87,22 +83,22 @@
<li>Digital signing of the executable with sign4j.</li>
<li>Supports Windows Security Features of the Windows 8 certification kit.</li>
<li><strong>GUI</strong> and command line interface.</li>
<li>Build integration through an <strong>Ant task</strong>.</li>
<li>Build integration through an <strong>Ant task</strong> and a <strong><a href="https://github.com/lukaszlenart/launch4j-maven-plugin">Maven Plugin</a></strong>.</li>
<li><strong>Lightweight: 35 KB!</strong></li>
<li><strong>It's free</strong> and may be used for commercial purposes.</li>
<li>Includes a sample application and <strong>Ant script</strong>
that automates the build process from Java sources to native executable.
</li>
<li>The wrapped program works on all Windows platforms (98/Me/NT/2K/XP/Vista/7/8),
Launch4j works on NT/2K/XP/Vista/7/8, Linux and Mac OS X.
<li>The wrapped program works on all Windows platforms,
Launch4j works on Windows, Linux and Mac OS X.
</li>
</ul>
<h2>License</h2>
<p>
This program is free software licensed under the
<a href="http://www.opensource.org/licenses/bsd-license.html">BSD license</a>, the <em>head</em> subproject
<a href="http://opensource.org/licenses/BSD-3-Clause">BSD 3-Clause License</a>, the <em>head</em> subproject
(the code which is attached to the wrapped jars) is licensed under the
<a href="http://www.opensource.org/licenses/mit-license.html">MIT license</a>.
<a href="http://opensource.org/licenses/mit-license.html">MIT License</a>.
Launch4j may be used for wrapping closed source, commercial applications.
</p>
<h2>Info</h2>
@@ -116,9 +112,9 @@
</div>
<div class="footer">
All trademarks mentioned are properties of their respective owners.<br />
Copyright &copy; 2005-2015 Grzegorz Kowal
<p style="margin-top: 2em">
<a href="http://sourceforge.net"><img style="width: 125px; height: 37px; border: none" src="http://sourceforge.net/sflogo.php?group_id=95944&amp;type=4" alt="sf.net"></a>
Copyright &copy; 2005-2017 Grzegorz Kowal
<p style="margin-top: 0.5em">
<a href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j Executable Wrapper" src="https://sourceforge.net/sflogo.php?type=16&group_id=95944"></a>
</p>
</div>
</div>

View File

@@ -11,7 +11,7 @@
<body>
<div id="container">
<div id="top">
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.7</span>
<img style="width: 249px; height: 58px;" src="launch4j.gif" alt="launch4j"> <span class="version">3.12</span>
</div>
<div id="leftnav">
<ul>
@@ -19,23 +19,21 @@
<li><a href="docs.html">Docs</a></li>
<li><a href="changelog.html">Changelog</a></li>
<li><a href="http://sourceforge.net/project/screenshots.php?group_id=95944">Screenshots</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.7">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/files/launch4j-3/3.12">Download</a></li>
<li><a href="http://sourceforge.net/projects/launch4j/support">Support</a></li>
<li><a href="http://sourceforge.net/projects/launch4j">Project summary</a></li>
<li><a href="http://sourceforge.net/tracker/?atid=613100&amp;group_id=95944">Bug tracker</a></li>
<li><a href="links.html">Links</a></li>
</ul>
<!--
*** Spanish docs are outdated ***
<ul style="margin-top: 20px; font-size: 75%">
<li><a href="index.html">English</a></li>
<li><a href="index_es.html">Español</a></li>
</ul>
-->
<br />
<a class="button" href="https://sourceforge.net/projects/launch4j/files/launch4j-3/3.12" rel="nofollow"><img alt="Downloads" src="https://img.shields.io/sourceforge/dm/launch4j.svg"></a>
<a class="button" href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j" src="https://sourceforge.net/sflogo.php?type=10&group_id=95944"></a>
</div>
<div id="content">
<h2>Links</h2>
<p>
<a href="https://github.com/lukaszlenart/launch4j-maven-plugin">Maven plugin by Lukasz Lenart<a><br>
<a href="http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22net.sf.launch4j%22%20AND%20a%3A%22launch4j%22">Maven Central Repository</a><br>
<a href="http://prdownloads.sourceforge.net/dev-cpp/devcpp-4.9.9.2_setup.exe">Bloodshed Dev-C++</a><br>
<a href="http://www.mingw.org/">MinGW</a><br>
<a href="http://jakarta.apache.org/commons/beanutils/">Commons BeanUtils</a><br>
@@ -52,9 +50,9 @@
</div>
<div class="footer">
All trademarks mentioned are properties of their respective owners.<br />
Copyright &copy; 2005-2015 Grzegorz Kowal
<p style="margin-top: 2em">
<a href="http://sourceforge.net"><img style="width: 125px; height: 37px; border: none" src="http://sourceforge.net/sflogo.php?group_id=95944&amp;type=4" alt="sf.net"></a>
Copyright &copy; 2005-2017 Grzegorz Kowal
<p style="margin-top: 0.5em">
<a href="https://sourceforge.net/p/launch4j/" rel="nofollow"><img alt="Download Launch4j Executable Wrapper" src="https://sourceforge.net/sflogo.php?type=16&group_id=95944"></a>
</p>
</div>
</div>

View File

@@ -114,6 +114,13 @@ table td {
color: #ffffff;
}
#leftnav a.button {
display: inline;
}
#leftnav a.button:hover {
background-color: transparent;
}
#content {
max-width: 52em;

View File

@@ -1 +1 @@
version=0.3.5
version=0.4.2

Some files were not shown because too many files have changed in this diff Show More