2 static define buildString = $"Ecere SDK v0.44.10 (Without MinGW) -- built on March 2nd, 2014 ";
4 static define buildString = $"Ecere SDK v0.44.10 -- built on March 2nd, 2014 ";
7 #define WIN32_LEAN_AND_MEAN
8 #define GetFreeSpace _GetFreeSpace
22 static bool IsAdministrator()
25 SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
26 PSID AdministratorsGroup;
27 b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);
30 if(!CheckTokenMembership(NULL, AdministratorsGroup, &b))
32 FreeSid(AdministratorsGroup);
42 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
46 strcpy(tempString, name);
47 strcat(tempString, " (32)");
53 void OnDisplay(Surface surface, int x, int y, int width, void * fieldData, Alignment alignment, DataDisplayFlags displayFlags)
55 if(!displayFlags.active) { displayFlags.current = false; displayFlags.selected = false; }
56 class::OnDisplay(surface, x + 22, y, width - 22, fieldData, alignment, displayFlags);
60 //#define BUFFERSIZE 0x10000
61 #define BUFFERSIZE 0x1000
62 bool abortInstall = false;
64 void ExtractFileFromArchive(ProgressBar progressBar, char * path, char * outputFile)
66 char fileName[MAX_LOCATION];
67 FileAttribs exists = FileExists(path);
71 if(exists.isDirectory)
73 FileListing listing { path };
77 if(MakeDir(outputFile))
80 FileGetStats(path, &stats);
84 while(listing.Find() && !abortInstall)
86 strcpy(fileName, outputFile);
88 // Tweak file name if out
91 if(!strcmp(fileName, ".")) fileName[0] = '\0';
92 if(listing.name[0] == '/' || listing.name[0] == '\\')
94 char * afterSlash, rest[MAX_LOCATION];
95 for(afterSlash = fileName; *afterSlash == '/' || *afterSlash == '\\'; afterSlash++);
96 strcpy(rest, afterSlash);
97 PathCat(fileName, "_root");
98 PathCat(fileName, rest);
100 else if(listing.name[1] == ':')
103 sprintf(letter, "_%cdrive", toupper(listing.name[0]));
104 PathCat(fileName, letter);
105 PathCat(fileName, listing.name[2] ? (listing.name + 3) : (listing.name + 2));
108 PathCat(fileName, listing.name);
111 PathCat(fileName, listing.name);
112 if(!strcmp(fileName, "/") || !strcmp(fileName, "\\"))
113 strcpy(fileName, DIR_SEPS);
114 ExtractFileFromArchive(progressBar, listing.path, fileName);
120 File input = FileOpen(path, read);
123 File output = FileOpen(outputFile, write);
126 char fileName[MAX_FILENAME];
127 uint position = progressBar.progress;
130 byte buffer[BUFFERSIZE];
132 FileGetSize(path, &dataSize);
133 GetLastDirectory(outputFile, fileName);
135 ((GuiApplication)__thisModule).SignalEvent();
136 //((GuiApplication)__thisModule).ProcessInput();
137 //((GuiApplication)__thisModule).UpdateDisplay();
139 for(c = 0; c<dataSize && !abortInstall; c += BUFFERSIZE)
141 uint size = (dataSize > c + BUFFERSIZE) ? BUFFERSIZE : (dataSize - c);
143 ((GuiApplication)__thisModule).Unlock();
145 input.Read(buffer, 1, size);
146 output.Write(buffer, 1, size);
148 ((GuiApplication)__thisModule).Lock();
150 progressBar.progress = position + c + size;
151 ((GuiApplication)__thisModule).SignalEvent();
153 //((GuiApplication)__thisModule).ProcessInput();
154 //((GuiApplication)__thisModule).UpdateDisplay();
159 FileGetStats(path, &stats);
165 FileSetTime(outputFile, stats.created, 0, stats.modified);
168 public enum BitArch { none, bits32, bits64 };
174 char * defInstallPath;
175 Component * subComponents;
185 char installPath[MAX_LOCATION];
188 void GetFullPath(char * path, bool is32bit)
190 if(this != null && parent)
191 parent->GetFullPath(path, is32bit || (arch == bits32 && osIS64bit));
193 strcpy(path, (this && (is32bit || (arch == bits32 && osIS64bit))) ? installDir32 : installDir);
196 PathCat(path, installPath);
199 void Install(char * parentPath, char * parentPath32)
202 if(selected && (arch == none || arch == bits32 || osIS64bit))
204 char path64[MAX_LOCATION];
205 char path32[MAX_LOCATION];
206 strcpy(path64, parentPath);
207 PathCat(path64, installPath);
209 strcpy(path32, parentPath32);
210 PathCat(path32, installPath);
212 installProgress.installing.SetText($"Installing %s...", name);
213 ((GuiApplication)__thisModule).UpdateDisplay();
217 char * path = path64;
218 char source[MAX_LOCATION];
220 strcat(source, dataPath);
227 if(FileExists(source).isFile)
229 char name[MAX_FILENAME];
230 GetLastDirectory(source, name);
235 uint p = installProgress.progressBar.progress;
236 ExtractFileFromArchive(installProgress.progressBar, source, path);
241 for(c = 0; subComponents[c].name; c++)
242 subComponents[c].Install(path64, path32);
249 define minGWIncluded = true;
251 define minGWIncluded = false;
254 Array<Component> samples
256 { "Ecere Chess", "samples/chess", "chess", null, false, true, true, none },
257 { "Ecere Fractals", "samples/fractals", "fractals", null, false, true, true, none },
258 { "3D", "samples/3D", "3D", null, false, true, true, none },
259 { "Android", "samples/android", "android", null, false, true, true, none },
260 { $"Audio", "samples/audio", "audio", null, false, true, true, none },
261 { $"Database", "samples/db", "db", null, false, true, true, none },
262 { "eC", "samples/eC", "eC", null, false, true, true, none },
263 { $"Games", "samples/games", "games", null, false, true, true, none },
264 { $"GUI & Graphics", "samples/guiAndGfx", "guiAndGfx", null, false, true, true, none },
265 { $"Miscellaneous", "samples/misc", "misc", null, false, true, true, none },
266 { $"Networking", "samples/net", "net", null, false, true, true, none },
267 { $"WIA Scanning", "samples/scanning", "scanning", null, false, true, true, none },
268 { $"Threading", "samples/threads", "threads", null, false, true, true, none },
272 public enum CoreSDKID
274 ide, ide32, runtime, runtime32, ec, ec32,
275 gcc, gdb, mingw, binutils, make,
279 Array<Component> coreSDK
281 { "Ecere IDE", "ecere-sdk/ide", "bin", null, true, true, true, bits64 },
282 { "Ecere IDE", "ecere-sdk32/ide", "bin", null, true, true, true, bits32 },
283 { $"Runtime Library", "ecere-sdk/ecere.dll", "bin", null, true, true, true, bits64 },
284 { $"Runtime Library", "ecere-sdk32/ecere.dll", "bin", null, true, true, true, bits32 },
285 { $"eC Compiler", "ecere-sdk/compiler", "bin", null, true, true, true, bits64 },
286 { $"eC Compiler", "ecere-sdk32/compiler", "bin", null, true, true, true, bits32 },
287 { $"GNU C Compiler", "tdm/gcc/core", "tdm", null, true, true, minGWIncluded, none },
288 { $"GNU Debugger", "tdm/gdb", "tdm", null, true, true, minGWIncluded, none },
289 { $"MinGW-w64 Runtime", "tdm/mingwrt", "tdm", null, true, true, minGWIncluded, none },
290 { $"Binary Utils", "tdm/binutils", "tdm", null, true, true, minGWIncluded, none },
291 { $"GNU Make", "tdm/make", "tdm", null, true, true, minGWIncluded, none },
295 public enum AdditionalID
297 eda, eda32, vanilla, vanilla32, extras, upx, gnurx, gnurx32, /*pthreads, */cpp, /*w32api, gcci18n, gdbi18n, makei18n, binutilsi18n, */none
300 Array<Component> additional
302 { $"Data Access", "ecere-sdk/eda", "bin", null, false, true, true, bits64 },
303 { $"Data Access", "ecere-sdk32/eda", "bin", null, false, true, true, bits32 },
304 { $"Ecere Vanilla", "ecere-sdk/libecereVanilla.a", "lib", null, false, true, true, bits64 },
305 { $"Ecere Vanilla", "ecere-sdk32/libecereVanilla.a", "lib", null, false, true, true, bits32 },
306 { $"Ecere Extras", "extras", "extras", null, false, true, true, none },
307 { "UPX", "upx/bin", "upx/bin", null, false, true, true, none },
308 { $"GNU Regexp", "tdm/gnurx", "tdm", null, false, true, true, bits64 },
309 { $"GNU Regexp", "tdm/gnurx32", "tdm", null, false, true, true, bits32 },
310 // { "pthreads", "tdm/pthreads", "mingw", null, false, true, minGWIncluded, none },
311 { $"C++ Compiler", "tdm/gcc/c++", "tdm", null, false, true, minGWIncluded, none },
312 // { "Win32 APIs", "mingw/w32api", "mingw", null, false, true, minGWIncluded, none },
313 /* { "GCC I18n", "mingw/locale/gcc", "tdm", null, false, false, minGWIncluded, none },
314 { "GDB I18n", "mingw/locale/gdb", "tdm", null, false, false, minGWIncluded, none },
315 { "Make I18n", "mingw/locale/make", "tdm", null, false, false, minGWIncluded, none },
316 { "Binutils I18n", "mingw/locale/binutils", "tdm", null, false, false, minGWIncluded, none },
321 public enum DocumentationID
323 ecereBook, apiRef, tutorials, coursework,
324 gccDoc, gppDocs, gdbDocs, makeDocs, binDocs, mingwDocs, gnurxDocs, upxDocs,
328 Array<Component> documentation
330 { $"Ecere Book", "ecere-sdk/book", "doc", null, false, true, true, none },
331 { $"API Reference", "ecere-sdk/doc", "doc", null, false, true, true, none },
332 { $"Ecere Tutorials", "ecere-sdk/tutorials", "doc", null, false, true, true, none },
333 { $"Ecere Coursework", "ecere-sdk/coursework", "doc", null, false, true, true, none },
334 { $"GCC Docs", "tdm/doc/gcc", "tdm", null, false, false, minGWIncluded, none },
335 { $"G++ Docs", "tdm/doc/g++", "tdm", null, false, false, minGWIncluded, none },
336 { $"GDB Docs", "tdm/doc/gdb", "tdm", null, false, false, minGWIncluded, none },
337 { $"Make Docs", "tdm/doc/make", "tdm", null, false, false, minGWIncluded, none },
338 { $"Binutils Docs", "tdm/doc/binutils", "tdm", null, false, false, minGWIncluded, none },
339 { $"gnurx Docs", "tdm/doc/gnurx", "tdm", null, false, false, minGWIncluded, none },
340 { $"UPX Docs", "upx/doc", "upx/doc", null, false, false, minGWIncluded, none },
344 public enum ComponentID
353 Array<Component> components
355 { $"Core SDK Files", null, null, coreSDK.array, true, true, true, none },
356 { $"Additional Support", null, null, additional.array, false, true, true, none },
357 { $"Documentation", null /*"doc"*/, null /*"doc"*/, documentation.array, false, true, true, none },
358 { $"Samples", null, "samples", samples.array, false, true, true, none },
362 FileSize totalInstalled;
367 InstallOption * subOptions;
373 enum AssociateOptions
384 Array<InstallOption> associateOptions
386 { $"Associate with Ecere Project Files (*.epj)", null, true },
387 { $"Associate with eC Files (*.ec, *.eh)", null, true },
388 { $"Associate with C files (*.c, *.h)", null, false },
389 { $"Associate with C++ Files (*.cpp, *.hpp, *.cc, *.hh, *.cxx, *.hxx)", null, false },
390 { $"Associate with text files (*.txt)", null, false },
391 { $"Associate with 3D Studio Model Files (*.3ds)", null, true },
392 { $"Associate with Image Files (*.png, *.jpg, *.pcx, *.bmp, *.gif)", null, false },
398 AddECEREPaths, AddMinGWPaths
401 Array<InstallOption> pathOptions
403 { $"Add Ecere binaries location to the user environment path", null, true, true },
404 { $"Add MinGW to the user environment path", null, true, minGWIncluded },
415 Array<InstallOption> options
417 { $"Install for All Users", null, true, true },
418 { $"Start Menu Group", null, true, true },
419 { $"Desktop Icon", null, true, true },
420 { $"Quicklaunch Icon", null, true, true },
421 { $"Associate the Ecere IDE with Supported File Types", associateOptions.array, true, true },
422 { $"Add binaries location to the user environment paths", pathOptions.array, true, minGWIncluded },
426 char sourceDir[MAX_LOCATION] = ":";
427 char installDir[MAX_LOCATION];
428 char installDir32[MAX_LOCATION];
431 class Installer : Window
433 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
434 background = activeBorder;
439 clientSize = { 636, 476 };
440 // clientSize = { 796, 576 };
441 icon = { ":icon.png" };
443 Picture back { image = BitmapResource { ":ryoanji.png" }, parent = this, position = { 0, 0 } };
444 FileDialog fileDialog
446 master = this, type = selectDir,
447 text = $"Select a new location"
451 master = this, autoCreate = false, inactive = true, text = "...";
453 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
455 DataRow row = componentsBox.currentRow;
456 Component * component = ((CheckItem *)row.GetData(componentField))->data;
457 component->GetFullPath(fileDialog.filePath, false);
458 StripLastDirectory(fileDialog.filePath, fileDialog.currentDirectory);
460 if(fileDialog.Modal() == ok)
462 componentsBox.StopEditing(false);
463 row.SetData(locationField, fileDialog.filePath);
464 componentsBox.NotifyChanged(this, componentsBox, row);
465 componentsBox.currentField = componentsBox.currentField;
470 CheckListBox componentsBox
472 this, size = { 460, 112 }, position = { 160, 160 }, hasHeader = true;
473 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
476 selectionColor = { 145, 150, 140 };
481 bool NotifyKeyDown(ListBox listBox, DataRow row, Key key, unichar ch)
483 if(key == f2 && browse.visible)
484 browse.NotifyClicked(this, browse, 0, 0, 0);
488 bool NotifyChanged(ListBox listBox, DataRow row)
490 Component * component = ((CheckItem *)listBox.GetData(componentField))->data;
491 char path[MAX_LOCATION], relative[MAX_LOCATION] = "", * newPath;
492 char fullPath[MAX_LOCATION];
494 component->parent->GetFullPath(path, false);
495 strcpy(fullPath, path);
497 newPath = row.GetData(locationField);
500 PathCat(fullPath, newPath);
501 if(IsPathInsideOf(fullPath, path))
502 MakePathRelative(fullPath, path, relative);
504 strcpy(relative, fullPath);
506 listBox.SetData(locationField, relative);
507 strcpy(component->installPath, relative);
509 //SetAvailableSpace(component, path);
512 install.disabled = false;
513 for(c = 0; components[c].name; c++)
515 SetAvailableSpace(components[c], installDir);
521 bool NotifyEditDone(ListBox listBox, DataRow row)
527 bool NotifyEdited(ListBox listBox, DataRow row)
530 browse.parent = listBox;
531 browse.position = { componentField.width + locationField.width + 18, (listBox.currentIndex+1) * listBox.rowHeight - 2 };
532 browse.size = { 30, listBox.rowHeight + 3 };
533 for(e = listBox.firstChild; e; e = e.next)
535 if(e._class == class(DataBox))
544 void NotifyChecked(CheckListBox listBox, DataRow row)
546 Component * component = ((CheckItem *)row.GetData(componentField))->data;
548 component->selected = listBox.IsChecked(row);
550 if(!component->parent) totalSize -= component->requiredSize;
551 component->requiredSize = 0;
552 if(component->selected)
554 component->requiredSize += component->size;
555 if(component->subComponents)
556 for(c = 0; component->subComponents[c].name; c++)
557 component->requiredSize += component->subComponents[c].requiredSize;
559 if(component->requiredSize)
561 uint requiredSize = component->requiredSize;
562 row.SetData(reqField, requiredSize);
565 row.UnsetData(reqField);
566 if(!component->parent)
568 totalSize += component->requiredSize;
570 char sizeString[100];
571 PrintSize(sizeString, totalSize, 2);
572 totalSpaceValue.text = sizeString;
577 Label agreementLbl { parent = this, text = $"By installing the Ecere SDK, you agree to the .", font = { "Tahoma", 8.25f }, anchor = Anchor { left = 24, top = 444 } };
580 this, inactive = true, offset = false, bevel = false, foreground = blue, font = { "Tahoma", 8.25f, underline = true, bold = true },
581 // text = $"terms and conditions", anchor = Anchor { left = 241, top = 421 };
582 text = $"terms and conditions", anchor = Anchor { left = 237, top = 441 };
583 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
585 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
587 // LicenseBox { master = this, sourceFile = ":ecere-sdk/doc/LICENSE" }.Modal();
588 LicensesForm { master = this }.Modal();
592 CheckListBox optionsBox
594 this, size = { 460, 114 }, position = { 160, 284 };
595 fullRowSelect = false, collapseControl = true, treeBranches = true, rootCollapseButton = true,
600 void NotifyChecked(CheckListBox listBox, DataRow row)
602 CheckItem * item = row.GetData(optionField);
603 InstallOption * option = item->data;
604 option->selected = listBox.IsChecked(row);
605 // Update default samples/extras path whether we're installing for All Users or not
606 if(option == &options[0])
608 char appData[MAX_LOCATION];
610 options[5].name = options[0].selected ? $"Add binaries location to the system environment paths" : $"Add binaries location to the user environment paths";
612 ((CheckItem *)options[5].row.GetData(optionField))->name = options[5].name;
614 pathOptions[PathOptions::AddECEREPaths].name = options[0].selected ? $"Add Ecere binaries location to the system environment path" : $"Add Ecere binaries location to the user environment path";
615 if(pathOptions[PathOptions::AddECEREPaths].row)
616 ((CheckItem *)pathOptions[PathOptions::AddECEREPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddECEREPaths].name;
618 pathOptions[PathOptions::AddMinGWPaths].name = options[0].selected ? $"Add TDM-GCC/MinGW-w64 to the system environment path" : $"Add TDM-GCC/MinGW-w64 to the user environment path";
619 if(pathOptions[PathOptions::AddMinGWPaths].row)
620 ((CheckItem *)pathOptions[PathOptions::AddMinGWPaths].row.GetData(optionField))->name = pathOptions[PathOptions::AddMinGWPaths].name;
622 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
623 if(appData && appData[0])
625 char defPath[MAX_LOCATION];
627 char * s = components[ComponentID::samples].installPath;
628 strcpy(defPath, installDir);
629 PathCat(defPath, components[ComponentID::samples].defInstallPath);
630 ChangeCh(defPath, '/', DIR_SEP);
631 if(!strcmp(defPath, components[ComponentID::samples].installPath))
633 static char defSamplesPath[MAX_LOCATION];
634 strcpy(defSamplesPath, appData);
635 PathCat(defSamplesPath, "Ecere SDK\\Samples");
636 components[ComponentID::samples].defInstallPath = defSamplesPath;
638 strcpy(components[ComponentID::samples].installPath, components[ComponentID::samples].defInstallPath);
639 ChangeCh(components[ComponentID::samples].installPath, '/', DIR_SEP);
640 components[ComponentID::samples].row.SetData(locationField, components[ComponentID::samples].installPath);
643 strcpy(defPath, installDir);
644 PathCat(defPath, additional[AdditionalID::extras].defInstallPath);
645 ChangeCh(defPath, '/', DIR_SEP);
646 if(!strcmp(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].installPath))
648 static char defExtrasPath[MAX_LOCATION];
649 strcpy(defExtrasPath, appData);
650 PathCat(defExtrasPath, "Ecere SDK\\extras");
651 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
653 strcpy(additional[AdditionalID::extras].installPath, additional[AdditionalID::extras].defInstallPath);
654 ChangeCh(additional[AdditionalID::extras].installPath, '/', DIR_SEP);
655 additional[AdditionalID::extras].row.SetData(locationField, additional[AdditionalID::extras].installPath);
663 parent = this, text = $"Install", isDefault = true, size = { 75, 23 }, position = { 432, 436 };
665 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
667 installProgress.Create();
669 // installProgress.thread.Main();
670 installProgress.thread.Create();
674 Button button3 { parent = this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 436 }, NotifyClicked = ButtonCloseDialog };
675 Label label1 { labeledWindow = destBox, tabCycle = true, isGroupBox = true, parent = this, inactive = false, size = Size { 458, 50 }, anchor = Anchor { left = 160, top = 96 } };
678 parent = label1, master = this, text = $" Destination Folder", size = Size { 336, 22 }, anchor = Anchor { left = 12, top = 20, right = 12 };
679 typeExpected = directory;
680 browseDialog = fileDialog;
683 bool NotifyModified(PathBox pathBox)
686 strcpy(installDir, destBox.path);
687 install.disabled = false;
688 for(c = 0; components[c].name; c++)
690 SetAvailableSpace(components[c], installDir);
697 label1, this, $"Browse", altB, size = { 83, 24 }, position = { 360, 16 };
699 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
701 strcpy(fileDialog.filePath, installDir);
702 StripLastDirectory(installDir, fileDialog.currentDirectory);
703 if(fileDialog.Modal())
705 strcpy(installDir, fileDialog.filePath);
706 destBox.contents = installDir;
707 // TOCHECK: Should setting contents call NotifyModified?
708 destBox.NotifyModified(destBox.master, destBox);
715 this, multiLine = true,
716 opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 96 }, noSelect = true,
717 contents = $"Select the default root\n"
718 "folder where to install\n"
723 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 132 }, position = { 14, 152 }, noSelect = true,
725 contents = $"Select the optional\n"
726 "components you wish\n"
728 "You may customize the\n"
729 "install location for each\n"
730 "of them, or use the default\n"
731 "based on the main\n"
732 "destination folder."
736 this, opacity = 0, borderStyle = none, inactive = true, size = { 136, 53 }, position = { 14, 280 }, noSelect = true,
738 contents = $"Select icons to install, file\n"
739 "associations, and system\n"
740 "environment modifications:"
742 Label totalSpaceLabel
744 this, position = { 18, 352 }, text = $"Space Required: "
746 Label totalSpaceValue
748 this, position = { 100, 352 }, text = "0 mb"
752 inactive = true, noSelect = true,
753 multiLine = true, parent = label3, text = "editBox1", opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
754 contents = $"Choose in which folder to install the Ecere SDK, which features\n"
755 "of the SDK to install, as well as where to install program icons."
757 Label label2 { parent = this, text = buildString, position = { 16, 412 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
760 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, text = "picture1", anchor = Anchor { left = 16, top = 4 };
761 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
763 bool OnLeftButtonDown(int x, int y, Modifiers mods)
765 ShellOpen("http://www.ecere.com/");
769 Label label4 { parent = label3, text = $"Choose Components, Locations and Install Options", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
770 DataField componentField { "CheckItem", width = 160, header = $"Component" };
771 DataField locationField { "char *", width = 108, header = $"Destination Folder", editable = true };
772 DataField reqField { "FileSize", width = 70, header = $"Req. Space", alignment = right };
773 DataField avField { "FileSize64", width = 70, header = $"Avail. Space", alignment = right };
774 DataField optionField { "CheckItem" };
776 void SetAvailableSpace(Component component, char * parentPath)
778 char path[MAX_LOCATION];
782 strcpy(path, parentPath);
783 PathCat(path, component.installPath);
785 if(component.subComponents)
786 for(c = 0; component.subComponents[c].name; c++)
787 SetAvailableSpace(component.subComponents[c], path);
789 while(!FileExists(path) && path[0])
790 StripLastDirectory(path, path);
793 GetFreeSpace(path, &size);
794 component.row.SetData(avField, size);
795 if(!size) install.disabled = true;
798 FileSize ComputeSize(char * path)
801 FileAttribs attribs = FileExists(path);
802 if(attribs.isDirectory)
804 FileListing listing { path };
805 while(listing.Find())
807 if(listing.stats.attribs.isDirectory)
808 size += ComputeSize(listing.path);
810 size += listing.stats.size;
814 FileGetSize(path, &size);
818 void AddComponent(Component component, Component parent, char * parentPath)
820 DataRow row = (parent != null) ? parent.row.AddRow() : componentsBox.AddRow();
822 FileSize64 avSize = 0;
823 char path[MAX_LOCATION];
826 strcpy(path, parentPath);
827 if(component.defInstallPath)
828 PathCat(path, component.defInstallPath);
829 component.parent = parent;
831 row.SetData(null, CheckItem { component.name, component, (component.arch == bits32 && osIS64bit) } );
833 if(component.defInstallPath)
835 strcpy(component.installPath, component.defInstallPath);
836 ChangeCh(component.installPath, '/', DIR_SEP);
837 row.SetData(locationField, component.installPath);
840 if(component.mandatory)
842 if(component.arch != bits32 || !osIS64bit) // || component == &coreSDK[gdb32])
843 componentsBox.SetDisabled(row, true);
845 component.selected = false;*/
847 else if(component.arch == bits32 && osIS64bit)
848 ; //component.selected = false;
850 componentsBox.SetCheck(row, component.selected);
852 if(component.dataPath)
854 char path[MAX_LOCATION];
856 PathCat(path, component.dataPath);
857 component.size = ComputeSize(path);
859 if(component.subComponents)
862 for(c = 0; component.subComponents[c].name; c++)
864 Component * sub = &component.subComponents[c];
865 if(sub->available && (osIS64bit || sub->arch == bits32 || sub->arch == none))
867 AddComponent(sub, component, path);
868 size += sub->requiredSize;
871 sub->selected = false;
875 component.requiredSize = component.selected ? (size + component.size) : 0;
876 if(component.requiredSize)
877 row.SetData(reqField, component.requiredSize);
879 while(!FileExists(path) && path[0])
880 StripLastDirectory(path, path);
883 GetFreeSpace(path, &avSize);
886 row.SetData(avField, avSize);
887 row.collapsed = true;
890 void AddOption(InstallOption option, InstallOption parent)
892 DataRow row = option.row = (parent != null) ? parent.row.AddRow() : optionsBox.AddRow();
893 row.SetData(null, CheckItem { option.name, option } );
894 optionsBox.SetCheck(row, option.selected);
895 if(option.subOptions)
898 for(c = 0; option.subOptions[c].name; c++)
900 AddOption(option.subOptions[c], option);
903 row.collapsed = true;
909 char programFilesDir[MAX_LOCATION];
910 char appData[MAX_LOCATION];
911 char homeDrive[MAX_LOCATION];
912 char winDir[MAX_LOCATION];
915 bool isAdministrator = IsAdministrator();
919 options[0].available = false;
920 options[0].selected = false;
923 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
924 GetEnvironment("windir", winDir, sizeof(winDir));
926 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "APPDATA", appData, sizeof(appData));
928 componentsBox.AddField(componentField);
929 componentsBox.AddField(locationField);
930 componentsBox.AddField(reqField);
931 componentsBox.AddField(avField);
933 optionsBox.AddField(optionField);
935 programFilesDir[0] = 0;
936 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
938 x86 = strstr(programFilesDir, " (x86)");
943 if(isAdministrator && programFilesDir[0])
947 strcpy(installDir32, programFilesDir);
948 PathCat(installDir32, "Ecere SDK");
950 strcpy(installDir, programFilesDir);
951 PathCat(installDir, "Ecere SDK");
955 strcpy(installDir, programFilesDir);
956 PathCat(installDir, "Ecere SDK");
957 strcpy(installDir32, installDir);
960 else if(homeDrive && homeDrive[0])
962 strcpy(installDir, homeDrive);
963 PathCat(installDir, "Ecere SDK");
964 strcpy(installDir32, installDir);
965 strcat(installDir32, " (32)");
967 else if(winDir && winDir[0])
969 strcpy(installDir, winDir);
970 PathCat(installDir, "..\\Ecere SDK");
971 strcpy(installDir32, installDir);
972 strcat(installDir32, " (32)");
976 strcpy(installDir, "C:\\Ecere SDK");
977 strcpy(installDir32, installDir);
978 strcat(installDir32, " (32)");
981 if(appData && appData[0])
983 static char defSamplesPath[MAX_LOCATION];
984 static char defExtrasPath[MAX_LOCATION];
985 strcpy(defSamplesPath, appData);
986 PathCat(defSamplesPath, "Ecere SDK\\Samples");
987 components[ComponentID::samples].defInstallPath = defSamplesPath;
989 strcpy(defExtrasPath, appData);
990 PathCat(defExtrasPath, "Ecere SDK\\extras");
991 additional[AdditionalID::extras].defInstallPath = defExtrasPath;
994 destBox.path = installDir;
998 for(c = 0; components[c].name; c++)
999 AddComponent(components[c], null, installDir);
1002 // Compute size apart because ToggleCheck will change it
1006 for(c = 0; components[c].name; c++)
1007 totalSize += components[c].requiredSize;
1010 char sizeString[100];
1011 PrintSize(sizeString, totalSize, 2);
1012 totalSpaceValue.text = sizeString;
1014 for(c = 0; options[c].name; c++)
1016 if(options[c].available)
1017 AddOption(options[c], null);
1027 void OnDrawOverChildren(Surface surface)
1029 int tw = label2.size.w;
1030 surface.SetForeground(Color { 128, 128, 128 });
1031 surface.HLine(label2.position.x + tw + 6, 620, 420);
1032 surface.SetForeground(white);
1033 surface.HLine(label2.position.x + tw + 6, 621, 421);
1034 surface.PutPixel(621, 400);
1039 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1043 class InstallProgress : Window
1045 text = $"Ecere Software Development Kit Setup - v0.44.10 \"Ryōan-ji\" 64 Bit Edition";
1046 background = activeBorder;
1047 borderStyle = fixed;
1051 // size = Size { 640, 480 };
1052 clientSize = { 636, 476 };
1053 //clientSize = { 796, 576 };
1054 icon = { ":icon.png" };
1056 Picture back { image = BitmapResource { ":ryoanji-progress.png" }, parent = this, position = { 0, 0 } };
1057 Label installing { this, position = { 32, 160 } };
1058 ProgressBar progressBar { parent = this, size = Size { 588, 24 }, anchor = Anchor { left = 24, top = 184 } };
1061 parent = this, text = $"Install", disabled = true, isDefault = true, size = Size { 75, 23 }, anchor = Anchor { left = 432, top = 436 };
1063 NotifyClicked = ButtonCloseDialog
1067 this, text = $"Cancel", hotKey = altX, size = Size { 75, 23 }, anchor = Anchor { left = 544, top = 436 };
1069 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
1071 abortInstall = true;
1077 inactive = true, noSelect = true,
1078 multiLine = true, parent = label3, opacity = 0, borderStyle = none, size = Size { 350, 35 }, anchor = Anchor { horz = 111, vert = 13 },
1079 contents = $"Please wait while the Ecere Software Development Kit is being installed."
1081 Label label2 { parent = this, text = buildString, position = { 16, 412 }, font = { "Tahoma", 10, true }, disabled = true, opacity = 0, background = activeBorder };
1084 image = BitmapResource { ":ecere.png", alphaBlend = true }, filter = true, parent = label3, anchor = Anchor { left = 16, top = 4 };
1085 cursor = ((GuiApplication)__thisModule).GetCursor(hand);
1087 bool OnLeftButtonDown(int x, int y, Modifiers mods)
1089 ShellOpen("http://www.ecere.com/");
1093 Label title { parent = label3, text = $"Installing the Ecere SDK", font = FontResource { "Tahoma", 8.25f, bold = true }, size = Size { 326, 16 }, anchor = Anchor { horz = 91, vert = -12 } };
1095 void OnDrawOverChildren(Surface surface)
1097 int tw = label2.size.w;
1098 surface.SetForeground(Color { 128, 128, 128 });
1099 surface.HLine(label2.position.x + tw + 6, 620, 420);
1100 surface.SetForeground(white);
1101 surface.HLine(label2.position.x + tw + 6, 621, 421);
1102 surface.PutPixel(621, 400);
1107 parent = this, opacity = 0, borderStyle = deep, size = Size { 644, 93 }, anchor = Anchor { left = -8, top = -8 };
1109 InstallThread thread
1114 Installer installer {};
1115 InstallProgress installProgress { autoCreate = false };
1117 static void AddPath(char * sysPaths[200], int sysCount, char * paths[200], int * count, char * oldPath, char * userPath, char * path)
1121 for(p = 0; p<sysCount; p++)
1122 if(!fstrcmp(sysPaths[p], path))
1127 for(p = 0; !found && p<*count; p++)
1128 if(!fstrcmp(paths[p], path))
1138 strcat(userPath, ";");
1139 start = paths[(*count)-1] + strlen(paths[(*count)-1])+1;
1144 strcpy(start, path);
1145 *(start + strlen(path)) = '\0';
1146 paths[(*count)++] = start;
1148 strcat(userPath, path);
1153 void ModifyPath(char * systemPath, char * userPath)
1155 char oldPath[8192], * paths[200], * sysPaths[200];
1156 int count, sysCount = 0;
1160 strcpy(oldPath, userPath);
1161 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1162 sysCount = TokenizeWith(systemPath, sizeof(sysPaths) / sizeof(char *), sysPaths, ";", false);
1166 strcpy(oldPath, systemPath);
1167 count = TokenizeWith(oldPath, sizeof(paths) / sizeof(char *), paths, ";", false);
1172 for(c = 0; coreSDK[c].name; c++)
1175 char path[MAX_LOCATION];
1176 if(!coreSDK[c].selected) continue;
1177 coreSDK[c].GetFullPath(path, false);
1178 if(c != ide && c != runtime && c != ec &&
1179 c != ide32 && c != runtime32 && c != ec32)
1181 if(!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected)
1183 PathCat(path, "bin");
1185 else if(!pathOptions[PathOptions::AddECEREPaths].selected) continue;
1187 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1193 for(c = 0; c <= cpp; c++)
1196 char path[MAX_LOCATION];
1197 if(!additional[c].selected || c == vanilla || c == vanilla32 || c == extras) continue;
1198 if((c != eda && c != eda32 && c != upx) && (!pathOptions[PathOptions::AddMinGWPaths].available || !pathOptions[PathOptions::AddMinGWPaths].selected))
1200 additional[c].GetFullPath(path, false);
1201 if(c != eda && c != eda32 && c != upx)
1202 PathCat(path, "bin");
1203 AddPath(sysPaths, sysCount, paths, &count, oldPath, userPath ? userPath : systemPath, path);
1208 void AssociateExtension(char * extension, char * description, char *name, char * action, char * path)
1214 RegCreateKeyEx(HKEY_CLASSES_ROOT, extension, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1215 RegSetValueEx(key, null, 0, REG_SZ, name, (uint)strlen(name)+1);
1218 RegCreateKeyEx(HKEY_CLASSES_ROOT, name, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1219 RegSetValueEx(key, null, 0, REG_SZ, description, (uint)strlen(description)+1);
1222 sprintf(keyName, "%s\\shell", extension);
1223 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1224 RegSetValueEx(key, null, 0, REG_SZ, action, (uint)strlen(action)+1);
1227 sprintf(keyName, "%s\\shell\\%s", name, action);
1228 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1231 sprintf(keyName, "%s\\shell\\%s\\command", name, action);
1232 RegCreateKeyEx(HKEY_CLASSES_ROOT, keyName, 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1234 sprintf(keyName, path);
1235 strcat(keyName, " \"%L\"");
1237 uint16 wKeyName[2048];
1238 UTF8toUTF16Buffer(keyName, wKeyName, sizeof(wKeyName) / sizeof(uint16));
1239 RegSetValueExW(key, null, 0, REG_SZ, (byte *)wKeyName, (uint)(wcslen(wKeyName) + 1)*sizeof(uint16));
1244 class InstallThread : Thread
1249 ((GuiApplication)__thisModule).Lock();
1250 installProgress.progressBar.range = totalSize;
1253 strcpy(installDir32, installDir);
1255 for(c = 0; components[c].name && !abortInstall; c++)
1256 components[c].Install(installDir, installDir32);
1259 installProgress.progressBar.range = 0;
1260 installProgress.finish.Destroy(0);
1261 installProgress.cancel.text = $"Close";
1262 installProgress.cancel.isDefault = true;
1263 installProgress.cancel.disabled = false;
1264 installProgress.cancel.NotifyClicked = Window::ButtonCloseDialog;
1265 installProgress.installing.text = $"Installation Cancelled.";
1266 installProgress.title.text = $"Installation Cancelled";
1267 installProgress.titleInfo.contents = $"The installation was not completed.";
1271 char idePath[MAX_LOCATION];
1272 char userProfile[MAX_LOCATION];
1275 IDESettings settings = null; // Don't instantiate yet so we can pick up old settings
1277 IDESettingsContainer settingsContainer
1280 dataOwner = &settings;
1281 dataClass = class(IDESettings);
1282 allUsers = options[0].selected;
1284 CompilerConfig compiler;
1285 installProgress.installing.text = $"Configuring Ecere IDE...";
1286 ((GuiApplication)__thisModule).Unlock();
1287 ((GuiApplication)__thisModule).SignalEvent();
1289 settingsContainer.Load();
1290 compiler = settings.GetCompilerConfig(defaultCompilerName);
1295 for(c = 0; coreSDK[c].name; c++)
1297 char path[MAX_LOCATION];
1298 if(!coreSDK[c].selected || !coreSDK[c].available) continue;
1300 coreSDK[c].GetFullPath(path, false);
1301 if(c != ide && c != runtime && c != ec &&
1302 c != ide32 && c != runtime32 && c != ec32)
1303 PathCat(path, "bin");
1304 MakeSlashPath(path);
1305 if((c == ide && osIS64bit) || (c == ide32 && !osIS64bit))
1307 coreSDK[c].GetFullPath(idePath, false);
1308 PathCat(idePath, "ide.exe");
1311 if(c == runtime || c == runtime32)
1313 if(!compiler.libraryDirs.Find(path))
1314 compiler.libraryDirs.Add(CopyString(path));
1321 for(c = 0; c <= cpp; c++)
1323 char path[MAX_LOCATION];
1324 if(c == extras || !additional[c].selected || !additional[c].available) continue;
1325 additional[c].GetFullPath(path, false);
1326 if(c != upx && c != eda && c != vanilla && c != eda32 && c != vanilla32)
1327 PathCat(path, "bin");
1328 MakeSlashPath(path);
1329 if(c == vanilla || c == vanilla32)
1331 if(!compiler.libraryDirs.Find(path))
1332 compiler.libraryDirs.Add(CopyString(path));
1336 if(!compiler.executableDirs.Find(path))
1337 compiler.executableDirs.Add(CopyString(path));
1344 char path[MAX_LOCATION] = "";
1346 if(components[ComponentID::samples].selected)
1347 components[ComponentID::samples].GetFullPath(path, false);
1348 // IDE will now default to HOME for the default project/files locations
1350 if(!settings.ideProjectFileDialogLocation[0])
1351 settings.ideProjectFileDialogLocation = path;
1352 if(!settings.ideFileDialogLocation[0])
1353 settings.ideFileDialogLocation = path;
1355 if(documentation[DocumentationID::apiRef].selected)
1357 documentation[DocumentationID::apiRef].GetFullPath(path, false);
1358 if(!settings.docDir[0])
1359 settings.docDir = path;
1363 settingsContainer.Save();
1364 delete settingsContainer;
1367 // Set up Uninstaller
1368 ((GuiApplication)__thisModule).Lock();
1369 installProgress.installing.text = $"Registering uninstaller...";
1370 ((GuiApplication)__thisModule).Unlock();
1371 ((GuiApplication)__thisModule).SignalEvent();
1376 char * displayName = "Ecere SDK 0.44";
1377 char uninstaller[MAX_LOCATION];
1378 bool nomodify = true;
1380 strcpy(uninstaller, installDir);
1381 PathCat(uninstaller, "uninstall_ecere.exe");
1383 RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ecere SDK", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &key, &status);
1385 RegSetValueEx(key, "DisplayName", 0, REG_SZ, displayName, (uint)strlen(displayName)+1);
1386 RegSetValueEx(key, "UninstallString", 0, REG_SZ, uninstaller, (uint)strlen(uninstaller)+1);
1387 RegSetValueEx(key, "DisplayIcon", 0, REG_SZ, idePath, (uint)strlen(idePath)+1);
1388 //RegSetValueEx(key, "NoModify", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1389 //RegSetValueEx(key, "NoRepair", 0, REG_DWORD, (byte *)&nomodify, sizeof(nomodify));
1394 if(pathOptions[PathOptions::AddECEREPaths].selected
1396 || pathOptions[PathOptions::AddMinGWPaths].selected
1400 HKEY userKey = null, systemKey = null;
1402 char userPath[8192] = "";
1403 char systemPath[8192] = "";
1404 uint16 wUserPath[8192];
1405 uint16 wSystemPath[8192];
1410 ((GuiApplication)__thisModule).Lock();
1411 installProgress.installing.text = "Registering paths...";
1412 ((GuiApplication)__thisModule).Unlock();
1413 ((GuiApplication)__thisModule).SignalEvent();
1415 if(options[0].selected)
1417 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_ALL_ACCESS, &systemKey) == ERROR_SUCCESS)
1419 size = sizeof(wSystemPath);
1420 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1421 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1422 ModifyPath(systemPath, null);
1424 UTF8toUTF16Buffer(systemPath, wSystemPath, sizeof(wSystemPath) / sizeof(uint16));
1425 RegSetValueExW(systemKey, L"path", 0, REG_EXPAND_SZ, (byte *)wSystemPath, (uint)(wcslen(wSystemPath)+1) * 2);
1426 RegCloseKey(systemKey);
1431 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", 0, KEY_QUERY_VALUE, &systemKey) == ERROR_SUCCESS)
1433 size = sizeof(wSystemPath);
1434 RegQueryValueExW(systemKey, L"path", null, null, (byte *)wSystemPath, &size);
1435 UTF16toUTF8Buffer(wSystemPath, systemPath, sizeof(systemPath));
1436 RegCloseKey(systemKey);
1439 RegCreateKeyEx(HKEY_CURRENT_USER, "Environment", 0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, null, &userKey, &status);
1440 if(status == REG_OPENED_EXISTING_KEY)
1442 size = sizeof(wUserPath);
1443 RegQueryValueExW(userKey, L"path", null, null, (byte *)wUserPath, &size);
1444 UTF16toUTF8Buffer(wUserPath, userPath, sizeof(userPath));
1446 ModifyPath(systemPath, userPath);
1447 UTF8toUTF16Buffer(userPath, wUserPath, sizeof(wUserPath) / sizeof(uint16));
1448 RegSetValueExW(userKey, L"path", 0, REG_EXPAND_SZ, (byte *)wUserPath, (uint)(wcslen(wUserPath)+1) * 2);
1449 RegCloseKey(userKey);
1451 SendMessageTimeout (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_NORMAL, 1000, NULL);
1454 // Install Program Group Icons
1455 GetEnvironment(options[0].selected ? "ALLUSERSPROFILE" : "USERPROFILE", userProfile, sizeof(userProfile));
1457 if(options[IconOptions::StartMenuIcon].selected)
1459 char destPath[MAX_LOCATION];
1460 char startMenuPath[MAX_LOCATION] = "";
1463 ((GuiApplication)__thisModule).Lock();
1464 installProgress.installing.text = $"Installing Start Menu Icons...";
1465 ((GuiApplication)__thisModule).Unlock();
1466 ((GuiApplication)__thisModule).SignalEvent();
1468 strcpy(destPath, userProfile);
1470 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1471 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1473 uint16 wStartMenuPath[2048];
1474 uint size = sizeof(wStartMenuPath);
1475 // RegQueryValueEx(key, "Start Menu", null, null, startMenuPath, &size);
1476 RegQueryValueExW(key, options[0].selected ? L"Common Programs" : L"Programs", null, null, (byte *)wStartMenuPath, &size);
1477 UTF16toUTF8Buffer(wStartMenuPath, startMenuPath, sizeof(startMenuPath));
1480 if(!startMenuPath[0] && userProfile[0])
1482 strcpy(startMenuPath, userProfile);
1483 PathCat(startMenuPath, "Start Menu\\Programs");
1486 if(startMenuPath[0])
1488 strcpy(destPath, startMenuPath);
1489 PathCat(destPath, "Ecere SDK");
1492 strcpy(destPath, startMenuPath);
1493 PathCat(destPath, "Ecere SDK\\Ecere IDE.lnk");
1494 CreateLink(idePath, destPath, null); //"Ecere IDE");
1495 if(components[ComponentID::samples].selected)
1497 char samplesPath[MAX_LOCATION] = "";
1498 components[ComponentID::samples].GetFullPath(samplesPath, false);
1500 strcpy(destPath, startMenuPath);
1501 PathCat(destPath, "Ecere SDK\\Sample Projects.lnk");
1502 CreateLink(samplesPath, destPath, null);//"Sample Projects");
1504 if(components[ComponentID::documentation].selected && documentation[DocumentationID::ecereBook].selected)
1506 char docPath[MAX_LOCATION] = "";
1507 documentation[DocumentationID::ecereBook].GetFullPath(docPath, false);
1508 PathCat(docPath, "Ecere Tao of Programming [work in progress].pdf");
1511 char tao[MAX_LOCATION] ;
1512 documentation[DocumentationID::ecereBook].GetFullPath(tao, false);
1513 PathCat(tao, "tao.pdf");
1514 RenameFile(tao, docPath);
1517 strcpy(destPath, startMenuPath);
1518 PathCat(destPath, "Ecere SDK\\The Ecere Tao of Programming.lnk");
1519 CreateLink(docPath, destPath, null);
1524 // Install Desktop Icon
1525 if(options[IconOptions::DesktopIcon].selected)
1528 char desktopPath[MAX_LOCATION];
1530 if(RegOpenKeyEx(options[0].selected ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER,
1531 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_QUERY_VALUE, &key) == ERROR_SUCCESS)
1533 uint16 wDesktopPath[MAX_LOCATION];
1534 uint size = sizeof(wDesktopPath);
1535 RegQueryValueExW(key, options[0].selected ? L"Common Desktop" : L"Desktop", null, null, (byte *)wDesktopPath, &size);
1536 UTF16toUTF8Buffer(wDesktopPath, desktopPath, sizeof(desktopPath));
1539 if(!desktopPath[0] && userProfile[0])
1541 strcpy(desktopPath, userProfile);
1542 PathCat(desktopPath, "Desktop");
1547 PathCat(desktopPath, "Ecere IDE.lnk");
1549 ((GuiApplication)__thisModule).Lock();
1550 installProgress.installing.text = $"Installing Desktop Icon...";
1551 ((GuiApplication)__thisModule).Unlock();
1552 ((GuiApplication)__thisModule).SignalEvent();
1554 CreateLink(idePath, desktopPath, null);//"Ecere IDE");
1558 // Install QuickLaunch Icon
1559 if(options[IconOptions::QuickLaunchIcon].selected)
1561 char appData[MAX_LOCATION];
1562 GetEnvironment("APPDATA", appData, sizeof(appData));
1565 char destPath[MAX_LOCATION];
1567 if(appData[0] && options[0].selected)
1569 char dir[MAX_FILENAME];
1570 GetLastDirectory(appData, dir);
1571 if(!strcmpi(dir, "Roaming"))
1572 PathCat(appData, "../../../Default/AppData/Roaming");
1574 PathCat(appData, "../Default");
1577 ((GuiApplication)__thisModule).Lock();
1578 installProgress.installing.text = $"Installing Quicklaunch Icon...";
1579 ((GuiApplication)__thisModule).Unlock();
1580 ((GuiApplication)__thisModule).SignalEvent();
1582 strcpy(destPath, appData);
1583 PathCat(destPath, "Microsoft\\Internet Explorer\\Quick Launch\\Ecere IDE.lnk");
1584 CreateLink(idePath, destPath, null);
1586 // Set it up on the dock for Windows 7 -- not working
1588 StripLastDirectory(destPath, destPath);
1589 PathCat(destPath, "User Pinned\\TaskBar");
1591 PathCat(destPath, "Ecere IDE.lnk");
1592 CreateLink(idePath, destPath, null);
1597 // Register File Types
1598 if(associateOptions[AssociateOptions::AssociateEPJ].selected ||
1599 associateOptions[AssociateOptions::AssociateEC].selected ||
1600 associateOptions[AssociateOptions::AssociateC].selected ||
1601 associateOptions[AssociateOptions::AssociateCPP].selected ||
1602 associateOptions[AssociateOptions::AssociateTXT].selected ||
1603 associateOptions[AssociateOptions::Associate3DS].selected ||
1604 associateOptions[AssociateOptions::AssociateIMG].selected)
1606 ((GuiApplication)__thisModule).Lock();
1607 installProgress.installing.text = $"Resgistering File Types...";
1608 ((GuiApplication)__thisModule).Unlock();
1609 ((GuiApplication)__thisModule).SignalEvent();
1611 if(associateOptions[AssociateOptions::AssociateEPJ].selected)
1613 AssociateExtension(".epj", "Ecere IDE Project", "epj_file", "Open", idePath);
1615 if(associateOptions[AssociateOptions::AssociateEC].selected)
1617 AssociateExtension(".ec", "eC Source File", "ec_file", "Open", idePath);
1618 AssociateExtension(".eh", "eC Header File", "eh_file", "Open", idePath);
1620 if(associateOptions[AssociateOptions::AssociateC].selected)
1622 AssociateExtension(".c", "C Source File", "c_file", "Open", idePath);
1623 AssociateExtension(".h", "C Header File", "h_file", "Open", idePath);
1625 if(associateOptions[AssociateOptions::AssociateCPP].selected)
1627 AssociateExtension(".cpp", "C++ Source File", "cpp_file", "Open", idePath);
1628 AssociateExtension(".cc", "C++ Source File", "cpp_file", "Open", idePath);
1629 AssociateExtension(".cxx", "C++ Source File", "cpp_file", "Open", idePath);
1630 AssociateExtension(".chh", "C++ Header File", "chh_file", "Open", idePath);
1631 AssociateExtension(".hh", "C++ Header File", "chh_file", "Open", idePath);
1632 AssociateExtension(".hxx", "C++ Header File", "chh_file", "Open", idePath);
1634 if(associateOptions[AssociateOptions::AssociateTXT].selected)
1636 AssociateExtension(".txt", "Text File", "txt_file", "Open", idePath);
1638 if(associateOptions[AssociateOptions::Associate3DS].selected)
1640 AssociateExtension(".3ds", "3D Studio Model", "3ds_file", "View", idePath);
1642 if(associateOptions[AssociateOptions::AssociateIMG].selected)
1644 AssociateExtension(".bmp", "BMP Image", "bmp_file", "View", idePath);
1645 AssociateExtension(".pcx", "PCX Image", "pcx_file", "View", idePath);
1646 AssociateExtension(".png", "PNG Image", "png_file", "View", idePath);
1647 AssociateExtension(".jpg", "JPEG Image", "jpg_file", "View", idePath);
1648 AssociateExtension(".jpeg", "JPEG Image", "jpg_file", "View", idePath);
1649 AssociateExtension(".gif", "GIF Image", "gif_file", "View", idePath);
1652 ((GuiApplication)__thisModule).Lock();
1654 installProgress.cancel.Destroy(0);
1655 installProgress.finish.text = $"Finish";
1656 installProgress.finish.disabled = false;
1657 installProgress.finish.Activate();
1658 installProgress.installing.text = $"Installation Complete.";
1659 installProgress.title.text = $"Installation Complete";
1660 installProgress.titleInfo.contents = $"Thank you for using the Ecere SDK.";
1662 ((GuiApplication)__thisModule).Unlock();