Added RMS and clipping alert in tree view
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
+196
-21
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/jniconsolehead.exe
|
||||
/jniconsolehead.layout
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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=
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/jniguihead.exe
|
||||
/jniguihead.layout
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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=
|
||||
|
||||
@@ -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
|
||||
);
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user