using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Threading; using Microsoft.Win32; namespace TweetDuck.Utils{ static class WindowsUtils{ private static readonly bool IsWindows8OrNewer = OSVersionEquals(major: 6, minor: 2); // windows 8/10 public static bool ShouldAvoidToolWindow { get; } = IsWindows8OrNewer; public static bool IsAeroEnabled => IsWindows8OrNewer || (NativeMethods.DwmIsCompositionEnabled(out bool isCompositionEnabled) == 0 && isCompositionEnabled); private static bool OSVersionEquals(int major, int minor){ System.Version ver = Environment.OSVersion.Version; return ver.Major == major && ver.Minor == minor; } public static bool OpenAssociatedProgram(string file, string arguments = "", bool runElevated = false){ try{ using(Process.Start(new ProcessStartInfo{ FileName = file, Arguments = arguments, Verb = runElevated ? "runas" : string.Empty, ErrorDialog = true })){ return true; } }catch(Win32Exception e) when (e.NativeErrorCode == 0x000004C7){ // operation canceled by the user return false; }catch(Exception e){ Program.Reporter.HandleException("Error Opening Program", "Could not open the associated program for " + file, true, e); return false; } } public static bool TrySleepUntil(Func<bool> test, int timeoutMillis, int timeStepMillis){ for(int waited = 0; waited < timeoutMillis; waited += timeStepMillis){ if (test()){ return true; } Thread.Sleep(timeStepMillis); } return false; } public static void TryDeleteFolderWhenAble(string path, int timeout){ new Thread(() => { TrySleepUntil(() => { try{ Directory.Delete(path, true); return true; }catch(DirectoryNotFoundException){ return true; }catch{ return false; } }, timeout, 500); }).Start(); } public static IEnumerable<Browser> FindInstalledBrowsers(){ static IEnumerable<Browser> ReadBrowsersFromKey(RegistryHive hive){ using RegistryKey root = RegistryKey.OpenBaseKey(hive, RegistryView.Default); using RegistryKey browserList = root.OpenSubKey(@"SOFTWARE\Clients\StartMenuInternet", false); if (browserList == null){ yield break; } foreach(string sub in browserList.GetSubKeyNames()){ using RegistryKey browserKey = browserList.OpenSubKey(sub, false); using RegistryKey shellKey = browserKey?.OpenSubKey(@"shell\open\command"); if (shellKey == null){ continue; } string browserName = browserKey.GetValue(null) as string; string browserPath = shellKey.GetValue(null) as string; if (string.IsNullOrEmpty(browserName) || string.IsNullOrEmpty(browserPath)){ continue; } if (browserPath[0] == '"' && browserPath[browserPath.Length - 1] == '"'){ browserPath = browserPath.Substring(1, browserPath.Length - 2); } yield return new Browser(browserName, browserPath); } } HashSet<Browser> browsers = new HashSet<Browser>(); try{ browsers.UnionWith(ReadBrowsersFromKey(RegistryHive.CurrentUser)); browsers.UnionWith(ReadBrowsersFromKey(RegistryHive.LocalMachine)); }catch{ // oops I guess } return browsers; } public sealed class Browser{ public string Name { get; } public string Path { get; } public Browser(string name, string path){ this.Name = name; this.Path = path; } public override int GetHashCode() => Name.GetHashCode(); public override bool Equals(object obj) => obj is Browser other && Name == other.Name; public override string ToString() => Name; } } }