source: other-projects/expeditee-release-kits/windows_wrapper.cpp@ 28715

Last change on this file since 28715 was 28695, checked in by ak19, 10 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.

File size: 13.4 KB
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", "@[email protected]" );
273
274 if(result == 0){
275 printf("\n");
276 printf("Extraction complete\n");
277 printf("You can now type java -jar @[email protected] 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 @[email protected] 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 = "@[email protected]";
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 @[email protected]" );
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( "@[email protected]" );
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 repository browser.