source: release-kits/shared/windows/wrapper/wrapper.cpp@ 16203

Last change on this file since 16203 was 16203, checked in by oranfry, 16 years ago

made the wrapper general, so it can be used with greenstone2 or greenstone3 release kits

File size: 11.2 KB
RevLine 
[15023]1#include <windows.h>
2
3#include <fstream>
4#include <iostream>
[15095]5#include <conio.h>
6#include <string>
7#include <time.h>
[15689]8#include <shellapi.h>
9#include <direct.h>
10#include "libsearch4j.h"
[15023]11
12using namespace std;
13
[15689]14//globals
15HBITMAP g_splash = NULL; //the main splash bitmap
[16079]16HFONT g_hfFont = NULL; //the main splash bitmap
[15689]17char step[10] = "TMP"; //the current step
18char progress[4] = "0"; //progress in the current step
19HWND splashWnd;
20HINSTANCE mainInstance;
21int mainCmdShow;
22bool window_loaded = false;
[15023]23
[15689]24void set_splash_step( char* new_step ) {
25 strcpy( step, new_step );
26 InvalidateRect(splashWnd, NULL, FALSE);
27 UpdateWindow(splashWnd);
[15023]28}
29
[15689]30void set_splash_progress( int percent_progress ) {
31 percent_progress = ( percent_progress / 10 ) * 10;
32 char p[4] = {0};
33 strcpy( progress, itoa( percent_progress, p, 10 ) );
34 InvalidateRect(splashWnd, NULL, FALSE);
35 //RedrawWindow(splashWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_INTERNALPAINT);
36 UpdateWindow(splashWnd);
37}
[15023]38
[15689]39void spoof_progress( int interval ) {
40 int tenPercentWait = interval / 11;
41 for ( int i=0; i <= 100; i+=10 ) {
42 set_splash_progress( i );
43 Sleep( tenPercentWait );
44 }
45}
46
47//extracts a resource in chunks
[16079]48int extractResource( const char * basename, const char * type, char * file ) {
[15689]49
[15023]50 HMODULE hModule = GetModuleHandle(NULL);
[15689]51 set_splash_progress( 0 );
[15023]52
[16079]53 int no_chunks;
54 bool chunk_available = true;
55 for ( no_chunks = 0; chunk_available; no_chunks++ ) {
[15023]56
[15689]57 //construct the chunk name
58 char chunkname[127] = {0};
59 strcpy( chunkname, basename );
60 strcat( chunkname, "_" );
61 char chunknum[5] = {0};
[16079]62 itoa( no_chunks+1, chunknum, 10 );
63 strcat( chunkname, chunknum );
64
65 if ( FindResource(hModule, chunkname, type) == NULL ) {
66 chunk_available = false;
67 }
68 }
69
70 for ( int i=0; i<no_chunks; i++ ) {
71
72 //construct the chunk name
73 char chunkname[127] = {0};
74 strcpy( chunkname, basename );
75 strcat( chunkname, "_" );
76 char chunknum[5] = {0};
[15689]77 itoa( i+1, chunknum, 10 );
78 strcat( chunkname, chunknum );
79
[16079]80 //find it
[15689]81 HRSRC hRsrc = FindResource(hModule, chunkname, type);
[16079]82 if (hRsrc == NULL ) return 1; //couldn't find the chunk
[15689]83
84 //load it
85 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
86 if (hGlobal == NULL) return 1; //couldn't lock
[16079]87
88 //lock it
[15689]89 BYTE* pBytes = (BYTE*) LockResource(hGlobal);
90 if (pBytes == NULL) return 1; //couldn't lock
91
92 //put it on disk
93 DWORD dwLength = SizeofResource(hModule, hRsrc);
94 ofstream fStream(file, ios::binary | ios::out | ios::app );
95 fStream.write((char*) pBytes, dwLength);
96 fStream.close();
97
98 //unload
99 UnlockResource(hGlobal);
100 FreeResource(hGlobal);
101
102 //update the progress
103 set_splash_progress( i * 100 / no_chunks );
104
105 }
[15023]106
107 return 0;
108
109}
110
[15689]111//the splash window procedure
112LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
113 switch(msg) {
114
115 case WM_CREATE: {
116 //load in the reusable resources
117 g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
[16079]118 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
[15689]119 if(g_splash == NULL) {
120 MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
121 }
122
123 //center the window automatically
124 RECT rect;
125 GetWindowRect(hwnd, &rect);
126 int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
127 int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
128 SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
129 }
130
131 case WM_PAINT: {
132 // Don't use MessageBox from inside WM_PAINT
133
134 //load in the correct resources
135 HBITMAP g_progress = NULL;
136 HBITMAP g_step = NULL;
137 char progress_res[20] = "PROGRESS_";
138 strcat( progress_res, progress );
139 char step_res[20] = "STEP_";
140 strcat( step_res, step );
141 g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
142 g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
143 if( g_progress == NULL || g_step == NULL ) {
144 MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
145 }
146
147 BITMAP bm; //holds info about the width and height
148 PAINTSTRUCT ps;
149
150 HDC hdc = BeginPaint(hwnd, &ps);
151 HDC hdcMem = CreateCompatibleDC(hdc);
152
153 //paint the main splash screen
154 GetObject(g_splash, sizeof(bm), &bm);
155 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
156 BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
157
158 //paint in the progress
159 GetObject(g_progress, sizeof(bm), &bm);
160 SelectObject(hdcMem, g_progress);
161 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
162
163 //paint in the step with transparency
164 GetObject(g_step, sizeof(bm), &bm);
165 SelectObject(hdcMem, g_step);
166 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
167
[16079]168 //print the step with text
169 RECT rcClient;
170 GetClientRect(hwnd, &rcClient);
171 //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
172
[15689]173 //restore the hdc
174 SelectObject(hdcMem, hbmOld);
175
176 //release resources
177 DeleteDC(hdcMem);
178 EndPaint(hwnd, &ps);
179 DeleteObject(g_progress);
180 DeleteObject(g_step);
181
182 }
183 break;
184
[15813]185 /*
[15689]186 case WM_LBUTTONDOWN: {
187 DeleteObject(g_splash);
188 PostQuitMessage(0);
189 }
190 break;
[15813]191 */
[15689]192
193 case WM_CLOSE:
194 DestroyWindow(hwnd);
195 break;
196
197 case WM_DESTROY:
198 DeleteObject(g_splash);
199 PostQuitMessage(0);
200 break;
201
202 default:
203 return DefWindowProc(hwnd, msg, wParam, lParam);
204 }
205
206 return 0;
207
[15095]208}
209
[15689]210//function to process the window
211DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
212
213 const char g_szClassName[] = "splash";
214 WNDCLASSEX wc;
215 MSG Msg;
[15095]216
[15689]217 //Step 1: Registering the Window Class
218 wc.cbSize = sizeof(WNDCLASSEX);
219 wc.style = 0;
220 wc.lpfnWndProc = WndProc;
221 wc.cbClsExtra = 0;
222 wc.cbWndExtra = 0;
223 wc.hInstance = mainInstance;
224 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
225 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
226 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
227 wc.lpszMenuName = NULL;
228 wc.lpszClassName = g_szClassName;
229 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
230 if(!RegisterClassEx(&wc)) {
231 MessageBox(NULL, "Window Registration Failed!", "Error!",
232 MB_ICONEXCLAMATION | MB_OK);
233 return 0;
234 }
[15095]235
[15689]236 // Step 2: Creating the Window
237 splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
238 if( splashWnd == NULL ) {
239 MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
240 return 0;
241 }
242 ShowWindow(splashWnd, mainCmdShow);
243 UpdateWindow(splashWnd);
244
245 window_loaded = true;
[15023]246
[15689]247 // Step 3: The Message Loop
248 while(GetMessage(&Msg, NULL, 0, 0) > 0) {
249 TranslateMessage(&Msg);
250 DispatchMessage(&Msg);
251 }
252 return 0;
253}
254
255int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
[15023]256
[15689]257 const int SPOOF_TIME = 1000;
258 string command;
259 srand( time(0) );
260 mainInstance = hInstance;
261 mainCmdShow = nCmdShow;
[15095]262
[15689]263 //start the window
264 HANDLE hThread;
265 DWORD dwThreadId, dwThrdParam = 1;
266 hThread = CreateThread(
267 NULL, // no security attributes
268 0, // use default stack size
269 ProcessWindow, // thread function
270 &dwThrdParam, // argument to thread function
271 0, // use default creation flags
272 &dwThreadId); // returns the thread identifier
273 if ( hThread == NULL ) {
274 return -1;
275 //ErrorExit( "CreateThread failed." );
276 }
277 CloseHandle( hThread );
278
279 while ( !window_loaded ) {
280 Sleep( 100 );
281 }
282
283 //create the temp folder and change to it
284 set_splash_step( "TMP" );
285 spoof_progress( SPOOF_TIME );
286 char* tmp = getenv( "TMP" );
287 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
[16203]288 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
[15689]289 _mkdir( tempdir.c_str() );
[15095]290 SetCurrentDirectory( tempdir.c_str() );
291
[15689]292 //find java
293 //set_splash_status( hInstance, statusWnd, "STATUS_SEARCHING4J", 1000 );
294 set_splash_step( "SEARCHING" );
295 spoof_progress( SPOOF_TIME );
296 bool use_minimum = true;
297 Jvm minimum;
298 minimum.setVersionFromString( "@java.min.version@" );
299 string hint = "";
300 bool verbose = true;
301 Jvm foundJvm;
302 bool jvmFound = find( foundJvm, use_minimum, minimum, hint, verbose );
303
[15095]304 //if the jvm was not found, try to fix it and find it
305 if ( !jvmFound ) {
[15689]306
[15095]307 //did not find a good java
[16203]308 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
[15023]309
[15095]310 //tell them if java is absent or just too old
[15689]311 if ( find( foundJvm, false, minimum, "", false ) ) {
312 message.append( "your java is too old.");
[15095]313 } else {
[15689]314 message.append( "java could not be found on your computer." );
[15095]315 }
[15689]316 message.append( "\n\n" );
[15095]317
[15023]318 //is this an installer with the bundled JRE?
[15689]319 set_splash_step( "XJAVA" );
[16079]320 int extract_result = extractResource( "JAVA", "EXE", "@java.installer@" );
[15689]321
[15023]322 if ( extract_result == 0 ) {
[15689]323
[15023]324 //yes, JRE is bundled
[15689]325 message.append( "This installer is bundled with a suitible version of java (bundled.version.java)\n");
326 message.append( "The installer program for this java will now be launched.\n" );
327 string title = "Must install java first";
328 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
329 ShellExecute(NULL, "open", "@java.installer@", NULL, NULL, SW_SHOWNORMAL);
330 jvmFound = true; //assume the java installation went well
331
[15023]332 } else {
[15689]333
[15023]334 //no, JRE is not bundled
[15689]335 set_splash_step( "SEARCHING" );
336 set_splash_progress( 100 ); //we are done searching
337 message.append( "Please install java (@java.min.version@ or newer) and try again.\n" );
[16203]338 message.append( "Or, download an installer with bundled java and use that instead of this one" );
[15689]339 string title = "Installation Failed: Couldn't find java";
340 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
[15095]341 }
342 }
343
[15689]344
[15095]345 //if we have found it by now, launch the installer
346 if ( jvmFound ) {
[15689]347
348 //extract the jar
[16203]349 string jarLocation = ""; jarLocation.append( tempdir ); jarLocation.append( "\\greenstone.jar" );
[15689]350 //set_splash_status( hInstance, statusWnd, "STATUS_JAR", 0 );
[15023]351
[15689]352 set_splash_step( "XJAR" );
[16079]353 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
[15689]354
355 //launch the jar
356 set_splash_step( "LAUNCHING" );
357 spoof_progress( SPOOF_TIME );
358 string cmd = "\"";
359 cmd.append( foundJvm.getWinExecutable() );
[16203]360 cmd.append( "\" -jar greenstone.jar" );
[15689]361
362 //hide splash screen
363 ShowWindow(splashWnd, SW_HIDE);
364
365 //run the jar
366 int launch_exit_code = process( cmd, true );
367
[15146]368 //report how it went
[15689]369 if ( launch_exit_code != 0 ) {
370 string title = "Installation Error";
371 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.";
372 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
[15023]373 }
374 }
[15025]375
[15689]376 //clean up the temp directory
[16203]377 _unlink("greenstone.jar");
[15689]378 _unlink("ant.install.log");
379 _unlink("@java.installer@");
[15023]380 SetCurrentDirectory("..");
[15689]381 _rmdir( tempdir.c_str() );
[15095]382
[15689]383 return 0;
[15023]384
[15095]385}
Note: See TracBrowser for help on using the repository browser.