/// <summary> /// Location of the installed executable app /// </summary> public static string InstalledExe(XmlData data) => Path.Combine(InstalledDirectory(data.Id), data.ExeName);
public static async Task UninstallAsync(string id, IProgress <ProgressData> progress = null) { if (Debugger.IsAttached) { return; } #if DEBUG return; #endif if (Environment.OSVersion.Platform == PlatformID.Win32NT) { progress?.Report(new ProgressData("Deleting registry entries")); RegistryEntries.UnregisterUninstallInfo(id); //Delete the desktop shortcut try { XmlData data = await XmlData.ReadAsync(Path2.LocalManifest(id)).ConfigureAwait(false); progress?.Report(new ProgressData("Deleting shortcuts")); string shortcut = Path2.DesktopLinkPath(data.Name); if (File.Exists(shortcut)) { File.Delete(shortcut); } //Delete the Pinned To Taskbar shortcut shortcut = Path2.TaskBarShortcutPath(data.Name); if (File.Exists(shortcut)) { File.Delete(shortcut); } //Delete the Pinned To Start Menu shortcut //Delete Start Menu Shortcut } catch { } } await Task.Run(() => { //Delete files DirectoryInfo rootDir = new DirectoryInfo(Path2.InstalledDirectory(id)); if (rootDir.Exists) { var files = new List <FileSystemInfo>(rootDir.GetFileSystemInfos("*", SearchOption.AllDirectories)); files.Sort((x, y) => x.FullName.CompareTo(y.FullName)); files.Reverse(); double total = files.Count; double cur = 0; int lastPerc = 0; progress?.Report(new ProgressData("Deleting files", 0)); foreach (var file in files) { try { file.Delete(); } catch { NativeMethods.DeleteAfterReboot(file.FullName); } int perc = Math.Min(99, (int)Math.Floor((++cur / total) * 100)); if (perc != lastPerc) { lastPerc = perc; progress?.Report(new ProgressData("Deleting files", perc)); } } } string xmlPath = Path2.LocalManifest(id); if (File.Exists(xmlPath)) { File.Delete(xmlPath); } }); progress?.Report(new ProgressData("Uninstall Complete", 100, true)); }
private async void frmInstaller_Load(object sender, EventArgs e) { try { using var mre = new ManualResetEvent(false); IProgress <ProgressData> prog = new Progress <ProgressData>(p => { lblStatus.Text = p.Status; pbProgress.Value = p.Percent; if (p.Done) { mre.Set(); } }); if (_processId > 0) { await Task.Run(() => { prog.Report(new ProgressData("Waiting for previous app to close")); try { Process.GetProcessById(_processId).WaitForExit(); } catch { } }); } var ret = await Installer.InstallAsync(_packageFile, prog, _createShortcuts); await mre.WaitOneAsync(); if (!ret.Success) { throw ret.Error; } string exePath = Path2.InstalledExe(XmlData.Read(Path2.LocalManifest(ret.Id))); if (string.IsNullOrWhiteSpace(_relaunchArgs)) { Process.Start(exePath); } else { string args = Encoding.UTF8.GetString(Convert.FromBase64String(_relaunchArgs)); Process.Start(exePath, args); } ErrorCode = 0; } catch (AggregateException ex) { Program.ShowErrors(ex.InnerExceptions); if (ex.HResult != 0) { ErrorCode = ex.HResult; } } catch (Exception ex) { Program.ShowErrors(new Exception[] { ex }); if (ex.HResult != 0) { ErrorCode = ex.HResult; } } Close(); }
internal static async Task <InstallResult> InstallAsync(string url, IProgress <ProgressData> progress, bool createShortcuts) { InstallResult ret = new InstallResult { Success = true }; if (Debugger.IsAttached) { return(ret); } #if DEBUG return(ret); #endif try { //Read the package progress?.Report(new ProgressData("Reading package")); XmlData serverData = await XmlData.ReadAsync(url).ConfigureAwait(false); ret.Id = serverData.Id; ret.Version = serverData.Version; //If installed, check installed version try { var localVersion = GetInstalledVersion(ret.Id); if (localVersion >= serverData.Version) { return(ret); } } catch { } //Install! progress?.Report(new ProgressData($"Preparing to install v{serverData.Version}")); //Unzip from the web string status = $"Installing v{serverData.Version}"; string zipSrc = Path2.DepoPackage(serverData); if (StreamHelper.IsWebUrl(zipSrc)) { using var response = await StreamHelper.GetWebResponseAsync(zipSrc).ConfigureAwait(false); using var source = response.GetResponseStream(); await UnzipPackage(source, Path2.InstalledDirectory(serverData.Id), status, progress).ConfigureAwait(false); } else { using var source = StreamHelper.OpenAsyncRead(zipSrc); await UnzipPackage(source, Path2.InstalledDirectory(serverData.Id), status, progress).ConfigureAwait(false); } if (Environment.OSVersion.Platform == PlatformID.Win32NT) { RegistryEntries.RegisterUninstallInfo(serverData); //Create desktop shortcut string shortcutFile = Path2.DesktopLinkPath(serverData.Name); if (createShortcuts || File.Exists(shortcutFile)) { Shortcut.Create(shortcutFile, Path2.InstalledExe(serverData)); } } else { Process.Start("chmod", $"+x \"{Path2.InstalledExe(serverData)}\""); } //Success serverData.Save(Path2.LocalManifest(serverData.Id)); progress?.Report(new ProgressData("Done", 100, true)); } catch (Exception ex) { ret.Success = false; ret.Error = ex; } return(ret); }
static int Main(string[] args) { int ret = -1; #if !NETFX Application.SetHighDpiMode(HighDpiMode.SystemAware); #endif Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { var parsed = Parser.Default.ParseArguments <CLOptions.BuildOptions, CLOptions.InstallMeOptions, CLOptions.InstallOptions, CLOptions.UpdateOptions, CLOptions.UninstallOptions>(args); parsed.WithParsed <CLOptions.BuildOptions>(opts => { using var frm = new frmPackager(opts); Application.Run(frm); ret = frm.ErrorCode; }); parsed.WithParsed <CLOptions.InstallOptions>(opts => { using var frm = new frmInstaller(opts.Package, 0, true, null); Application.Run(frm); ret = frm.ErrorCode; }); parsed.WithParsed <CLOptions.UpdateOptions>(opts => { string packageFile = Path2.DepoManifest(XmlData.Read(Path2.LocalManifest(opts.AppId))); using var frm = new frmInstaller(packageFile, opts.ProcessId, false, opts.RelaunchArgs); Application.Run(frm); ret = frm.ErrorCode; }); parsed.WithParsed <CLOptions.UninstallOptions>(opts => { using var frm = new frmUninstaller(opts); Application.Run(frm); ret = frm.ErrorCode; }); parsed.WithParsed <CLOptions.InstallMeOptions>(opts => { if (Manager.InstallMe(opts)) { if (!opts.NoGui) { MessageBox.Show("SUAG Installed", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); } } ret = 0; }); } catch (AggregateException ex) { ShowErrors(ex.InnerExceptions); if (ex.HResult != 0) { ret = ex.HResult; } } catch (Exception ex) { ShowErrors(new Exception[] { ex }); if (ex.HResult != 0) { ret = ex.HResult; } } return(ret); }
static int Main(string[] args) { int ret = 0; try { int cursorTop = -1; int cursorLeft = -1; int maxLen = 0; string lastStatus = null; try { cursorTop = Console.CursorTop; cursorLeft = Console.CursorLeft; } catch { } ManualResetEvent mre = new ManualResetEvent(false); IProgress <ProgressData> prog = new Progress <ProgressData>(p => { string status = p.Status; if (p.Percent > 0) { status += $" {p.Percent}%"; } if (maxLen > status.Length) { status += new string(' ', maxLen - status.Length); } if (status != lastStatus) { bool setPosWorked = false; try { Console.SetCursorPosition(cursorLeft, cursorTop); setPosWorked = true; } catch { } Console.WriteLine(status); lastStatus = status; if (setPosWorked) { maxLen = Math.Max(maxLen, lastStatus.Length); } } if (p.Done) { mre.Set(); } }); var parsed = Parser.Default.ParseArguments <CLOptions.BuildOptions, CLOptions.InstallMeOptions, CLOptions.InstallOptions, CLOptions.UpdateOptions, CLOptions.UninstallOptions>(args); parsed.WithParsed <CLOptions.BuildOptions>(opts => { Packager.BuildPackageAsync(opts, prog).Wait(); mre.WaitOne(); }); parsed.WithParsed <CLOptions.InstallOptions>(opts => { var installed = Installer.InstallAsync(opts.Package, prog, true).Result; mre.WaitOne(); if (!installed.Success) { throw installed.Error; } var installedData = XmlData.Read(Path2.LocalManifest(installed.Id)); Process.Start(Path2.InstalledExe(installedData)); }); parsed.WithParsed <CLOptions.UpdateOptions>(opts => { if (opts.ProcessId > 0) { try { Process.GetProcessById(opts.ProcessId).WaitForExit(); } catch { } } var updated = Installer.InstallAsync(Path2.DepoManifest(XmlData.Read(Path2.LocalManifest(opts.AppId))), prog, false).Result; mre.WaitOne(); if (!updated.Success) { throw updated.Error; } string exePath = Path2.InstalledExe(XmlData.Read(Path2.LocalManifest(updated.Id))); if (string.IsNullOrWhiteSpace(opts.RelaunchArgs)) { Process.Start(exePath); } else { string relaunchArgs = Encoding.UTF8.GetString(Convert.FromBase64String(opts.RelaunchArgs)); Process.Start(exePath, relaunchArgs); } }); parsed.WithParsed <CLOptions.UninstallOptions>(opts => { Uninstaller.UninstallAsync(opts.AppId, prog).Wait(); mre.WaitOne(); }); parsed.WithParsed <CLOptions.InstallMeOptions>(opts => { if (Manager.InstallMe(opts)) { Console.WriteLine("SAUC Installed"); if (!opts.NoGui) { Console.ReadLine(); } } }); parsed.WithNotParsed <object>(opts => { //Arguments error ret = -1; }); } catch (AggregateException ex) { Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Red; foreach (var subEx in ex.InnerExceptions) { Console.WriteLine(subEx.Message); } Console.ResetColor(); Console.WriteLine(); ret = ex.HResult == 0 ? -1 : ex.HResult; } catch (Exception ex) { Console.WriteLine(); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(ex.Message); Console.ResetColor(); Console.WriteLine(); ret = ex.HResult == 0 ? -1 : ex.HResult; } return(ret); }
public static async Task BuildPackageAsync(CLOptions.BuildOptions opts, IProgress <ProgressData> progress = null) { opts.SourceExe = Path.GetFullPath(opts.SourceExe); //if (!opts.SourceExe.EndsWith(".exe", StringComparison.CurrentCultureIgnoreCase)) // throw new Exception("The source-exe argument must be an executable file"); if (!File.Exists(opts.SourceExe)) { throw new FileNotFoundException("The executable file was not found", opts.SourceExe); } if (string.IsNullOrWhiteSpace(opts.Name)) { opts.Name = Path.GetFileNameWithoutExtension(opts.SourceExe); } //Get info progress?.Report(new ProgressData("Gathering info")); DateTime dt = DateTime.UtcNow; Version version = new Version ( dt.Year - 2000, dt.Month, dt.Day, (dt.Hour * 60) + dt.Minute ); if (!string.IsNullOrWhiteSpace(opts.Version)) { version = new Version(opts.Version); } string inDir = Path.GetDirectoryName(opts.SourceExe); var sourceFiles = new DirectoryInfo(inDir).GetFiles("*", SearchOption.AllDirectories); double totalLength = sourceFiles.Sum(item => item.Length); //Fix the input folder - if it doesn't end with the dir sep char, then the entries in the zip will be wrong if (!inDir.EndsWith(Path.DirectorySeparatorChar.ToString())) { inDir += Path.DirectorySeparatorChar; } string exeName = Path.GetFileName(opts.SourceExe); string xmlFile = Path.Combine(opts.TargetDir, "packages", opts.AppId + ThisApp.Extension); string zipFile = Path.Combine(opts.TargetDir, "packages", opts.AppId + ".zip"); string friendlyFile = Path.Combine(opts.TargetDir, opts.Name + ThisApp.Extension); string msg = $"Building v{version}"; if (opts.ForceSUAG && ThisApp.Extension == ".suac") { xmlFile = Path.ChangeExtension(xmlFile, ".suag"); friendlyFile = Path.ChangeExtension(friendlyFile, ".suag"); } //Build the xml progress?.Report(new ProgressData(msg)); var package = new XmlData { Depo = opts.Depo, ExeName = exeName, Id = opts.AppId, Name = opts.Name, Version = version }; package.Save(xmlFile); package.Save(friendlyFile); //Create the package double totalRead = 0; int lastPerc = 0; byte[] buffer = new byte[Constants.BUFFER_SIZE]; using (var zipStream = StreamHelper.CreateAsyncWrite(zipFile)) { using var archive = new ZipArchive(zipStream, ZipArchiveMode.Create); foreach (var file in sourceFiles) { using var fileStream = file.OpenAsyncRead(); string entryName = file.FullName.Substring(inDir.Length); using var entryStream = archive.CreateEntry(entryName, CompressionLevel.Optimal).Open(); long readFromFile = 0; while (readFromFile < file.Length) { int thisRead = await fileStream.ReadAsync(buffer, 0, Constants.BUFFER_SIZE).ConfigureAwait(false); await entryStream.WriteAsync(buffer, 0, thisRead).ConfigureAwait(false); readFromFile += thisRead; totalRead += thisRead; int perc = Math.Min((int)Math.Floor((totalRead / totalLength) * 100), 99); if (perc != lastPerc) { lastPerc = perc; progress?.Report(new ProgressData(msg, perc)); } } } } progress?.Report(new ProgressData(msg, 100, true)); }