mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-20 20:33:06 +12:00
Added logging infrastructure.
Switched to logging for most debug information output.
This commit is contained in:
parent
dc031dcdb1
commit
39a33a4a67
34
OnTopReplica/AppPaths.cs
Normal file
34
OnTopReplica/AppPaths.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
public static class AppPaths {
|
||||
|
||||
const string AppDataFolder = "OnTopReplica";
|
||||
|
||||
public static void SetupPaths() {
|
||||
var roamingAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
var roamingAppDataApplicationPath = Path.Combine(roamingAppData, AppDataFolder);
|
||||
|
||||
if (!Directory.Exists(roamingAppDataApplicationPath)) {
|
||||
Directory.CreateDirectory(roamingAppDataApplicationPath);
|
||||
}
|
||||
PrivateRoamingFolderPath = roamingAppDataApplicationPath;
|
||||
}
|
||||
|
||||
public static string PrivateRoamingFolderPath { get; private set; }
|
||||
|
||||
public static string GenerateCrashDumpPath() {
|
||||
var now = DateTime.Now;
|
||||
|
||||
string dump = string.Format("OnTopReplica-dump-{0}{1}{2}-{3}{4}.txt",
|
||||
now.Year, now.Month, now.Day,
|
||||
now.Hour, now.Minute);
|
||||
|
||||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), dump);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,9 +134,7 @@ namespace OnTopReplica {
|
|||
AspectRatio = ((double)aspectRatioSource.Width / (double)aspectRatioSource.Height);
|
||||
_keepAspectRatio = true;
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Setting aspect ratio of {0} (for {1}).", AspectRatio, aspectRatioSource));
|
||||
#endif
|
||||
Log.Write("Setting new aspect ratio {0} (for {1})", AspectRatio, aspectRatioSource);
|
||||
|
||||
if (forceRefresh) {
|
||||
RefreshAspectRatio();
|
||||
|
|
|
@ -31,8 +31,6 @@ namespace OnTopReplica {
|
|||
e.SuppressKeyPress = true;
|
||||
}
|
||||
|
||||
//Console.WriteLine("{0} ({1})", e.KeyCode, e.KeyValue);
|
||||
|
||||
base.OnKeyUp(e);
|
||||
}
|
||||
|
||||
|
|
74
OnTopReplica/Log.cs
Normal file
74
OnTopReplica/Log.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
static class Log {
|
||||
|
||||
const string LogFileName = "lastrun.log.txt";
|
||||
|
||||
private readonly static StreamWriter Writer;
|
||||
|
||||
static Log() {
|
||||
try {
|
||||
var filepath = Path.Combine(AppPaths.PrivateRoamingFolderPath, LogFileName);
|
||||
Writer = new StreamWriter(new FileStream(filepath, FileMode.Create));
|
||||
Writer.AutoFlush = true;
|
||||
}
|
||||
catch (Exception) {
|
||||
Writer = null;
|
||||
|
||||
#if DEBUG
|
||||
throw;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
public static void Write(string message) {
|
||||
WriteLine(message);
|
||||
}
|
||||
|
||||
public static void Write(string format, object arg0) {
|
||||
WriteLine(string.Format(format, arg0));
|
||||
}
|
||||
|
||||
public static void Write(string format, object arg0, object arg1) {
|
||||
WriteLine(string.Format(format, arg0, arg1));
|
||||
}
|
||||
|
||||
public static void Write(string format, params object[] args) {
|
||||
WriteLine(string.Format(format, args));
|
||||
}
|
||||
|
||||
public static void WriteDetails(string caption, string format, params object[] args) {
|
||||
WriteLines(caption, string.Format(format, args));
|
||||
}
|
||||
|
||||
public static void WriteException(string message, Exception exception) {
|
||||
if (exception != null) {
|
||||
WriteLines(message, exception.ToString());
|
||||
}
|
||||
else {
|
||||
WriteLines(message, "(no last exception)");
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteLine(string message) {
|
||||
var s = string.Format("{0,-8:HH:mm:ss} {1}", DateTime.Now, message);
|
||||
Writer.WriteLine(s);
|
||||
}
|
||||
|
||||
private static void WriteLines(params string[] messages) {
|
||||
if (messages.Length > 0)
|
||||
WriteLine(messages[0]);
|
||||
if (messages.Length > 1) {
|
||||
for (int i = 1; i < messages.Length; ++i) {
|
||||
Writer.WriteLine(" {0}", messages[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -266,7 +266,7 @@ namespace OnTopReplica {
|
|||
/// <param name="region">Region of the window to clone or null.</param>
|
||||
public void SetThumbnail(WindowHandle handle, ThumbnailRegion region) {
|
||||
try {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Cloning window HWND {0} of class {1}.", handle.Handle, handle.Class));
|
||||
Log.Write("Cloning window HWND {0} of class {1}", handle.Handle, handle.Class);
|
||||
|
||||
CurrentThumbnailWindowHandle = handle;
|
||||
_thumbnailPanel.SetThumbnailHandle(handle, region);
|
||||
|
@ -275,7 +275,7 @@ namespace OnTopReplica {
|
|||
SetAspectRatio(_thumbnailPanel.ThumbnailPixelSize, !FullscreenManager.IsFullscreen);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.Diagnostics.Trace.Fail("Unable to set thumbnail.", ex.ToString());
|
||||
Log.WriteException("Unable to set new thumbnail", ex);
|
||||
|
||||
ThumbnailError(ex, false, Strings.ErrorUnableToCreateThumbnail);
|
||||
_thumbnailPanel.UnsetThumbnail();
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace OnTopReplica {
|
|||
_processors[processor.GetType()] = processor;
|
||||
processor.Initialize(form);
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Registered message pump processor: {0}", processor.GetType()));
|
||||
Log.Write("Registered message pump processor: {0}", processor.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -27,10 +27,10 @@ namespace OnTopReplica {
|
|||
|
||||
//Register window shell hook
|
||||
if (!HookMethods.RegisterShellHookWindow(form.Handle)) {
|
||||
Console.Error.WriteLine("Failed to register shell hook window.");
|
||||
Log.Write("Failed to register shell hook window");
|
||||
}
|
||||
else {
|
||||
System.Diagnostics.Trace.WriteLine("Shell hook window registered successfully.");
|
||||
Log.Write("Shell hook window registered successfully");
|
||||
}
|
||||
|
||||
//Register message pump processors
|
||||
|
@ -65,10 +65,10 @@ namespace OnTopReplica {
|
|||
|
||||
public void Dispose() {
|
||||
if (!HookMethods.DeregisterShellHookWindow(Form.Handle)) {
|
||||
Console.Error.WriteLine("Failed to deregister shell hook window.");
|
||||
Log.Write("Failed to deregister shell hook window");
|
||||
}
|
||||
else {
|
||||
System.Diagnostics.Trace.WriteLine("Deregistered shell hook window successfully.");
|
||||
Log.Write("Deregistered shell hook window successfully");
|
||||
}
|
||||
|
||||
foreach (var processor in _processors.Values) {
|
||||
|
|
|
@ -71,8 +71,6 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
}
|
||||
|
||||
private void HandleForegroundWindowChange(IntPtr activeWindow) {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("New active window (h {0}). ", activeWindow));
|
||||
|
||||
//Seek window in tracked handles
|
||||
WindowHandleWrapper activated = null;
|
||||
foreach (var i in _lruHandles) {
|
||||
|
@ -82,7 +80,6 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
|
||||
if (activated == null) {
|
||||
//New foreground window is not tracked
|
||||
System.Diagnostics.Trace.WriteLine("Active window is not tracked.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -93,7 +90,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
//Get least recently used
|
||||
var next = _lruHandles[0];
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Tracked. Switching to {0} (last use: {1}).", next.WindowHandle.Title, next.LastTimeUsed));
|
||||
Log.Write("Switched to tracked window: switching to {0} (last use: {1})", next.WindowHandle.Title, next.LastTimeUsed);
|
||||
|
||||
Form.SetThumbnail(next.WindowHandle, null);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
var key = ++_lastUsedKey;
|
||||
|
||||
if (!HotKeyMethods.RegisterHotKey(owner.Handle, key, modifiers, keyCode)) {
|
||||
Console.Error.WriteLine("Failed to create hotkey on keys {0}.", keyCode);
|
||||
Log.Write("Failed to create hotkey on key {0} with modifiers {1}", keyCode, modifiers);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
|
||||
public void Dispose() {
|
||||
if (!HotKeyMethods.UnregisterHotKey(_hwnd, RegistrationKey)) {
|
||||
Console.Error.WriteLine("Failed to unregister hotkey #{0}.", RegistrationKey);
|
||||
Log.Write("Failed to unregister hotkey #{0}", RegistrationKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace OnTopReplica.MessagePumpProcessors {
|
|||
if (msg.Msg == HookMethods.WM_SHELLHOOKMESSAGE) {
|
||||
int hookCode = msg.WParam.ToInt32();
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Hook msg #{0}: {1}", hookCode, msg.LParam));
|
||||
Log.Write("Hook msg #{0}: {1}", hookCode, msg.LParam);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -12,8 +12,9 @@ namespace OnTopReplica.Native {
|
|||
|
||||
static HookMethods() {
|
||||
WM_SHELLHOOKMESSAGE = RegisterWindowMessage("SHELLHOOK");
|
||||
if (WM_SHELLHOOKMESSAGE == 0)
|
||||
Console.Error.WriteLine("Failed to register SHELLHOOK Windows message.");
|
||||
if (WM_SHELLHOOKMESSAGE == 0) {
|
||||
Log.Write("Failed to register SHELLHOOK window message");
|
||||
}
|
||||
}
|
||||
|
||||
public static int WM_SHELLHOOKMESSAGE {
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AppPaths.cs" />
|
||||
<Compile Include="AspectRatioForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -115,6 +116,7 @@
|
|||
<Compile Include="ImageComboBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="MainForm_Features.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -13,7 +13,15 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
public static PlatformSupport Create() {
|
||||
var os = Environment.OSVersion;
|
||||
var platform = CreateFromOperatingSystem(os);
|
||||
|
||||
Log.Write("{0} detected, using support class {1}",
|
||||
os.VersionString, platform.GetType().FullName);
|
||||
|
||||
return platform;
|
||||
}
|
||||
|
||||
private static PlatformSupport CreateFromOperatingSystem(OperatingSystem os) {
|
||||
if (os.Platform != PlatformID.Win32NT)
|
||||
return new Other();
|
||||
|
||||
|
|
|
@ -22,6 +22,15 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main(string[] args) {
|
||||
try {
|
||||
AppPaths.SetupPaths();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
MessageBox.Show(string.Format("Unable to setup application folders: {0}", ex), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
|
||||
Log.Write("Launching OnTopReplica v.{0}", Application.ProductVersion);
|
||||
|
||||
//Hook fatal abort handler
|
||||
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||||
|
||||
|
@ -31,6 +40,8 @@ namespace OnTopReplica {
|
|||
return;
|
||||
Platform.PreHandleFormInit();
|
||||
|
||||
Log.Write("Platform support initialized");
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
|
@ -65,7 +76,7 @@ namespace OnTopReplica {
|
|||
_mainForm.IsChromeVisible = true;
|
||||
|
||||
//Persist settings
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Persisting {0} size {1} to settings.", _mainForm.Location, _mainForm.ClientSize));
|
||||
Log.Write("Last position before shutdown: {0}, size: {1}", _mainForm.Location, _mainForm.Size);
|
||||
Settings.Default.RestoreLastPosition = _mainForm.Location;
|
||||
Settings.Default.RestoreLastSize = _mainForm.ClientSize;
|
||||
Settings.Default.Save();
|
||||
|
@ -90,20 +101,21 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
static void UpdateManager_CheckCompleted(object sender, UpdateCheckCompletedEventArgs e) {
|
||||
if (e.Success && e.Information != null) {
|
||||
Log.Write("Updated check successful (latest version is {0})", e.Information.LatestVersion);
|
||||
|
||||
if (e.Information.IsNewVersion) {
|
||||
Update.ConfirmAndInstall();
|
||||
}
|
||||
}
|
||||
else {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Failed to check updates. {0}", e.Error));
|
||||
Log.WriteException("Unable to check for updates", e.Error);
|
||||
}
|
||||
}
|
||||
|
||||
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
|
||||
string dump = string.Format("OnTopReplica-dump-{0}{1}{2}-{3}{4}.txt",
|
||||
DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
|
||||
DateTime.Now.Hour, DateTime.Now.Minute);
|
||||
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), dump);
|
||||
Log.WriteException("Unhandled exception", e.ExceptionObject as Exception);
|
||||
|
||||
string path = AppPaths.GenerateCrashDumpPath();
|
||||
|
||||
using (var s = new FileStream(path, FileMode.Create)) {
|
||||
using (var sw = new StreamWriter(s)) {
|
||||
|
@ -114,14 +126,16 @@ namespace OnTopReplica {
|
|||
sw.WriteLine("Last exception:");
|
||||
sw.WriteLine(e.ExceptionObject.ToString());
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("OnTopReplica v.{0}", Assembly.GetEntryAssembly().GetName().Version);
|
||||
sw.WriteLine("OnTopReplica v.{0}", Application.ProductVersion);
|
||||
sw.WriteLine("OS: {0}", Environment.OSVersion.ToString());
|
||||
sw.WriteLine(".NET: {0}", Environment.Version.ToString());
|
||||
sw.WriteLine("Aero DWM: {0}", WindowsFormsAero.OsSupport.IsCompositionEnabled);
|
||||
sw.WriteLine("DWM: {0}", WindowsFormsAero.OsSupport.IsCompositionEnabled);
|
||||
sw.WriteLine("Launch command: {0}", Environment.CommandLine);
|
||||
sw.WriteLine("UTC time: {0} {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString());
|
||||
}
|
||||
}
|
||||
|
||||
Log.Write("Crash dump written to {0}", path);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace OnTopReplica {
|
|||
|
||||
var move = end.Difference(start);
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("From {0} to {1} => {2}.", start, end, move));
|
||||
//System.Diagnostics.Trace.WriteLine(string.Format("From {0} to {1} => {2}.", start, end, move));
|
||||
|
||||
var original = form.Location;
|
||||
form.Location = new Point(original.X + move.X, original.Y + move.Y);
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace OnTopReplica.StartupOptions {
|
|||
options.StartLocation = Settings.Default.RestoreLastPosition;
|
||||
options.StartSize = Settings.Default.RestoreLastSize;
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Restoring window at {0} size {1}.", Settings.Default.RestoreLastPosition, Settings.Default.RestoreLastSize));
|
||||
Log.Write("Restoring window at {0} size {1}", Settings.Default.RestoreLastPosition, Settings.Default.RestoreLastSize);
|
||||
}
|
||||
|
||||
if (Settings.Default.RestoreLastWindow) {
|
||||
|
@ -45,14 +45,20 @@ namespace OnTopReplica.StartupOptions {
|
|||
var seeker = new RestoreWindowSeeker(new IntPtr(handle), title, className);
|
||||
seeker.SkipNotVisibleWindows = true;
|
||||
seeker.Refresh();
|
||||
|
||||
var resultHandle = seeker.Windows.FirstOrDefault();
|
||||
|
||||
if (resultHandle != null) {
|
||||
//Load window
|
||||
//Found a window: load it!
|
||||
options.WindowId = resultHandle.Handle;
|
||||
}
|
||||
else {
|
||||
System.Diagnostics.Trace.WriteLine("Couldn't find window to restore.");
|
||||
Log.WriteDetails("Failed to find window to restore from last use",
|
||||
"HWND {0}, Title '{1}', Class '{2}'",
|
||||
Settings.Default.RestoreLastWindowHwnd,
|
||||
Settings.Default.RestoreLastWindowTitle,
|
||||
Settings.Default.RestoreLastWindowClass
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,8 @@ namespace OnTopReplica.StartupOptions {
|
|||
#region Application
|
||||
|
||||
public void Apply(MainForm form) {
|
||||
Log.Write("Applying command line launch parameters");
|
||||
|
||||
form.Opacity = (double)Opacity / 255.0;
|
||||
|
||||
//Seek handle for thumbnail cloning
|
||||
|
|
|
@ -194,7 +194,9 @@ namespace OnTopReplica {
|
|||
/// <param name="handle">Handle of the window to clone.</param>
|
||||
/// <param name="region">Optional region.</param>
|
||||
public void SetThumbnailHandle(WindowHandle handle, ThumbnailRegion region) {
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Setting thumbnail to handle {0}, with region {1}.", handle, region), "ThumbnailPanel");
|
||||
Log.WriteDetails("Setting new thumbnail",
|
||||
"HWND {0}, region {1}", handle, region
|
||||
);
|
||||
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
_thumbnail.Close();
|
||||
|
@ -203,8 +205,8 @@ namespace OnTopReplica {
|
|||
|
||||
//Get form and register thumbnail on it
|
||||
Form owner = this.TopLevelControl as Form;
|
||||
if(owner == null)
|
||||
throw new Exception("Internal error: ThumbnailPanel.TopLevelControl is not a Form.");
|
||||
if (owner == null)
|
||||
throw new Exception("Internal error: ThumbnailPanel.TopLevelControl is not a Form.");
|
||||
|
||||
_labelGlass.Visible = false;
|
||||
|
||||
|
@ -219,7 +221,7 @@ namespace OnTopReplica {
|
|||
/// Disposes current thumbnail and enters stand-by mode.
|
||||
/// </summary>
|
||||
public void UnsetThumbnail() {
|
||||
System.Diagnostics.Trace.WriteLine("Unsetting thumbnail.");
|
||||
Log.Write("Unsetting thumbnail");
|
||||
|
||||
if (_thumbnail != null && !_thumbnail.IsInvalid) {
|
||||
_thumbnail.Close();
|
||||
|
@ -327,7 +329,7 @@ namespace OnTopReplica {
|
|||
endPoint.Y - startPoint.Y
|
||||
);
|
||||
|
||||
System.Diagnostics.Trace.WriteLine(string.Format("Drawn from {0} to {1}, as region {2}.", start, end, final));
|
||||
//System.Diagnostics.Trace.WriteLine(string.Format("Drawn from {0} to {1}, as region {2}.", start, end, final));
|
||||
|
||||
//Signal
|
||||
OnRegionDrawn(final);
|
||||
|
|
|
@ -53,8 +53,6 @@ namespace OnTopReplica {
|
|||
public static bool ContainsMousePointer(this Control ctrl, System.Drawing.Point screenCoordinates) {
|
||||
var bb = new System.Drawing.Rectangle(ctrl.Location, ctrl.Size);
|
||||
|
||||
//Console.Out.WriteLine("<{0},{1}> in {2}? {3}", screenCoordinates.X, screenCoordinates.Y, bb, bb.Contains(screenCoordinates));
|
||||
|
||||
return bb.Contains(screenCoordinates);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue