#include #include #include #include #include #include #include #include using namespace std; #ifndef CDROM #include "libsearch4j.h" #endif //globals HBITMAP g_splash = NULL; //the main splash bitmap HFONT g_hfFont = NULL; //the main splash bitmap char step[10] = "TMP"; //the current step char progress[4] = "0"; //progress in the current step HWND splashWnd; HINSTANCE mainInstance; int mainCmdShow; bool window_loaded = false; void set_splash_step( char* new_step ) { strcpy( step, new_step ); InvalidateRect(splashWnd, NULL, FALSE); UpdateWindow(splashWnd); } void set_splash_progress( int percent_progress ) { percent_progress = ( percent_progress / 10 ) * 10; char p[4] = {0}; strcpy( progress, itoa( percent_progress, p, 10 ) ); InvalidateRect(splashWnd, NULL, FALSE); //RedrawWindow(splashWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_INTERNALPAINT); UpdateWindow(splashWnd); } void spoof_progress( int interval ) { int tenPercentWait = interval / 11; for ( int i=0; i <= 100; i+=10 ) { set_splash_progress( i ); Sleep( tenPercentWait ); } } //extracts a resource in chunks int extractResource( const char * basename, const char * type, char * file ) { HMODULE hModule = GetModuleHandle(NULL); set_splash_progress( 0 ); int no_chunks; bool chunk_available = true; for ( no_chunks = 0; chunk_available; no_chunks++ ) { //construct the chunk name char chunkname[127] = {0}; strcpy( chunkname, basename ); strcat( chunkname, "_" ); char chunknum[5] = {0}; itoa( no_chunks+1, chunknum, 10 ); strcat( chunkname, chunknum ); if ( FindResource(hModule, chunkname, type) == NULL ) { chunk_available = false; break; } } if ( no_chunks == 0 ) { return 1; } for ( int i=0; i 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return 0; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { const int SPOOF_TIME = 1000; string command = lpCmdLine; if((command.compare("-extract") == 0) || (command.compare("--extract") == 0) || (command.compare("-x") == 0)){ printf("----------------------------\n"); printf("Extracting java installer...\n"); printf("----------------------------\n"); int result = extractResource( "JAR", "JAR", "@projectname@.jar" ); if(result == 0){ printf("\n"); printf("Extraction complete\n"); printf("You can now type java -jar @projectname@.jar to run the installer from the command line\n"); return 0; } else{ return 1; } } else if(command.compare("-text") == 0 || command.compare("text") == 0 ) { cerr << "-text is depricated, please use -extract and then run \"java -jar @projectname@.jar text\"" << endl; } srand( time(0) ); mainInstance = hInstance; mainCmdShow = nCmdShow; //start the window HANDLE hThread; DWORD dwThreadId, dwThrdParam = 1; hThread = CreateThread( NULL, // no security attributes 0, // use default stack size ProcessWindow, // thread function &dwThrdParam, // argument to thread function 0, // use default creation flags &dwThreadId); // returns the thread identifier if ( hThread == NULL ) { return -1; //ErrorExit( "CreateThread failed." ); } CloseHandle( hThread ); while ( !window_loaded ) { Sleep( 100 ); } //create the temp folder and change to it set_splash_step( "TMP" ); spoof_progress( SPOOF_TIME ); //get the original working directory char* owdChar = _getcwd(NULL, 1024); string owd = ""; owd.append( owdChar ); free(owdChar); //strip trailing slash if ( owd.substr(owd.length()-1,1).compare( "\\" ) == 0 ) { owd = owd.substr(0, owd.length()-1); } //using the users TMP directory for temp files rather than the current directory so //installation from cdrom works char* tmp = getenv( "TMP" ); char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\@projectname@-" ); tempdir.append( id ); const char* tmpdir = tempdir.c_str(); if ( _mkdir( tmpdir ) != 0 ) { string title = "Failed to create the temp folder."; string message = "Failed to create the temp folder.\nPlease set the environment variable TMP to a folder you have permission to write to."; //ShowWindow(splashWnd, SW_HIDE); //hide splash screen MessageBox(splashWnd, message.c_str(), title.c_str(), MB_OK); return -1; } //SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN); SetCurrentDirectory(tmpdir); // delete tmp; // should be tmpdir? ??? (deallocate memory) #ifdef CDROM //ask if they want to install, then do it if so int choice = MessageBox(splashWnd, "Install @projectname@?", "@projectname@", MB_OKCANCEL | MB_ICONQUESTION ); if ( choice == IDOK ) { //prepare to launch the jar set_splash_step( "LAUNCHING" ); spoof_progress( SPOOF_TIME ); string cmd = "\""; cmd.append( owd ); cmd.append( "\\Java\\Windows\\jre\\bin\\java.exe\" \"-Dorig.dir=" ); cmd.append( owd ); cmd.append( "\" -jar \"" ); cmd.append( owd ); cmd.append( "\\Java\\Jars\\windows.jar\"" ); char cmdLpstr[1024]; strcpy( cmdLpstr, cmd.c_str() ); STARTUPINFO si; PROCESS_INFORMATION pi; memset(&pi, 0, sizeof(pi)); memset(&si, 0, sizeof(si)); si.cb = sizeof(si); DWORD dwExitCode = -1; //hide splash screen ShowWindow(splashWnd, SW_HIDE); //launch the jar bool result; result = CreateProcess(NULL, cmdLpstr, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &dwExitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } #else //rip out java archive if it is bundled set_splash_step( "XJAVA" ); int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0); if ( javaIsBundled ) { process( "@java.installer@", false ); } //find java set_splash_step( "SEARCHING" ); spoof_progress( SPOOF_TIME ); bool use_minimum = true; Jvm minimum; minimum.setVersionFromString( "@java.min.version@" ); string phint = "@java.extracted@"; string hint = ""; bool verbose = true; Jvm foundJvm; bool jvmFound = find( foundJvm, use_minimum, minimum, false, false, phint, hint, verbose ); //if the jvm was not found, try to fix it and find it if ( !jvmFound ) { //did not find a good java string message = "This version of @projectname@ requires java @java.min.version@ or greater, but "; //tell them if java is absent or just too old if ( find( foundJvm, false, minimum, false, false, "", "", false ) ) { message.append( "your java is too old."); } else { message.append( "java could not be found on your computer." ); } message.append( "\n" ); string title = "Installation Failed: Couldn't find java"; //ShowWindow(splashWnd, SW_HIDE); //hide splash screen MessageBox(splashWnd, message.c_str(), title.c_str(), MB_OK); //if java was found, carry on } else { //extract the jar string jarLocation = "@projectname@.jar"; set_splash_step( "XJAR" ); extractResource( "JAR", "JAR", (char*) jarLocation.c_str() ); //launch the jar set_splash_step( "LAUNCHING" ); spoof_progress( SPOOF_TIME ); string cmd = "\""; cmd.append( foundJvm.getWinExecutable() ); cmd.append( "\" \"-Dorig.dir=" ); cmd.append( owd ); cmd.append( "\" -jar @projectname@.jar" ); //hide splash screen ShowWindow(splashWnd, SW_HIDE); //run the jar int launch_exit_code = process( cmd, true ); //report how it went if ( launch_exit_code != 0 ) { string title = "Installation Error"; string message = "The installation exited with an error. Java may not be installed properly, or the installation may have been interrupted partway through. Please try again."; //ShowWindow(splashWnd, SW_HIDE); //hide splash screen MessageBox(NULL, message.c_str(), title.c_str(), MB_OK); } } #endif //clean up the temp directory _unlink( "ant.install.log" ); #ifndef CDROM _unlink( "@projectname@.jar" ); _unlink( "@java.installer@" ); process( "cmd.exe /c rd /s /q @java.extracted@", false ); #endif SetCurrentDirectory( ".." ); _rmdir( tempdir.c_str() ); return 0; }