#if DEBUG using System; using System.Diagnostics; using System.IO; using System.Reflection; using TweetDuck.Browser; using TweetDuck.Management; using TweetLib.Core.Features.Plugins; namespace TweetDuck.Resources { sealed class ScriptLoaderDebug : ScriptLoader { private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../"))); private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp")); private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "bld", "post_build.exe"); private static string FixPathSlash(string path) { return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + '\\'; } public ScriptLoaderDebug() { if (File.Exists(HotSwapRebuildScript)) { Debug.WriteLine("Activating resource hot swap..."); ResetHotSwap(); System.Windows.Forms.Application.ApplicationExit += (sender, args) => ResetHotSwap(); } } public override void OnReloadTriggered() { HotSwap(); } protected override string LocateFile(string path) { if (Directory.Exists(HotSwapTargetDir)) { Debug.WriteLine($"Hot swap active, redirecting {path}"); return Path.Combine(HotSwapTargetDir, "resources", path); } return base.LocateFile(path); } private void HotSwap() { if (!File.Exists(HotSwapRebuildScript)) { Debug.WriteLine($"Failed resource hot swap, missing rebuild script: {HotSwapRebuildScript}"); return; } ResetHotSwap(); Directory.CreateDirectory(HotSwapTargetDir); Stopwatch sw = Stopwatch.StartNew(); using (Process process = Process.Start(new ProcessStartInfo { FileName = HotSwapRebuildScript, Arguments = $"\"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"Debug\" \"{Program.VersionTag}\"", WindowStyle = ProcessWindowStyle.Hidden })) { // ReSharper disable once PossibleNullReferenceException if (!process.WaitForExit(8000)) { Debug.WriteLine("Failed resource hot swap, script did not finish in time"); return; } else if (process.ExitCode != 0) { Debug.WriteLine($"Failed resource hot swap, script exited with code {process.ExitCode}"); return; } } sw.Stop(); Debug.WriteLine($"Finished rebuild script in {sw.ElapsedMilliseconds} ms"); ClearCache(); // Force update plugin manager setup scripts string newPluginRoot = Path.Combine(HotSwapTargetDir, "plugins"); const BindingFlags flagsInstance = BindingFlags.Instance | BindingFlags.NonPublic; Type typePluginManager = typeof(PluginManager); Type typeFormBrowser = typeof(FormBrowser); // ReSharper disable PossibleNullReferenceException object instPluginManager = typeFormBrowser.GetField("plugins", flagsInstance).GetValue(FormManager.TryFind<FormBrowser>()); typePluginManager.GetField("pluginFolder", flagsInstance).SetValue(instPluginManager, newPluginRoot); Debug.WriteLine("Reloading hot swapped plugins..."); ((PluginManager) instPluginManager).Reload(); // ReSharper restore PossibleNullReferenceException } private void ResetHotSwap() { try { Directory.Delete(HotSwapTargetDir, true); } catch (DirectoryNotFoundException) {} } } } #endif