using System; using System.Diagnostics; using System.IO; using System.IO.MemoryMappedFiles; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Text.RegularExpressions; namespace TrustedUninstaller.Shared { public static class DualOut { private static TextWriter _current; static MemoryMappedFile mmf = null; static MemoryMappedViewAccessor accessor = null; static int absolutePosition = 0; static int relativePosition = 0; private static string logDir = Directory.GetCurrentDirectory() + "\\Logs"; private class OutputWriter : TextWriter { public override Encoding Encoding { get { return _current.Encoding; } } public override void WriteLine(string value) { value = Regex.Replace(value, "(? windowSize) { absolutePosition += relativePosition; relativePosition = 0; accessor.Dispose(); accessor = mmf.CreateViewAccessor(absolutePosition, windowSize, MemoryMappedFileAccess.ReadWrite); } accessor.WriteArray(relativePosition, bytes, 0, bytes.Length); relativePosition += bytes.Length; } finally { if (accessor != null) accessor.Dispose(); } File.AppendAllText($"{logDir}\\TIOutput.txt", value + Environment.NewLine); // Small delay, less far less than a millisecond on most processors Thread.SpinWait(40000); } } public override void WriteLine() { WriteLine(""); } } public static void Init() { if (!Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } if (WinUtil.IsTrustedInstaller()) { var i = 0; while (true) { try { mmf = MemoryMappedFile.OpenExisting("ImgA"); break; } catch (FileNotFoundException) { if (i > 300) throw new Exception("Memory file not found."); Task.Delay(200).Wait(); i++; } } } _current = Console.Out; Console.SetOut(new OutputWriter()); } } }