root/other-projects/expeditee-release-kits/wrapper.cpp @ 28719

Revision 28695, 13.4 KB (checked in by ak19, 7 years ago)

Expeditee team (Jeremy, jts21). Preliminary versions of the release-kits files for generating an installer containing the executable expeditee jar file. The installer is still tattoed with Greenstone and fails, but will leave a working jar behind on the file system.

Line 
1#include <windows.h>
2
3#include <fstream>
4#include <iostream>
5#include <conio.h>
6#include <string>
7#include <time.h>
8#include <shellapi.h>
9#include <direct.h>
10
11using namespace std;
12
13#ifndef CDROM
14#include "libsearch4j.h"
15#endif
16
17//globals
18HBITMAP g_splash = NULL; //the main splash bitmap
19HFONT g_hfFont = NULL; //the main splash bitmap
20char step[10] = "TMP"; //the current step
21char progress[4] = "0"; //progress in the current step
22HWND splashWnd;
23HINSTANCE mainInstance;
24int mainCmdShow;
25bool window_loaded = false;
26
27void set_splash_step( char* new_step ) {
28    strcpy( step, new_step );
29    InvalidateRect(splashWnd, NULL, FALSE);
30    UpdateWindow(splashWnd);
31}
32
33void set_splash_progress( int percent_progress ) {
34    percent_progress = ( percent_progress / 10 ) * 10;
35    char p[4] = {0};
36    strcpy( progress, itoa( percent_progress, p, 10 ) );
37    InvalidateRect(splashWnd, NULL, FALSE);
38    //RedrawWindow(splashWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_INTERNALPAINT);
39    UpdateWindow(splashWnd);
40}
41
42void spoof_progress( int interval ) {
43    int tenPercentWait = interval / 11;
44    for ( int i=0; i <= 100; i+=10 ) {
45        set_splash_progress( i );
46        Sleep( tenPercentWait );
47    }
48}
49
50//extracts a resource in chunks
51int extractResource( const char * basename, const char * type, char * file ) {
52
53    HMODULE hModule = GetModuleHandle(NULL);
54    set_splash_progress( 0 );
55
56    int no_chunks;
57    bool chunk_available = true;
58    for ( no_chunks = 0; chunk_available; no_chunks++ ) {
59
60        //construct the chunk name
61        char chunkname[127] = {0};
62        strcpy( chunkname, basename );
63        strcat( chunkname, "_" );
64        char chunknum[5] = {0};
65        itoa( no_chunks+1, chunknum, 10 );
66        strcat( chunkname, chunknum );
67       
68        if ( FindResource(hModule, chunkname, type) == NULL ) {
69            chunk_available = false;
70            break;
71        }
72    }
73   
74    if ( no_chunks == 0 ) {
75        return 1;
76    }
77   
78    for ( int i=0; i<no_chunks; i++ ) {
79   
80        //construct the chunk name
81        char chunkname[127] = {0};
82        strcpy( chunkname, basename );
83        strcat( chunkname, "_" );
84        char chunknum[5] = {0};
85        itoa( i+1, chunknum, 10 );
86        strcat( chunkname, chunknum );
87       
88        //find it
89        HRSRC hRsrc = FindResource(hModule, chunkname, type);
90        if (hRsrc == NULL ) return 1; //couldn't find the chunk
91       
92        //load it
93        HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
94        if (hGlobal == NULL) return 1; //couldn't lock
95       
96        //lock it
97        BYTE* pBytes = (BYTE*) LockResource(hGlobal);
98        if (pBytes == NULL) return 1; //couldn't lock
99       
100        //put it on disk
101        DWORD dwLength = SizeofResource(hModule, hRsrc);
102        ofstream fStream(file, ios::binary | ios::out | ios::app );
103        fStream.write((char*) pBytes, dwLength);
104        fStream.close();
105       
106        //unload
107        UnlockResource(hGlobal);
108        FreeResource(hGlobal);
109       
110        //update the progress
111        set_splash_progress( i * 100 / no_chunks );
112       
113    }
114
115    return 0;
116
117}
118
119//the splash window procedure
120LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
121    switch(msg) {
122
123        case WM_CREATE: {
124            //load in the reusable resources
125            g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
126            g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
127            if(g_splash == NULL) {
128                MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
129            }
130           
131            //center the window automatically
132            RECT rect;
133            GetWindowRect(hwnd, &rect);
134            int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
135            int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
136            SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
137        }
138       
139        case WM_PAINT: {
140            // Don't use MessageBox from inside WM_PAINT
141       
142            //load in the correct resources
143            HBITMAP g_progress = NULL;
144            HBITMAP g_step = NULL;
145            char progress_res[20] = "PROGRESS_";
146            strcat( progress_res, progress );
147            char step_res[20] = "STEP_";
148            strcat( step_res, step );
149            g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
150            g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
151            if( g_progress == NULL || g_step == NULL ) {
152                //MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
153            }
154       
155            BITMAP bm; //holds info about the width and height
156            PAINTSTRUCT ps;
157           
158            HDC hdc = BeginPaint(hwnd, &ps);
159            HDC hdcMem = CreateCompatibleDC(hdc);
160           
161            //paint the main splash screen
162            GetObject(g_splash, sizeof(bm), &bm);
163            HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
164            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
165                       
166            //paint in the progress
167            GetObject(g_progress, sizeof(bm), &bm);
168            SelectObject(hdcMem, g_progress);
169            BitBlt(hdc, 0, 270, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
170           
171            //paint in the step with transparency
172            GetObject(g_step, sizeof(bm), &bm);
173            SelectObject(hdcMem, g_step);
174            BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
175           
176            //print the step with text
177            RECT rcClient;
178            GetClientRect(hwnd, &rcClient);
179            //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
180           
181            //restore the hdc
182            SelectObject(hdcMem, hbmOld);
183           
184            //release resources
185            DeleteDC(hdcMem);
186            EndPaint(hwnd, &ps);
187            DeleteObject(g_progress);
188            DeleteObject(g_step);
189           
190        }
191        break;
192       
193        /*
194        case WM_LBUTTONDOWN: {
195            DeleteObject(g_splash);
196            PostQuitMessage(0);
197        }
198        break;
199        */
200       
201        case WM_CLOSE:
202            DestroyWindow(hwnd);
203            break;
204       
205        case WM_DESTROY:
206            DeleteObject(g_splash);
207            PostQuitMessage(0);
208            break;
209       
210        default:
211            return DefWindowProc(hwnd, msg, wParam, lParam);
212    }
213
214    return 0;
215
216}
217
218//function to process the window
219DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
220   
221    const char g_szClassName[] = "splash";
222    WNDCLASSEX wc;
223    MSG Msg;
224
225    //Step 1: Registering the Window Class
226    wc.cbSize = sizeof(WNDCLASSEX);
227    wc.style = 0;
228    wc.lpfnWndProc = WndProc;
229    wc.cbClsExtra = 0;
230    wc.cbWndExtra = 0;
231    wc.hInstance = mainInstance;
232    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
233    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
234    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
235    wc.lpszMenuName = NULL;
236    wc.lpszClassName = g_szClassName;
237    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
238    if(!RegisterClassEx(&wc)) {
239        MessageBox(NULL, "Window Registration Failed!", "Error!",
240        MB_ICONEXCLAMATION | MB_OK);
241        return 0;
242    }
243
244    // Step 2: Creating the Window
245    splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
246    if( splashWnd == NULL ) {
247        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
248        return 0;
249    }
250    ShowWindow(splashWnd, mainCmdShow);
251    UpdateWindow(splashWnd);
252
253    window_loaded = true;
254   
255    // Step 3: The Message Loop
256    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
257        TranslateMessage(&Msg);
258        DispatchMessage(&Msg);
259    }
260    return 0;
261}
262
263int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
264   
265    const int SPOOF_TIME = 1000;
266    string command = lpCmdLine;
267
268    if((command.compare("-extract") == 0) || (command.compare("--extract") == 0) || (command.compare("-x") == 0)){
269        printf("----------------------------\n");
270        printf("Extracting java installer...\n");
271        printf("----------------------------\n");
272        int result = extractResource( "JAR", "JAR", "@projectname@.jar" );
273       
274        if(result == 0){
275            printf("\n");
276            printf("Extraction complete\n");
277            printf("You can now type java -jar @projectname@.jar to run the installer from the command line\n");
278            return 0;   
279        }
280        else{
281            return 1;
282        }
283    }
284    else if(command.compare("-text") == 0 || command.compare("text") == 0 )
285    {
286        cerr << "-text is depricated, please use -extract and then run \"java -jar @projectname@.jar text\"" << endl;
287    }
288   
289    srand( time(0) );
290    mainInstance = hInstance;
291    mainCmdShow = nCmdShow;
292   
293    //start the window
294    HANDLE hThread;
295    DWORD dwThreadId, dwThrdParam = 1;
296    hThread = CreateThread(
297       NULL,                        // no security attributes
298       0,                           // use default stack size 
299       ProcessWindow,               // thread function
300       &dwThrdParam,                // argument to thread function
301       0,                           // use default creation flags
302       &dwThreadId);                // returns the thread identifier
303    if ( hThread == NULL ) {
304        return -1;
305        //ErrorExit( "CreateThread failed." );
306    }
307    CloseHandle( hThread );
308   
309    while ( !window_loaded ) {
310        Sleep( 100 );
311    }
312   
313    //create the temp folder and change to it
314    set_splash_step( "TMP" );
315    spoof_progress( SPOOF_TIME );
316   
317    //get the original working directory
318    char* owdChar = _getcwd(NULL, 1024);
319    string owd = "";
320    owd.append( owdChar );
321    free(owdChar);
322   
323    //strip trailing slash
324    if ( owd.substr(owd.length()-1,1).compare( "\\" ) == 0 ) {
325        owd = owd.substr(0, owd.length()-1);
326    }
327       
328    //using the users TMP directory for temp files rather than the current directory so
329    //installation from cdrom works
330    char* tmp = getenv( "TMP" );
331    char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
332    string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\@projectname@-" ); tempdir.append( id );
333    const char* tmpdir = tempdir.c_str();
334    if ( _mkdir( tmpdir ) != 0 ) {
335        string title = "Failed to create the temp folder.";
336        string message = "Failed to create the temp folder.\nPlease set the environment variable TMP to a folder you have permission to write to.";
337        //ShowWindow(splashWnd, SW_HIDE); //hide splash screen
338        MessageBox(splashWnd, message.c_str(), title.c_str(), MB_OK);
339        return -1;
340    }
341    //SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
342    SetCurrentDirectory(tmpdir);
343    // delete tmp; //  should be tmpdir? ??? (deallocate memory)
344   
345    #ifdef CDROM
346
347    //ask if they want to install, then do it if so
348    int choice = MessageBox(splashWnd, "Install @projectname@?", "@projectname@", MB_OKCANCEL | MB_ICONQUESTION );
349    if ( choice == IDOK ) {
350
351        //prepare to launch the jar
352        set_splash_step( "LAUNCHING" );
353        spoof_progress( SPOOF_TIME );
354   
355        string cmd = "\"";
356        cmd.append( owd );
357        cmd.append( "\\Java\\Windows\\jre\\bin\\java.exe\" \"-Dorig.dir=" );
358        cmd.append( owd );
359        cmd.append( "\" -jar \"" );
360        cmd.append( owd );
361        cmd.append( "\\Java\\Jars\\windows.jar\"" );
362        char cmdLpstr[1024];
363        strcpy( cmdLpstr, cmd.c_str() );
364       
365       
366        STARTUPINFO si;
367        PROCESS_INFORMATION pi;
368        memset(&pi, 0, sizeof(pi));
369        memset(&si, 0, sizeof(si));
370        si.cb = sizeof(si);
371        DWORD dwExitCode = -1;
372
373        //hide splash screen
374        ShowWindow(splashWnd, SW_HIDE);
375
376        //launch the jar
377        bool result;
378        result = CreateProcess(NULL, cmdLpstr, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
379
380        WaitForSingleObject(pi.hProcess, INFINITE);
381        GetExitCodeProcess(pi.hProcess, &dwExitCode);
382        CloseHandle(pi.hThread);
383        CloseHandle(pi.hProcess);
384
385    }   
386    #else
387
388    //rip out java archive if it is bundled
389    set_splash_step( "XJAVA" );
390    int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
391    if ( javaIsBundled ) {
392        process( "@java.installer@", false );
393    }
394
395    //find java
396    set_splash_step( "SEARCHING" );
397    spoof_progress( SPOOF_TIME );
398    bool use_minimum = true;
399    Jvm minimum;
400    minimum.setVersionFromString( "@java.min.version@" );
401    string phint = "@java.extracted@";
402    string hint = "";
403    bool verbose = true;
404    Jvm foundJvm;
405    bool jvmFound = find( foundJvm, use_minimum, minimum, false, false, phint, hint, verbose );
406   
407    //if the jvm was not found, try to fix it and find it
408    if ( !jvmFound ) {
409
410        //did not find a good java
411        string message = "This version of @projectname@ requires java @java.min.version@ or greater, but ";
412       
413        //tell them if java is absent or just too old
414        if ( find( foundJvm, false, minimum, false, false, "", "", false ) ) {
415            message.append( "your java is too old.");
416        } else {
417            message.append( "java could not be found on your computer." );
418        }
419        message.append( "\n" );
420       
421        string title = "Installation Failed: Couldn't find java";
422        //ShowWindow(splashWnd, SW_HIDE); //hide splash screen
423        MessageBox(splashWnd, message.c_str(), title.c_str(), MB_OK);
424
425    //if java was found, carry on
426    } else {
427
428        //extract the jar
429        string jarLocation = "@projectname@.jar";
430       
431        set_splash_step( "XJAR" );
432        extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
433
434        //launch the jar
435        set_splash_step( "LAUNCHING" );
436        spoof_progress( SPOOF_TIME );
437        string cmd = "\"";
438        cmd.append( foundJvm.getWinExecutable() );
439        cmd.append( "\" \"-Dorig.dir=" );
440        cmd.append( owd );
441        cmd.append( "\" -jar @projectname@.jar" );
442       
443       
444        //hide splash screen
445        ShowWindow(splashWnd, SW_HIDE);
446       
447        //run the jar
448        int launch_exit_code = process( cmd, true );
449       
450        //report how it went
451        if ( launch_exit_code != 0 ) {
452            string title = "Installation Error";
453            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.";
454            //ShowWindow(splashWnd, SW_HIDE); //hide splash screen
455            MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
456        }
457    }
458    #endif
459   
460    //clean up the temp directory
461    _unlink( "ant.install.log" );
462    #ifndef CDROM
463    _unlink( "@projectname@.jar" );
464    _unlink( "@java.installer@" );
465    process( "cmd.exe /c rd /s /q @java.extracted@", false );
466    #endif
467
468    SetCurrentDirectory( ".." );
469    _rmdir( tempdir.c_str() );
470   
471    return 0;
472   
473}
Note: See TracBrowser for help on using the browser.