CLI tool for running Playbooks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.6 KiB

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, "(?<!\\r)\\n", "\r\n");
_current.WriteLine(value);
if (!WinUtil.IsTrustedInstaller())
{
File.AppendAllText($"{logDir}\\AdminOutput.txt", value + Environment.NewLine);
}
else
{
// Small window size to enforce roll-over for testing.
var windowSize = 2000000;
value += Environment.NewLine;
var bytes = Encoding.UTF8.GetBytes(value);
try
{
accessor = mmf.CreateViewAccessor(absolutePosition, windowSize, MemoryMappedFileAccess.ReadWrite);
if (bytes.Length + relativePosition > 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());
}
}
}