source: release-kits/wirk3/wrapper/wrapper.cpp@ 15813

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

modification to installer exe wrapper: dont hide the splash screen on click

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