using System; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; namespace TweetDuck.Core.Utils{ static class WindowsUtils{ private static readonly Lazy<Regex> RegexStripHtmlStyles = new Lazy<Regex>(() => new Regex(@"\s?(?:style|class)="".*?"""), false); private static readonly Lazy<Regex> RegexOffsetClipboardHtml = new Lazy<Regex>(() => new Regex(@"(?<=EndHTML:|EndFragment:)(\d+)"), false); public static int CurrentProcessID { get; } public static bool ShouldAvoidToolWindow { get; } static WindowsUtils(){ using(Process me = Process.GetCurrentProcess()){ CurrentProcessID = me.Id; } Version ver = Environment.OSVersion.Version; ShouldAvoidToolWindow = ver.Major == 6 && ver.Minor == 2; // windows 8/10 } public static void CreateDirectoryForFile(string file){ string dir = Path.GetDirectoryName(file); if (dir == null){ throw new ArgumentException("Invalid file path: "+file); } else if (dir.Length > 0){ Directory.CreateDirectory(dir); } } public static bool CheckFolderWritePermission(string path){ string testFile = Path.Combine(path, ".test"); try{ Directory.CreateDirectory(path); using(File.Create(testFile)){} File.Delete(testFile); return true; }catch{ return false; } } 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 file", e.Message, 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 void ClipboardStripHtmlStyles(){ if (!Clipboard.ContainsText(TextDataFormat.Html) || !Clipboard.ContainsText(TextDataFormat.UnicodeText)){ return; } string originalText = Clipboard.GetText(TextDataFormat.UnicodeText); string originalHtml = Clipboard.GetText(TextDataFormat.Html); string updatedHtml = RegexStripHtmlStyles.Value.Replace(originalHtml, string.Empty); int removed = originalHtml.Length-updatedHtml.Length; updatedHtml = RegexOffsetClipboardHtml.Value.Replace(updatedHtml, match => (int.Parse(match.Value)-removed).ToString().PadLeft(match.Value.Length, '0')); DataObject obj = new DataObject(); obj.SetText(originalText, TextDataFormat.UnicodeText); obj.SetText(updatedHtml, TextDataFormat.Html); SetClipboardData(obj); } public static void SetClipboard(string text, TextDataFormat format){ if (string.IsNullOrEmpty(text)){ return; } DataObject obj = new DataObject(); obj.SetText(text, format); SetClipboardData(obj); } private static void SetClipboardData(DataObject obj){ try{ Clipboard.SetDataObject(obj); }catch(ExternalException e){ Program.Reporter.HandleException("Clipboard Error", "TweetDuck could not access the clipboard as it is currently used by another process.", true, e); } } } }