internal static void Associate(LocalAppData appData, bool quiet = false, Form owner = default(Form)) { if (appData?.Settings?.FileTypes?.Any() != true) { MessageBoxEx.Show(owner, Language.GetText(nameof(en_US.associateBtnMsg)), Settings.Title, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!Elevation.IsAdministrator) { if (owner != default(Form)) { owner.TopMost = false; owner.Enabled = false; TaskBarProgress.SetState(owner.Handle, TaskBarProgressFlags.Indeterminate); } var bw = new BackgroundWorker(); bw.DoWork += (sender, args) => { using (var process = ProcessEx.Start(PathEx.LocalPath, $"{ActionGuid.FileTypeAssociation} \"{appData.Key}\"", true, false)) if (!process?.HasExited == true) { process.WaitForExit(); } }; bw.RunWorkerCompleted += (sender, args) => { if (owner == default(Form)) { return; } TaskBarProgress.SetState(owner.Handle, TaskBarProgressFlags.NoProgress); if (WinApi.NativeHelper.GetForegroundWindow() != owner.Handle) { WinApi.NativeHelper.SetForegroundWindow(owner.Handle); } owner.Enabled = true; owner.TopMost = true; }; bw.RunWorkerAsync(); return; } var assocData = new FileTypeAssocData { AppKey = appData.Key, InstallId = Settings.SystemInstallId }; using (var dialog = new ResourcesEx.IconBrowserDialog(Settings.IconResourcePath, Settings.Window.Colors.BaseDark, Settings.Window.Colors.ControlText, Settings.Window.Colors.Button, Settings.Window.Colors.ButtonText, Settings.Window.Colors.ButtonHover)) { dialog.TopMost = true; dialog.Plus(); dialog.ShowDialog(); if (!string.IsNullOrEmpty(dialog.IconPath)) { assocData.IconPath = dialog.IconPath; assocData.IconId = dialog.IconId.ToString(); } } if (!FileEx.Exists(assocData.IconPath) || string.IsNullOrEmpty(assocData.IconId)) { goto Cancel; } MessageBoxEx.ButtonText.OverrideEnabled = true; MessageBoxEx.ButtonText.Yes = "App"; MessageBoxEx.ButtonText.No = "Launcher"; MessageBoxEx.ButtonText.Cancel = Language.GetText(nameof(en_US.Cancel)); var result = MessageBoxEx.Show(Language.GetText(nameof(en_US.AssociateAppWayQuestion)), Settings.Title, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); switch (result) { case DialogResult.Yes: assocData.StarterPath = EnvironmentEx.GetVariablePathFull(appData.FilePath, false, false); break; case DialogResult.No: assocData.StarterPath = EnvironmentEx.GetVariablePathFull(PathEx.LocalPath, false, false); break; default: goto Cancel; } if (FileEx.Exists(assocData.StarterPath)) { appData.Settings.FileTypeAssoc = assocData; } else { goto Cancel; } assocData = appData.Settings?.FileTypeAssoc; assocData?.SystemRegistryAccess?.AssociateFileTypes(false); return; Cancel: MessageBoxEx.Show(owner, Language.GetText(nameof(en_US.OperationCanceledMsg)), MessageBoxButtons.OK, MessageBoxIcon.Information); }
internal static void AssociateFileTypes(string appName) { var types = Ini.Read(appName, "FileTypes"); if (string.IsNullOrWhiteSpace(types)) { MessageBoxEx.Show(Lang.GetText("associateBtnMsg"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!Elevation.IsAdministrator) { using (var p = ProcessEx.Start(PathEx.LocalPath, $"{ActionGuid.FileTypeAssociation} \"{appName}\"", true, false)) if (p != null && !p.HasExited) p.WaitForExit(); return; } string iconData = null; using (Form dialog = new ResourcesEx.IconBrowserDialog(SystemResourcePath, Colors.BaseDark, Colors.ControlText, Colors.Button, Colors.ButtonText, Colors.ButtonHover)) { dialog.TopMost = true; dialog.AddLoadingTimeStopwatch(); dialog.ShowDialog(); if (dialog.Text.Count(c => c == ',') == 1) iconData = dialog.Text; } if (string.IsNullOrWhiteSpace(iconData)) { MessageBoxEx.Show(Lang.GetText("OperationCanceledMsg"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } var iconPath = iconData.Split(',')[0]; iconData = iconData.Replace(iconData, GetEnvironmentVariablePath(iconPath)); string appPath; MessageBoxEx.ButtonText.OverrideEnabled = true; MessageBoxEx.ButtonText.Yes = "App"; MessageBoxEx.ButtonText.No = "Launcher"; MessageBoxEx.ButtonText.Cancel = Lang.GetText("Cancel"); var result = MessageBoxEx.Show(Lang.GetText("associateAppWayQuestion"), "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); switch (result) { case DialogResult.Yes: appPath = GetAppPath(appName); break; default: MessageBoxEx.Show(Lang.GetText("OperationCanceledMsg"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(appPath)) { MessageBoxEx.Show(Lang.GetText("OperationCanceledMsg"), MessageBoxButtons.OK, MessageBoxIcon.Information); return; } var restPointDir = PathEx.Combine("%CurDir%\\Restoration"); try { if (!Directory.Exists(restPointDir)) { Directory.CreateDirectory(restPointDir); Data.SetAttributes(restPointDir, FileAttributes.ReadOnly | FileAttributes.Hidden); var iniPath = Path.Combine(restPointDir, "desktop.ini"); if (!File.Exists(iniPath)) File.Create(iniPath).Close(); Ini.Write(".ShellClassInfo", "IconResource", "..\\Assets\\win10.folder.red.ico,0", iniPath); Data.SetAttributes(iniPath, FileAttributes.System | FileAttributes.Hidden); } } catch (Exception ex) { Log.Write(ex); } restPointDir = Path.Combine(restPointDir, Environment.MachineName, Win32_OperatingSystem.InstallDate?.ToString("F").EncryptToMd5().Substring(24), appName, "FileAssociation", DateTime.Now.ToString("yy-MM-dd")); var backupCount = 0; if (Directory.Exists(restPointDir)) backupCount = Directory.GetFiles(restPointDir, "*.ini", SearchOption.TopDirectoryOnly).Length; else try { Directory.CreateDirectory(restPointDir); } catch (Exception ex) { Log.Write(ex); } var restPointCfgPath = Path.Combine(restPointDir, $"{backupCount}.ini"); if (!File.Exists(restPointCfgPath)) File.Create(restPointCfgPath).Close(); restPointDir = Path.Combine(restPointDir, backupCount.ToString()); foreach (var type in (types.Contains(",") ? types : $"{types},").Split(',')) { if (string.IsNullOrWhiteSpace(type) || type.StartsWith(".")) continue; if (Reg.SubKeyExist($"HKCR\\.{type}")) { string restKeyName = $"KeyBackup_.{type}_#####.reg"; var count = 0; if (Directory.Exists(restPointDir)) count = Directory.GetFiles(restPointDir, restKeyName.Replace("#####", "*"), SearchOption.TopDirectoryOnly).Length; else try { Directory.CreateDirectory(restPointDir); } catch (Exception ex) { Log.Write(ex); } restKeyName = restKeyName.Replace("#####", count.ToString()); var restKeyPath = Path.Combine(restPointDir, restKeyName); Reg.ExportKeys(restKeyPath, $"HKCR\\.{type}"); if (File.Exists(restKeyPath)) Ini.Write(type.EncryptToMd5(), "KeyBackup", $"{backupCount}\\{restKeyName}", restPointCfgPath); } else Ini.Write(type.EncryptToMd5(), "KeyAdded", $"HKCR\\.{type}", restPointCfgPath); string typeKey = $"PortableAppsSuite_{type}file"; if (Reg.SubKeyExist($"HKCR\\{typeKey}")) { string restKeyName = $"KeyBackup_{typeKey}_#####.reg"; var count = 0; if (Directory.Exists(restPointDir)) count = Directory.GetFiles(restPointDir, restKeyName.Replace("#####", "*"), SearchOption.AllDirectories).Length; restKeyName = restKeyName.Replace("#####", count.ToString()); var restKeyPath = Path.Combine(restPointDir, restKeyName); Reg.ExportKeys(restKeyPath.Replace("#####", count.ToString()), $"HKCR\\{typeKey}"); if (File.Exists(restKeyPath)) Ini.Write(typeKey.EncryptToMd5(), "KeyBackup", $"{backupCount}\\{restKeyName}", restPointCfgPath); } else Ini.Write(typeKey.EncryptToMd5(), "KeyAdded", $"HKCR\\{typeKey}", restPointCfgPath); Reg.WriteValue(Reg.RegKey.ClassesRoot, $".{type}", null, typeKey, Reg.RegValueKind.ExpandString); var iconRegEnt = Reg.ReadStringValue(Reg.RegKey.ClassesRoot, $"{typeKey}\\DefaultIcon", null); if (iconRegEnt != iconData) Reg.WriteValue(Reg.RegKey.ClassesRoot, $"{typeKey}\\DefaultIcon", null, iconData, Reg.RegValueKind.ExpandString); var openCmdRegEnt = Reg.ReadStringValue(Reg.RegKey.ClassesRoot, $"{typeKey}\\shell\\open\\command", null); string openCmd = $"\"{GetEnvironmentVariablePath(appPath)}\" \"%1\""; if (openCmdRegEnt != openCmd) Reg.WriteValue(Reg.RegKey.ClassesRoot, $"{typeKey}\\shell\\open\\command", null, openCmd, Reg.RegValueKind.ExpandString); Reg.RemoveValue(Reg.RegKey.ClassesRoot, $"{typeKey}\\shell\\open\\command", "DelegateExecute"); } MessageBoxEx.Show(Lang.GetText("OperationCompletedMsg"), MessageBoxButtons.OK, MessageBoxIcon.Information); }