OSDN Git Service

add winjvm
authorankys <ankys@users.sourceforge.jp>
Wed, 8 Jun 2011 10:30:18 +0000 (19:30 +0900)
committerankys <ankys@users.sourceforge.jp>
Wed, 8 Jun 2011 10:30:18 +0000 (19:30 +0900)
build.xml
winjvm/Makefile [new file with mode: 0755]
winjvm/PosterDivider.exe [new file with mode: 0755]
winjvm/jvm.c [new file with mode: 0755]
winjvm/jvm.h [new file with mode: 0755]
winjvm/posterdivider.c [new file with mode: 0755]

index f7e4da8..e9fcfea 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -50,6 +50,7 @@
         <concat destfile="win/PosterDivider/Jar/fileversion.txt">iText.jar&#x0A;PosterDivider.jar&#x0A;</concat>
         <replace file="win/PosterDivider/Jar/fileversion.txt" token="iText.jar" value="iText.jar -> ${ITEXTJAR}"/>
         <replace file="win/PosterDivider/Jar/fileversion.txt" token="PosterDivider.jar" value="PosterDivider.jar -> PosterDivider-${VERSION}.jar"/>
+        <copy file="winjvm/PosterDivider.exe" todir="win/PosterDivider"/>
         <copy file="Readme.txt" todir="win/PosterDivider"/>
     </target>
     <target name="zip" depends="exe">
@@ -85,7 +86,7 @@
             <arg value="PosterDivider-${VERSION}.dmg"/>
         </exec>
     </target>
-    <target name="all" depends="srczip, jar, dmg"/>
+    <target name="all" depends="srczip, jar, zip, dmg"/>
     <target name="updateversion">
         <replaceregexp file="src/jp/sourceforge/posterdivider/Message.properties" match="App\.Version=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" replace="App\.Version=${VERSION}" encoding="UTF-8"/>
         <replaceregexp file="src/jp/sourceforge/posterdivider/Message.properties" match="App\.ShortVersion=[0-9]+\.[0-9]+\.[0-9]+" replace="App\.ShortVersion=${SHORTVERSION}" encoding="UTF-8"/>
@@ -95,7 +96,6 @@
     </target>
     <target name="release" depends="all">
         <copy file="PosterDivider-src-${VERSION}.zip" tofile="PosterDivider-src.zip"/>
-        <copy file="PosterDivider-${VERSION}.jar" tofile="PosterDivider.jar"/>
         <copy file="PosterDivider-${VERSION}.dmg" tofile="PosterDivider.dmg"/>
     </target>
     <target name="clean">
diff --git a/winjvm/Makefile b/winjvm/Makefile
new file mode 100755 (executable)
index 0000000..1ae9d5d
--- /dev/null
@@ -0,0 +1,23 @@
+CC = cl
+CFLAGS = /nologo /Ox
+#CFLAGS = /nologo
+INCLUDES = /Iinclude /Iinclude/win32
+LIBOBJS = user32.lib advapi32.lib shell32.lib comctl32.lib
+
+TARGETS = PosterDivider.exe
+
+.SUFFIXES: .c .cpp .obj
+.c.obj:
+       $(CC) $(CFLAGS) $(INCLUDES) "$<" /c /Fo"$@"
+.cpp.obj:
+       $(CC) $(CFLAGS) $(INCLUDES) "$<" /c /Fo"$@"
+
+all: $(TARGETS)
+run: $(TARGETS)
+       PosterDivider.exe
+
+PosterDivider.exe: posterdivider.obj jvm.obj
+       $(CC) $(CFLAGS) $(LIBOBJS) jvm.obj posterdivider.obj /Fe"$@"
+
+clean:
+       del /Q $(TARGETS) *.obj
diff --git a/winjvm/PosterDivider.exe b/winjvm/PosterDivider.exe
new file mode 100755 (executable)
index 0000000..3a7d5e8
Binary files /dev/null and b/winjvm/PosterDivider.exe differ
diff --git a/winjvm/jvm.c b/winjvm/jvm.c
new file mode 100755 (executable)
index 0000000..06a03c9
--- /dev/null
@@ -0,0 +1,166 @@
+//
+// jvm.c
+// This file is part of PosterDivider.
+//
+
+#include <windows.h>
+
+#include <jni.h>
+
+typedef jint (JNICALL* JNICreateJavaVM)(JavaVM**, void**, void *);
+
+int getJVMPath(LPTSTR lpPathJava, LPTSTR lpPathJVM)
+{
+       // レジストリから jvm.dll のパスを取得
+       TCHAR lpSubKey[MAX_PATH];
+       HKEY hKey;
+       DWORD type;
+    BYTE lpData[MAX_PATH];
+    DWORD cbData;
+       
+    lstrcpy(lpSubKey, TEXT("Software\\JavaSoft\\Java Runtime Environment"));
+       if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+       {
+               return 1;
+       }
+       
+       cbData = sizeof(TCHAR) * MAX_PATH;
+    if(RegQueryValueEx(hKey, TEXT("CurrentVersion"), NULL, &type, lpData, &cbData) != ERROR_SUCCESS)
+       {
+               RegCloseKey(hKey);
+        return 2;
+    }
+       RegCloseKey(hKey);
+       
+       lstrcat(lpSubKey, TEXT("\\"));
+       lstrcat(lpSubKey, (LPTSTR)lpData);
+    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
+       {
+        return 3;
+    }
+       
+       cbData = sizeof(TCHAR) * MAX_PATH;
+    if(RegQueryValueEx(hKey, TEXT("JavaHome"), NULL, &type, lpData, &cbData) != ERROR_SUCCESS)
+       {
+               RegCloseKey(hKey);
+        return 4;
+    }
+    lstrcpy(lpPathJava, (LPTSTR)lpData);
+       
+       cbData = sizeof(TCHAR) * MAX_PATH;
+    if(RegQueryValueEx(hKey, TEXT("RuntimeLib"), NULL, &type, lpData, &cbData) != ERROR_SUCCESS)
+       {
+               RegCloseKey(hKey);
+        return 4;
+    }
+    lstrcpy(lpPathJVM, (LPTSTR)lpData);
+       
+       RegCloseKey(hKey);
+       return 0;
+}
+
+int createJVM(JNIEnv** jniEnv, JavaVM** javaVM, char* classPath)
+{
+       // javaVM の作成
+       int c;
+       TCHAR lpPathJava[MAX_PATH];
+       TCHAR lpPathMsvcr[MAX_PATH];
+       TCHAR lpPathJVM[MAX_PATH];
+    HMODULE hLibJVM;
+    JNICreateJavaVM createJavaVM;
+       char optionClassPath[1024];
+    JavaVMInitArgs javaVMInitArgs;
+    JavaVMOption javaVMOptions[1];
+       
+       c = getJVMPath(lpPathJava, lpPathJVM);
+       if(c)
+       {
+               return c;
+       }
+
+    lstrcpy(lpPathMsvcr, lpPathJava);
+       lstrcat(lpPathMsvcr, TEXT("\\bin\\msvcr71.dll"));
+    LoadLibrary(lpPathMsvcr);
+    hLibJVM = LoadLibrary(lpPathJVM);
+    //hLibJVM = (HMODULE)LoadLibraryEx(lpPath, NULL, DONT_RESOLVE_DLL_REFERENCES);
+    if(hLibJVM == NULL)
+       {
+        return 5;
+    }
+       
+    createJavaVM = (JNICreateJavaVM)GetProcAddress(hLibJVM, "JNI_CreateJavaVM");
+       if(createJavaVM == NULL)
+       {
+               return 6;
+       }
+       
+    // Java VMの作成
+       sprintf(optionClassPath, "-Djava.class.path=%s", classPath);
+       javaVMOptions[0].optionString = optionClassPath;
+       javaVMOptions[0].extraInfo = 0;
+    javaVMInitArgs.version = JNI_VERSION_1_2;
+    javaVMInitArgs.options = javaVMOptions;
+    javaVMInitArgs.nOptions = 1;
+    javaVMInitArgs.ignoreUnrecognized = JNI_TRUE;
+    if(createJavaVM(javaVM, (void**)jniEnv, &javaVMInitArgs) != 0)
+    //if(JNI_CreateJavaVM(javaVM, (void**)jniEnv, &javaVMInitArgs) != 0)
+       {
+        return 7;
+    }
+
+       return 0;
+}
+
+jobjectArray convertStringArray(JNIEnv* jniEnv, char **strs, int cStrs)
+{
+       int i;
+       jclass classString;
+       jobjectArray strArray;
+       
+    classString = (*jniEnv)->FindClass(jniEnv, "java/lang/String");
+       strArray = (*jniEnv)->NewObjectArray(jniEnv, cStrs, classString, NULL);
+       for(i=0; i<cStrs; i++)
+       {
+               (*jniEnv)->SetObjectArrayElement(jniEnv, strArray, i, (*jniEnv)->NewStringUTF(jniEnv, strs[i]));
+       }
+
+       return strArray;
+}
+
+int execJVM(char *appClass, char *classPath, char **argv, int argc)
+{
+       int c;
+       JNIEnv* jniEnv;
+       JavaVM* javaVM;
+       jclass classApp;
+       jmethodID midMain;
+       jobjectArray args;
+       
+       // Java VM の作成
+       c = createJVM(&jniEnv, &javaVM, classPath);
+       if(c)
+       {
+               return c;
+       }
+
+    classApp = (*jniEnv)->FindClass(jniEnv, appClass);
+    if(classApp == NULL)
+       {
+        return 8;
+    }
+
+    midMain = (*jniEnv)->GetStaticMethodID(jniEnv, classApp, "main", "([Ljava/lang/String;)V");
+    if (midMain == NULL)
+       {
+        return 9;
+    }
+       
+       // コマンドライン引数の変換
+       args = convertStringArray(jniEnv, argv, argc);
+
+       // 実行
+    (*jniEnv)->CallStaticVoidMethod(jniEnv, classApp, midMain, args);
+       
+    (*javaVM)->DestroyJavaVM(javaVM);
+       return 0;
+}
diff --git a/winjvm/jvm.h b/winjvm/jvm.h
new file mode 100755 (executable)
index 0000000..d60f411
--- /dev/null
@@ -0,0 +1,11 @@
+//
+// jvm.h
+// This file is part of PosterDivider.
+//
+
+#ifndef JVM_H
+#define JVM_H
+
+int execJVM(char *appClass, char *classPath, char **argv, int argc);
+
+#endif JVM_H
diff --git a/winjvm/posterdivider.c b/winjvm/posterdivider.c
new file mode 100755 (executable)
index 0000000..d8aa5a8
--- /dev/null
@@ -0,0 +1,135 @@
+//
+// posterdivider.c
+// This file is part of PosterDivider.
+//
+
+#include <string.h>
+#include <windows.h>
+//#include <commctrl.h>
+
+#include "jvm.h"
+
+#define APPCLASS "jp/sourceforge/posterdivider/Program"
+#define CLASSPATH "%JAVAROOT%/iText.jar;%JAVAROOT%/PosterDivider.jar"
+
+char *strreplace(char *str, char *s1, char *s2)
+{
+       int i;
+       char *p;
+       int cstr, cs1, cs2;
+       char *start[257], *end[257];
+       int count;
+       char *ret;
+       
+       cstr = strlen(str);
+       cs1 = strlen(s1);
+       cs2 = strlen(s2);
+       p = str;
+       for(i=0; i<256; i++)
+       {
+               start[i] = p;
+               p = strstr(p, s1);
+               if(p == NULL) break;
+               
+               end[i] = p;
+               p += cs1;
+       }
+       end[i] = str + cstr;
+       count = i;
+       
+       ret = malloc(sizeof(char)*(cstr+(cs2-cs1)*count+1));
+       p = ret;
+       for(i=0; i<count; i++)
+       {
+               p = strncpy(p, start[i], end[i]-start[i])+(end[i]-start[i]);
+               p = strncpy(p, s2, cs2)+cs2;
+       }
+       p = strncpy(p, start[i], end[i]-start[i])+(end[i]-start[i]);
+       *p = '\0';
+       return ret;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
+{
+       TCHAR text[1024];
+       int c, i;
+       char *p;
+       LPTSTR lpTCmdLine;
+       LPWSTR lpWCmdLine;
+       LPWSTR *lpCmdArgs;
+       int nCmdArgs;
+       char **cmdArgs;
+       char *exePath;
+       char *javaRoot;
+       char *classPath;
+       
+       // コマンドライン引数の解析
+       lpTCmdLine = GetCommandLine();
+#ifdef UNICODE
+       lpWCmdLine = lpTCmdLine;
+#else
+       c = MultiByteToWideChar(CP_ACP, 0, lpTCmdLine, -1, NULL, 0);
+       lpWCmdLine = malloc(sizeof(LPWSTR)*(c+1));
+       MultiByteToWideChar(CP_ACP, 0, lpTCmdLine, -1, lpWCmdLine, c);
+#endif
+       lpCmdArgs = CommandLineToArgvW(lpWCmdLine, &nCmdArgs);
+#ifndef UNICODE
+       free(lpWCmdLine);
+#endif
+       
+       c = WideCharToMultiByte(CP_ACP, 0, lpCmdArgs[0], -1, NULL, 0, NULL, NULL);
+       exePath = malloc(sizeof(char)*(c+10));
+       WideCharToMultiByte(CP_ACP, 0, lpCmdArgs[0], -1, exePath, c, NULL, NULL);
+       // exeパスからディレクトリ名に変換
+       p = strrchr(exePath, '\\');
+       if(p == NULL) p = exePath;
+       else p++;
+       *p = '\0';
+       javaRoot = exePath;
+       strcat(javaRoot, "Jar");
+       
+       nCmdArgs = nCmdArgs-1;
+       cmdArgs = malloc(sizeof(char*)*(nCmdArgs+1));
+       for(i=0; i<nCmdArgs; i++)
+       {
+               c = WideCharToMultiByte(CP_UTF8, 0, lpCmdArgs[i+1], -1, NULL, 0, NULL, NULL);
+               cmdArgs[i] = malloc(sizeof(char)*(c+1));
+               WideCharToMultiByte(CP_UTF8, 0, lpCmdArgs[i+1], -1, cmdArgs[i], c, NULL, NULL);
+       }
+       LocalFree(lpCmdArgs);
+       
+       classPath = strreplace(CLASSPATH, "%JAVAROOT%", javaRoot);
+       //MessageBox(NULL, classPath, NULL, MB_OK);
+       free(javaRoot);
+       
+       //InitCommonControls();
+       
+       c = execJVM(APPCLASS, classPath, cmdArgs, nCmdArgs);
+       if(c)
+       {
+               switch(c)
+               {
+                       case 1:
+                       case 2:
+                       case 3:
+                       case 4:
+                       case 5:
+                       case 6:
+                               wsprintf(text, "Java Environment Not Found (error: %d)", c);
+                               break;
+                       case 7:
+                               wsprintf(text, "Failed Create JavaVM (error: %d)", c);
+                               break;
+                       case 8:
+                       case 9:
+                               wsprintf(text, "Jar Files Not Found (error: %d)", c);
+                               break;
+                       default:
+                               wsprintf(text, "error: %d", c);
+                               break;
+               }
+               MessageBox(NULL, text, NULL, MB_OK);
+       }
+       
+       return 0;
+}