public void AddSystemToBootStick(SystemInfo systemInfo, Logger logger, SystemProgressReporter systemProgressReporter) { if (SysLinuxConfigFile == null) { throw new InvalidOperationException(); } var systemDirectory = new DirectoryInfo(Path.Combine(_drive.RootDirectory.FullName, DriveDirectory, Path.GetFileNameWithoutExtension(systemInfo.Filename))); if (systemDirectory.Exists) { throw new Exception("System already exists"); } logger.Status($"Create directory \"{systemDirectory.FullName}\""); systemDirectory.Create(); var installer = _installer[systemInfo.InstallMethod]; logger.Status($"Install method \"{installer.InstallMethod}\" selected"); MenuItemInfo menuItem; installer.Install(systemDirectory, systemInfo.Name, systemInfo.SpecialSnowflake, systemInfo.Filename, out menuItem, systemProgressReporter); logger.Status("Add to config file"); SysLinuxConfigFile.AddSystem(systemInfo, menuItem, systemDirectory.Name); SysLinuxConfigFile.Save(); logger.Status("Update syslinux"); UpdateSysLinux(systemDirectory); }
public override void Install(DirectoryInfo systemDirectory, string systemName, SpecialSnowflake specialSnowflake, string filename, out MenuItemInfo menuItem, SystemProgressReporter progressReporter) { progressReporter.ReportStatus(InstallationStatus.CopyFiles); var fileDirectory = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(filename), "kon-bootUSB", "USBFILES")); if (!fileDirectory.Exists) { throw new FileNotFoundException($"Could not find kon boot USB directory: \"{fileDirectory.FullName}\""); } File.Copy(Path.Combine(fileDirectory.FullName, "grldr"), Path.Combine(systemDirectory.FullName, "grldr")); progressReporter.ReportProgress(.4); File.Copy(Path.Combine(fileDirectory.FullName, "konboot.img"), Path.Combine(systemDirectory.FullName, "konboot.img")); progressReporter.ReportProgress(.8); File.Copy(Path.Combine(fileDirectory.FullName, "konbootOLD.img"), Path.Combine(systemDirectory.FullName, "konbootOLD.img")); progressReporter.ReportProgress(1); progressReporter.ReportStatus(InstallationStatus.WriteConfig); var pathWithoutDrive = RemoveDriveFromPath(systemDirectory.FullName).Replace("\\", "/"); var konbootVersionSelectionFile = $@"title Kon-Boot (CURRENT VERSION) map --mem {pathWithoutDrive}/konboot.img (fd0) map --hook chainloader (fd0)+1 map (hd1) (hd0) map --hook rootnoverify (fd0) title Kon-Boot v2.1 (OLD VERSION) map --mem {pathWithoutDrive}/konbootOLD.img (fd0) map --hook chainloader (fd0)+1 map (hd1) (hd0) map --hook rootnoverify (fd0)"; File.WriteAllText(Path.Combine(systemDirectory.FullName, "konboot.lst"), konbootVersionSelectionFile); menuItem = new MenuItemInfo($@"KERNEL /multiboot/grub.exe APPEND --config-file={pathWithoutDrive}/konboot.lst"); }
public override void Install(DirectoryInfo systemDirectory, string systemName, SpecialSnowflake specialSnowflake, string filename, out MenuItemInfo menuItem, SystemProgressReporter progressReporter) { progressReporter.ReportStatus(InstallationStatus.ExtractFile); using (var file = new SevenZipExtractor(filename)) { file.Extracting += (sender, args) => { progressReporter.ReportProgress(args.PercentDone / 100d); }; file.ExtractArchive(systemDirectory.FullName); } progressReporter.ReportStatus(InstallationStatus.WriteConfig); var configInfo = GetSystemBootInfo(systemDirectory.FullName); menuItem = new MenuItemInfo( $@"CONFIG /{Path.Combine("multiboot", systemDirectory.Name, configInfo.ConfigPath, configInfo.ConfigFile).Replace('\\', '/')} APPEND /multiboot/{systemDirectory.Name}/{configInfo.ConfigPath}"); //For Ubuntu Desktop and derivatives ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\txt.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\text.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\isolinux.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); //Alt For derivatives like Dr.Web Livedisk ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "syslinux\\txt.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "syslinux\\text.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "syslinux\\syslinux.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" } }); //Rename the following for grub loopback.cfg ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "boot\\grub\\loopback.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "/casper/vmlinuz", $"/multiboot/{systemDirectory.Name}/casper/vmlinuz" }, { "/casper/initrd", $"/multiboot/{systemDirectory.Name}/casper/initrd" }, { "boot=casper", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid boot=NULL live-media-path=/multiboot/{systemDirectory.Name}/casper/" }, { "boot=NULL", "boot=casper" }, }); //Rename the following for grub.cfg ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "boot\\grub\\grub.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "/casper/vmlinuz", $"/multiboot/{systemDirectory.Name}/casper/vmlinuz" }, { "/casper/initrd", $"/multiboot/{systemDirectory.Name}/casper/initrd" }, { "boot=casper", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid boot=NULL live-media-path=/multiboot/{systemDirectory.Name}/casper/" }, { "boot=NULL", "boot=casper" }, }); //For Debian Based and derivatives ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux", "live.cfg"), new Dictionary <string, string> { { "linux /live/", $"linux /multiboot/{systemDirectory.Name}/live/" }, { "initrd /live/", $"initrd /multiboot/{systemDirectory.Name}/live/" }, { "append boot=live", $"append live-media-path=/multiboot/{systemDirectory.Name}/live/ cdrom-detect/try-usb=true noprompt boot=live" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux", "install.cfg"), new Dictionary <string, string> { { "linux /install/", $"linux /multiboot/{systemDirectory.Name}/install/" }, { "initrd /install/", $"initrd /multiboot/{systemDirectory.Name}/install/" }, { "-- quiet", "cdrom-detect/try-usb=true quiet" } }); //SolydX ReplaceStringInFile(Path.Combine(systemDirectory.FullName, configInfo.ConfigPath, configInfo.ConfigFile), new Dictionary <string, string> { { "kernel /solydxk", $"kernel /multiboot/{systemDirectory.Name}/solydxk" }, { "initrd=/solydxk", $"initrd=/multiboot/{systemDirectory.Name}/solydxk" }, { "live-media-path=/solydxk", $"live-media-path=/multiboot/{systemDirectory.Name}/solydxk" }, }); //For Desinfect Distro ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\os.cfg"), new Dictionary <string, string> { { "file=/cdrom/preseed/", $"file=/cdrom/multiboot/{systemDirectory.Name}/preseed/" }, { "initrd=/casper/", $"cdrom-detect/try-usb=true noprompt floppy.allowed_drive_mask=0 ignore_uuid live-media-path=/multiboot/{systemDirectory.Name}/casper/ initrd=/multiboot/{systemDirectory.Name}/casper/" }, { "kernel /casper/", $"kernel /multiboot/{systemDirectory.Name}/casper/" }, { "BOOT_IMAGE=/casper/", $"BOOT_IMAGE=/multiboot/{systemDirectory.Name}/casper/" }, }); //For Fedora Based and derivatives if (File.Exists(Path.Combine(systemDirectory.FullName, "isolinux\\isolinux.cfg")) && File.Exists(Path.Combine(systemDirectory.FullName, "LiveOS\\livecd-iso-to-disk"))) //Probably Fedora based { File.WriteAllText(Path.Combine(systemDirectory.FullName, "isolinux\\isolinux.cfg"), File.ReadAllText( Path.Combine(systemDirectory.FullName, "isolinux\\isolinux.cfg") .Replace("root=live:CDLABEL=", $"root=live:LABEL=MULTIBOOT live_dir=/multiboot/{systemDirectory.Name}/LiveOS NULL="))); } //For Puppy Based and derivatives if (File.Exists(Path.Combine(systemDirectory.FullName, "isolinux.cfg"))) { if (File.Exists(Path.Combine(systemDirectory.FullName, "help2.msg"))) //Probably Puppy based { ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux.cfg"), new Dictionary <string, string> { { "pmedia=cd", $"psubdir=/multiboot/{systemDirectory.Name} psubok=TRUE" }, }); } else if (File.Exists(Path.Combine(systemDirectory.FullName, "help.msg"))) //Probably Puppy based { ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux.cfg"), new Dictionary <string, string> { { "append search", $"append search psubdir=/multiboot/{systemDirectory.Name} psubok=TRUE" }, }); } } //For Clonezilla, and DRBL ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "syslinux\\syslinux.cfg"), new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"live-media-path=/multiboot/{systemDirectory.Name}/live/ initrd=/multiboot/{systemDirectory.Name}/live" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\isolinux.cfg"), new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"live-media-path=/multiboot/{systemDirectory.Name}/live/ initrd=/multiboot/{systemDirectory.Name}/live" }, { "live-media-path=/live", $"live-media-path=/multiboot/{systemDirectory.Name}/live" } //Linux Mint 2014 }); //Xpud if (File.Exists(Path.Combine(systemDirectory.FullName, "boot\\vesamenu.c32")) && File.Exists(Path.Combine(systemDirectory.FullName, "opt\\media"))) { ReplaceStringInFile(Path.Combine(systemDirectory.FullName, configInfo.ConfigPath, configInfo.ConfigFile), new Dictionary <string, string> { { "KERNEL /boot/", $"KERNEL /multiboot/{systemDirectory.Name}/boot/" }, { "/opt/media,/opt/scim", $"/multiboot/{systemDirectory.Name}/opt/media,/multiboot/{systemDirectory.Name}/opt/scim" }, { "DEFAULT /boot/", $"DEFAULT /multiboot/{systemDirectory.Name}/boot/" }, { "MENU BACKGROUND /boot/", $"MENU BACKGROUND /multiboot/{systemDirectory.Name}/boot/" }, { "APPEND initrd=/opt/media", $"APPEND initrd=/multiboot/{systemDirectory.Name}/opt/media" }, }); } //Panda Safe CD, Tails ReplaceStringInFile(Path.Combine(systemDirectory.FullName, Path.Combine(configInfo.ConfigPath.Replace('/', '\\'), "live.cfg")), new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"initrd=/multiboot/{systemDirectory.Name}/live" }, { "append initrd=", $"append noprompt live-media-path=/multiboot/{systemDirectory.Name}/live initrd=" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, Path.Combine(configInfo.ConfigPath.Replace('/', '\\'), "live486.cfg")), //Tails Specific 486 new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"initrd=/multiboot/{systemDirectory.Name}/live" }, { "append initrd=", $"append noprompt live-media-path=/multiboot/{systemDirectory.Name}/live initrd=" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, Path.Combine(configInfo.ConfigPath.Replace('/', '\\'), "live686.cfg")), //Tails Specific new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"initrd=/multiboot/{systemDirectory.Name}/live" }, { "append initrd=", $"append noprompt live-media-path=/multiboot/{systemDirectory.Name}/live initrd=" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, Path.Combine(configInfo.ConfigPath.Replace('/', '\\'), configInfo.ConfigFile)), new Dictionary <string, string> { { "default /isolinux/vesamenu.c32", $"default /multiboot/{systemDirectory.Name}/isolinux/vesamenu.c32" } }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, Path.Combine(configInfo.ConfigPath.Replace('/', '\\'), "stdmenu.cfg")), new Dictionary <string, string> { { "menu background /isolinux", $"menu background /multiboot/{systemDirectory.Name}/isolinux" }, }); ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux\\liveamd64.cfg"), //Tails Specific new Dictionary <string, string> { { "kernel /live", $"kernel /multiboot/{systemDirectory.Name}/live" }, { "initrd=/live", $"initrd=/multiboot/{systemDirectory.Name}/live" }, { "append initrd=", $"append noprompt live-media-path=/multiboot/{systemDirectory.Name}/live initrd=" } }); switch (specialSnowflake) { case SpecialSnowflake.SystemRescueDisk: ReplaceStringInFile(Path.Combine(systemDirectory.FullName, configInfo.ConfigPath, configInfo.ConfigFile), new Dictionary <string, string> { { "INITRD initram.igz", $"INITRD NULL initram.igz\r\nAPPEND subdir=multiboot/{systemDirectory.Name}" }, { "INITRD NULL initram.igz", "INITRD initram.igz" }, { "APPEND docache", $"APPEND subdir=multiboot/{systemDirectory.Name} docache" }, { "APPEND nomodeset", $"APPEND subdir=multiboot/{systemDirectory.Name} nomodeset" }, { "APPEND video=800x600", $"APPEND subdir=multiboot/{systemDirectory.Name} video=800x600" }, { "APPEND root=auto", $"APPEND subdir=multiboot/{systemDirectory.Name} root=auto" }, { "APPEND dostartx", $"APPEND subdir=multiboot/{systemDirectory.Name} dostartx" }, { "kernel /bootdisk", $"kernel /multiboot/{systemDirectory.Name}/bootdisk" }, { "kernel /ntpasswd", $"kernel /multiboot/{systemDirectory.Name}/ntpasswd" }, { "/ntpasswd/initrd.cgz,/ntpasswd/scsi.cgz", $"/multiboot/{systemDirectory.Name}/ntpasswd/initrd.cgz,/multiboot/{systemDirectory.Name}/ntpasswd/scsi.cgz" }, { "initrd=/bootdisk", $"initrd=/multiboot/{systemDirectory.Name}/bootdisk" }, }); break; case SpecialSnowflake.IsoLinuxPrompt0: var isoLinuxFile = new FileInfo(Path.Combine(systemDirectory.FullName, "isolinux.cfg")); if (!isoLinuxFile.Exists) { break; //not important enough to crash, it's just a comfort solution to prevent that boot shit } var content = File.ReadAllText(isoLinuxFile.FullName); File.WriteAllText(isoLinuxFile.FullName, content.Replace("PROMPT 1", "PROMPT 0", StringComparison.OrdinalIgnoreCase)); break; case SpecialSnowflake.UbuntuStudio: ReplaceStringInFile(Path.Combine(systemDirectory.FullName, "isolinux", "isolinux.cfg"), new Dictionary <string, string> { { "ui gfxboot bootlogo", "#ui gfxboot bootlogo" } }); break; } }
public override void Install(DirectoryInfo systemDirectory, string systemName, SpecialSnowflake specialSnowflake, string filename, out MenuItemInfo menuItem, SystemProgressReporter progressReporter) { FileInfo memtestFile = null; progressReporter.ReportStatus(InstallationStatus.ExtractFile); using (var fileStream = File.OpenRead(filename)) { var zipFile = new ZipFile(fileStream); foreach (ZipEntry zipEntry in zipFile) { if (zipEntry.Name.EndsWith(".bin", StringComparison.OrdinalIgnoreCase)) { memtestFile = new FileInfo(Path.Combine(systemDirectory.FullName, zipEntry.Name)); using (var zipStream = zipFile.GetInputStream(zipEntry)) using (var memetestFileStream = memtestFile.OpenWrite()) { var buffer = new byte[4096]; var totalRead = 0d; var length = zipEntry.Size; int read; while ((read = zipStream.Read(buffer, 0, buffer.Length)) > 0) { memetestFileStream.Write(buffer, 0, read); totalRead += read; progressReporter.ReportProgress(totalRead / length); } } break; } } } if (memtestFile == null) { throw new FileNotFoundException(); } var pathWithoutDrive = RemoveDriveFromPath(memtestFile.FullName).Replace('\\', '/'); menuItem = new MenuItemInfo($"LINUX {pathWithoutDrive}"); }
public override void Install(DirectoryInfo systemDirectory, string systemName, SpecialSnowflake specialSnowflake, string filename, out MenuItemInfo menuItem, SystemProgressReporter progressReporter) { progressReporter.ReportStatus(InstallationStatus.ExtractFile); using (var file = new SevenZipExtractor(filename)) { file.Extracting += (sender, args) => { progressReporter.ReportProgress(args.PercentDone / 100d); }; file.ExtractArchive(systemDirectory.FullName); } menuItem = new MenuItemInfo($@"MENU BEGIN Kaspersky Rescue Disk LABEL LIVE MENU LABEL ^Run Kaspersky Rescue Disk from this USB kernel /multiboot/{systemDirectory.Name}/boot/rescue append root=live:LABEL={App.DriveLabel} live_dir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ subdir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ rootfstype=auto vga=791 init=/linuxrc loop=/multiboot/{systemDirectory.Name}/rescue/LiveOS/squashfs.img initrd=/multiboot/{systemDirectory.Name}/boot/rescue.igz kav_rescue_10_lang=en udev liveimg splash quiet doscsi nomodeset label text menu label ^Run Kaspersky Rescue Disk - Text Mode kernel /multiboot/{systemDirectory.Name}/boot/rescue append root=live:LABEL={App.DriveLabel} live_dir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ subdir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ rootfstype=auto vga=791 init=/linuxrc loop=/multiboot/{systemDirectory.Name}/rescue/LiveOS/squashfs.img initrd=/multiboot/{systemDirectory.Name}/boot/rescue.igz kav_rescue_10_lang=en udev liveimg quiet nox kav_rescue_10shell noresume doscsi nomodeset label hwinfo menu label ^Run Hardware Info kernel /multiboot/{systemDirectory.Name}/boot/rescue append root=live:LABEL={App.DriveLabel} live_dir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ subdir=/multiboot/{systemDirectory.Name}/rescue/LiveOS/ rootfstype=auto vga=791 init=/linuxrc loop=/multiboot/{systemDirectory.Name}/rescue/LiveOS/squashfs.img initrd=/multiboot/{systemDirectory.Name}/boot/rescue.igz kav_rescue_10_lang=en udev liveimg quiet softlevel=boot nox hwinfo noresume doscsi nomodeset MENU SEPARATOR LABEL exit_kaspersky MENU LABEL Return to Antivirus Tools MENU EXIT MENU END", true); }
private async Task <bool> DoYourStuff(ProcessViewModel processView) { await Task.Delay(500); //wait for the view to build up and subscribe to the logger event processView.Logger.Status("Check if drive is still plugged in..."); if (!UsbStickSettings.Drive.IsReady) { processView.Logger.Error("Drive is not ready. Please plug it in again"); return(false); } var stopwatch = Stopwatch.StartNew(); //progress: //10 % = install syslinux etc. //60 % = install systems //30 % = download & copy applications processView.Logger.Success("Drive plugged in"); if (UsbStickSettings.FormatDrive) { if (MessageBoxEx.Show(Application.Current.MainWindow, $"Warning: You selected the formatting option. Formatting will erease ALL data on the drive {UsbStickSettings.Drive.Name}. If you want to continue, press ok.", $"Format drive {UsbStickSettings.Drive.Name}", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) != MessageBoxResult.OK) { return(false); } processView.Message = "Format USB stick to FAT32"; processView.Logger.Status($"Formatting drive {UsbStickSettings.Drive.Name} with FAT32"); var driveLetter = UsbStickSettings.Drive.Name.Substring(0, 2); FormatResponse formatResponse; if (User.IsAdministrator) { formatResponse = await Task.Run( () => DriveUtilities.FormatDrive(driveLetter, "FAT32", true, 8192, App.DriveLabel, false)); } else { var process = new Process { StartInfo = { FileName = Assembly.GetExecutingAssembly().Location, Arguments = $"/format {driveLetter}", Verb = "runas" } }; if (!process.Start()) { processView.Logger.Error( "Was not able to restart application with administrator privileges to format the drive"); return(false); } await Task.Run(() => process.WaitForExit()); formatResponse = (FormatResponse)process.ExitCode; } if (formatResponse != FormatResponse.Success) { processView.Logger.Error("Formatting drive failed: " + formatResponse); return(false); } processView.Logger.Success("Successfully formatted drive"); } processView.Message = "Creating bootable stick"; if (UsbStickSettings.Drive.VolumeLabel != App.DriveLabel) { processView.Logger.Status("Change volume label to " + App.DriveLabel); UsbStickSettings.Drive.VolumeLabel = App.DriveLabel; } if (UsbStickSettings.Drive.DriveFormat != "FAT32") { processView.Logger.Warn( $"The drive {UsbStickSettings.Drive.RootDirectory.FullName} is formatted with {UsbStickSettings.Drive.DriveFormat} which may be incompatible with SysLinux (it is recommended to format it as FAT32)"); } var bootStickCreator = new BootStickCreator(UsbStickSettings.Drive, UsbStickSettings.SysLinuxAppearance); processView.CurrentProgress = 0.05; await Task.Run(() => bootStickCreator.CreateBootStick(processView.Logger)); processView.CurrentProgress = 0.1; var installSystemPercentage = UsbStickSettings.ApplicationInfo.Any(x => x.Add) ? 0.6 : 0.9; var systemSizes = UsbStickSettings.Systems.ToDictionary(x => x, y => new FileInfo(y.Filename).Length); long processedSize = 0; var totalSize = systemSizes.Sum(x => x.Value); bool?skipAllExistingSystems = null; for (int i = 0; i < UsbStickSettings.Systems.Count; i++) { var systemInfo = UsbStickSettings.Systems[i]; var progressReporter = new SystemProgressReporter(); progressReporter.ProgressChanged += (sender, d) => processView.CurrentProgress = 0.1 + (processedSize + systemSizes[systemInfo] * d) / totalSize * installSystemPercentage; progressReporter.MessageChanged += (sender, s) => { processView.Message = $"Install {systemInfo.Name} ({i + 1} / {UsbStickSettings.Systems.Count}): " + s; processView.Logger.Status(s); }; if (bootStickCreator.SysLinuxConfigFile.ContainsSystem(systemInfo)) { if (skipAllExistingSystems == true) { continue; } if (skipAllExistingSystems == null) { var directory = bootStickCreator.SysLinuxConfigFile.GetSystemDirectory(systemInfo); var newFileName = Path.GetFileNameWithoutExtension(systemInfo.Filename); if (directory == newFileName) { var applyForAll = false; if (MessageBoxChk.Show(Application.Current.MainWindow, $"The system \"{systemInfo.Name}\" already exists on the drive. Should it be overwritten (else skip)?", systemInfo.Name + " already exists", "Apply for all", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No, ref applyForAll) != MessageBoxResult.Yes) { if (applyForAll) { skipAllExistingSystems = true; } continue; } if (applyForAll) { skipAllExistingSystems = false; } } } await Task.Run(() => bootStickCreator.RemoveSystem(systemInfo)); } processView.Message = $"Install {systemInfo.Name} ({i + 1} / {UsbStickSettings.Systems.Count}): Add to config"; await Task.Run( () => bootStickCreator.AddSystemToBootStick(systemInfo, processView.Logger, progressReporter)); processView.Logger.Success("Added " + systemInfo.Name); processedSize += systemSizes[systemInfo]; } processView.CurrentProgress = 0.7; processView.Logger.Success("All systems installed"); var applicationsToInstall = UsbStickSettings.ApplicationInfo.Where(x => x.Add).ToList(); for (int i = 0; i < applicationsToInstall.Count; i++) { var application = applicationsToInstall[i]; processView.Message = $"Install {application.Name} ({i + 1} / {applicationsToInstall.Count}): Download"; var downloadUrl = await Task.Run(() => application.DownloadUrl.Value); processView.Logger.Status($"Download {downloadUrl}"); var tempFile = FileSystemExtensions.GetFreeTempFileName(application.Extension ?? new FileInfo(new Uri(downloadUrl).AbsolutePath).Extension.Remove(0, 1)); //remove the dot of the extension var webClient = new WebClient(); webClient.DownloadProgressChanged += (sender, args) => processView.CurrentProgress = 0.1 + 0.6 + (0.3 / applicationsToInstall.Count * i + 0.3 / applicationsToInstall.Count * (args.ProgressPercentage / 100d)); await webClient.DownloadFileTaskAsync(downloadUrl, tempFile); processView.Logger.Success("Application downloaded successfully"); processView.Logger.Status("Extract zip archive"); processView.Message = $"Install {application.Name} ({i + 1} / {applicationsToInstall.Count}): Extract"; var targetDirectory = new DirectoryInfo(Path.Combine(UsbStickSettings.Drive.RootDirectory.FullName, "Tools", EnumUtilities.GetDescription(application.ApplicationCategory), application.Name)); if (targetDirectory.Exists) { processView.Logger.Warn("Old application found, removing..."); FileSystemExtensions.DeleteDirectory(targetDirectory.FullName); } targetDirectory.Create(); using (var file = new SevenZipExtractor(tempFile)) using (var autoResetEvent = new AutoResetEvent(false)) { EventHandler <EventArgs> setHandler = (sender, args) => autoResetEvent.Set(); file.ExtractionFinished += setHandler; file.BeginExtractArchive(targetDirectory.FullName); await Task.Run(() => autoResetEvent.WaitOne()); file.ExtractionFinished -= setHandler; } File.Delete(tempFile); var entries = targetDirectory.GetFileSystemInfos(); if (entries.Length == 1 && (entries[0].Attributes & FileAttributes.Directory) == FileAttributes.Directory) { var directory = new DirectoryInfo(entries[0].FullName); await Task.Run(() => { directory.MoveTo(Path.Combine(directory.Parent.FullName, Guid.NewGuid().ToString("D"))); //in case that there's a directory with the same name foreach (var fileInfo in directory.GetFiles()) { fileInfo.MoveTo(Path.Combine(targetDirectory.FullName, fileInfo.Name)); } foreach (var directoryInfo in directory.GetDirectories()) { directoryInfo.MoveTo(Path.Combine(targetDirectory.FullName, directoryInfo.Name)); } directory.Delete(); }); } processView.Logger.Success("Application successfully installed"); } processView.CurrentProgress = 1; processView.Logger.Success($"Finished in {stopwatch.Elapsed.ToString("g")}"); return(true); }