public bool StartInstall() { InstallStarted = false; if (Transfer.IsBusy || !File.Exists(DestPath)) { return(false); } const string nonHash = "None"; var fileHash = default(string); foreach (var(_, item2, _, item4) in SrcData) { if (!item4) { continue; } if (fileHash == default || fileHash == nonHash) { switch (item2.Length) { case Crypto.Md5.HashLength: fileHash = DestPath.EncryptFile(); break; case Crypto.Sha1.HashLength: fileHash = DestPath.EncryptFile(ChecksumAlgorithm.Sha1); break; case Crypto.Sha256.HashLength: fileHash = DestPath.EncryptFile(ChecksumAlgorithm.Sha256); break; case Crypto.Sha384.HashLength: fileHash = DestPath.EncryptFile(ChecksumAlgorithm.Sha384); break; case Crypto.Sha512.HashLength: fileHash = DestPath.EncryptFile(ChecksumAlgorithm.Sha512); break; default: fileHash = nonHash; break; } } if (fileHash != nonHash && !fileHash.EqualsEx(item2)) { switch (MessageBoxEx.Show(string.Format(CultureInfo.InvariantCulture, Language.GetText(nameof(en_US.ChecksumErrorMsg)), Path.GetFileName(DestPath)), Resources.GlobalTitle, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3)) { case DialogResult.Ignore: break; case DialogResult.Retry: AutoRetry = true; continue; default: continue; } } if (Directory.Exists(AppData.InstallDir)) { if (!BreakFileLocks(AppData.InstallDir, false)) { MessageBoxEx.Show(string.Format(CultureInfo.InvariantCulture, Language.GetText(nameof(en_US.InstallSkippedMsg)), AppData.Name), Resources.GlobalTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); continue; } } if (DestPath.EndsWithEx(".7z", ".rar", ".zip")) { if (!File.Exists(CorePaths.FileArchiver)) { throw new PathNotFoundException(CorePaths.FileArchiver); } using (var process = Compaction.SevenZipHelper.Unzip(DestPath, AppData.InstallDir)) if (process?.HasExited == false) { process.WaitForExit(); } } else { var appsDir = CorePaths.AppsDir; using (var process = ProcessEx.Start(DestPath, appsDir, $"/DESTINATION=\"{appsDir}\\\"", Elevation.IsAdministrator, false)) if (process?.HasExited == false) { process.WaitForInputIdle(0x1000); try { var buttons = Settings.NsisButtons; if (buttons == null) { throw new NotSupportedException(); } var okButton = buttons.Take(2).ToArray(); var langId = WinApi.NativeHelper.GetUserDefaultUILanguage(); var wndState = langId == 1031 || langId == 1033 || langId == 2057 ? WinApi.ShowWindowFlags.ShowMinNoActive : WinApi.ShowWindowFlags.ShowNa; var stopwatch = Stopwatch.StartNew(); var minimized = new List <IntPtr>(); var counter = new CounterInvestor <int>(); while (stopwatch.Elapsed.TotalMinutes < 5d) { if (process.HasExited) { break; } string title; using (var proc = Process.GetProcessById(process.Id)) title = proc.MainWindowTitle; if (string.IsNullOrEmpty(title)) { continue; } var parent = WinApi.NativeHelper.FindWindow(null, title); if (parent == IntPtr.Zero) { continue; } if (!minimized.Contains(parent) && WinApi.NativeHelper.ShowWindowAsync(parent, wndState)) { minimized.Add(parent); } foreach (var button in buttons) { var child = WinApi.NativeHelper.FindWindowEx(parent, IntPtr.Zero, "Button", button); if (child == IntPtr.Zero) { continue; } if (counter.Increase(button.GetHashCode()) > 10) { if (button.EqualsEx(okButton)) { goto Manually; } continue; } WinApi.NativeHelper.SendMessage(child, 0xf5u, IntPtr.Zero, IntPtr.Zero); } } } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } Manually: if (!process.HasExited) { try { using (var proc = Process.GetProcessById(process.Id)) { var hWnd = WinApi.NativeHelper.FindWindow(null, proc.MainWindowTitle); WinApi.NativeHelper.ShowWindowAsync(hWnd, WinApi.ShowWindowFlags.ShowNormal); WinApi.NativeHelper.SetForegroundWindow(hWnd); WinApi.NativeHelper.SetWindowPos(hWnd, new IntPtr(-1), 0, 0, 0, 0, WinApi.SetWindowPosFlags.NoMove | WinApi.SetWindowPosFlags.NoSize); } } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); } process.WaitForExit(); } } // fix for messy app installer var retries = 0; retry: try { var appDirs = new[] { Path.Combine(appsDir, "App"), Path.Combine(appsDir, "Data"), Path.Combine(appsDir, "Other") }; if (appDirs.Any(Directory.Exists)) { if (!Directory.Exists(AppData.InstallDir)) { Directory.CreateDirectory(AppData.InstallDir); } else { BreakFileLocks(AppData.InstallDir); foreach (var dir in new[] { "App", "Other" }.Select(name => Path.Combine(AppData.InstallDir, name)).Where(Directory.Exists)) { Directory.Delete(dir, true); } foreach (var file in Directory.EnumerateFiles(AppData.InstallDir, "*.*", SearchOption.TopDirectoryOnly)) { File.Delete(file); } } foreach (var dir in appDirs) { if (!Directory.Exists(dir)) { continue; } var dirName = Path.GetFileName(dir); if (string.IsNullOrEmpty(dirName)) { continue; } BreakFileLocks(dir); if (dirName.EqualsEx("Data")) { Directory.Delete(dir, true); continue; } var innerDir = Path.Combine(AppData.InstallDir, dirName); Directory.Move(innerDir, dir); } foreach (var file in Directory.EnumerateFiles(appsDir, "*.*", SearchOption.TopDirectoryOnly)) { if (FileEx.IsHidden(file) || file.EndsWithEx(".7z", ".rar", ".zip", ".paf.exe")) { continue; } var fileName = Path.GetFileName(file); if (string.IsNullOrEmpty(fileName)) { continue; } BreakFileLocks(file); var innerFile = Path.Combine(AppData.InstallDir, fileName); File.Move(innerFile, file); } } } catch (Exception ex) when(ex.IsCaught()) { Log.Write(ex); if (retries >= 15) { return(false); } retries++; Thread.Sleep(1000); goto retry; } } FileEx.TryDelete(DestPath); InstallStarted = true; return(true); } return(false); }