Added pluggable log (#44)

This commit is contained in:
Eugene Wang
2015-07-04 11:18:03 -04:00
parent 4356ed0615
commit 69d76569ff
17 changed files with 253 additions and 56 deletions

View File

@@ -36,7 +36,7 @@ namespace NTwain
var rc = ReturnCode.Failure;
_session.MessageLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: OpenSource.", Thread.CurrentThread.ManagedThreadId);
rc = _session.DGControl.Identity.OpenDS(this);
_session.UpdateCallback();
@@ -53,7 +53,7 @@ namespace NTwain
var rc = ReturnCode.Failure;
_session.MessageLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: CloseSource.", Thread.CurrentThread.ManagedThreadId);
rc = _session.DGControl.Identity.CloseDS();
//if (rc == ReturnCode.Success)

83
src/NTwain/ILog.cs Normal file
View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NTwain
{
/// <summary>
/// Simple log interface used by NTwain.
/// </summary>
public interface ILog
{
/// <summary>
/// Gets or sets a value indicating whether info messages will be logged.
/// </summary>
/// <value>
/// <c>true</c> to enable info logging.
/// </value>
bool IsInfoEnabled { get; set; }
/// <summary>
/// Gets or sets a value indicating whether debug messages will be logged.
/// </summary>
/// <value>
/// <c>true</c> to enable debug logging.
/// </value>
bool IsDebugEnabled { get; set; }
/// <summary>
/// Gets or sets a value indicating whether error messages will be logged.
/// </summary>
/// <value>
/// <c>true</c> to enable error logging.
/// </value>
bool IsErrorEnabled { get; set; }
/// <summary>
/// Logs info type message.
/// </summary>
/// <param name="message">The message.</param>
void Info(string message);
/// <summary>
/// Logs info type message.
/// </summary>
/// <param name="messageFormat">The message format.</param>
/// <param name="args">The arguments.</param>
void Info(string messageFormat, params object[] args);
/// <summary>
/// Logs debug type message.
/// </summary>
/// <param name="message">The message.</param>
void Debug(string message);
/// <summary>
/// Logs debug type message.
/// </summary>
/// <param name="messageFormat">The message format.</param>
/// <param name="args">The arguments.</param>
void Debug(string messageFormat, params object[] args);
/// <summary>
/// Logs error type message.
/// </summary>
/// <param name="message">The message.</param>
void Error(string message);
/// <summary>
/// Logs error type message.
/// </summary>
/// <param name="message">The message.</param>
/// <param name="exception">The exception.</param>
void Error(string message, Exception exception);
/// <summary>
/// Logs error type message.
/// </summary>
/// <param name="messageFormat">The message format.</param>
/// <param name="exception">The exception.</param>
/// <param name="args">The arguments.</param>
void Error(string messageFormat, Exception exception, params object[] args);
}
}

View File

@@ -86,5 +86,13 @@ namespace NTwain
/// The memory manager.
/// </value>
IMemoryManager MemoryManager { get; }
/// <summary>
/// Gets or sets the log used by NTwain.
/// </summary>
/// <value>
/// The log.
/// </value>
ILog Log { get; set; }
}
}

View File

@@ -34,7 +34,7 @@ namespace NTwain.Internals
{
var loopThread = new Thread(new ThreadStart(() =>
{
Debug.WriteLine("NTwain message loop is starting.");
PlatformInfo.Current.Log.Debug("NTwain internal message loop is starting.");
_dispatcher = Dispatcher.CurrentDispatcher;
if (!PlatformInfo.Current.IsOnMono)
{

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
namespace NTwain.Internals
{
class TraceLog : ILog
{
public TraceLog()
{
IsInfoEnabled = true;
IsErrorEnabled = true;
}
public bool IsInfoEnabled { get; set; }
public bool IsDebugEnabled { get; set; }
public bool IsErrorEnabled { get; set; }
public void Info(string message)
{
if (IsInfoEnabled && message != null)
{
System.Diagnostics.Trace.WriteLine(message, "Info");
}
}
public void Info(string messageFormat, params object[] args)
{
Debug(string.Format(CultureInfo.CurrentCulture, messageFormat, args));
}
public void Debug(string message)
{
if (IsDebugEnabled && message != null)
{
System.Diagnostics.Trace.WriteLine(message, "Debug");
}
}
public void Debug(string messageFormat, params object[] args)
{
Debug(string.Format(CultureInfo.CurrentCulture, messageFormat, args));
}
public void Error(string message)
{
if (IsErrorEnabled && message != null)
{
System.Diagnostics.Trace.WriteLine(message, "Error");
}
}
public void Error(string message, Exception exception)
{
if (exception == null)
{
Error(message);
}
else
{
Error(message + Environment.NewLine + exception.ToString());
}
}
public void Error(string messageFormat, Exception exception, params object[] args)
{
if (exception == null)
{
Error(string.Format(CultureInfo.CurrentCulture, messageFormat, args));
}
else
{
Error(string.Format(CultureInfo.CurrentCulture, messageFormat, args) + Environment.NewLine + exception.ToString());
}
}
}
}

View File

@@ -47,7 +47,6 @@ namespace NTwain.Internals
}
if (!handled)
{
Debug.WriteLine("Hwnd=" + hwnd);
handled = true;
// unnecessary to do default wndproc?
return NativeMethods.DefWindowProc(hwnd, (uint)msg, wParam, lParam);

View File

@@ -63,6 +63,8 @@
<Compile Include="DeviceEventArgs.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="IDataSource.cs" />
<Compile Include="ILog.cs" />
<Compile Include="Internals\TraceLog.cs" />
<Compile Include="Internals\Extensions.cs" />
<Compile Include="DataTransferredEventArgs.cs" />
<Compile Include="IMemoryManager.cs" />

View File

@@ -32,7 +32,7 @@ namespace NTwain
IsOnMono = Type.GetType("Mono.Runtime") != null;
IsWindows = Environment.OSVersion.Platform == PlatformID.Win32NT;
IsLinux = Environment.OSVersion.Platform == PlatformID.Unix;
_defaultLog = new TraceLog();
if (IsWindows)
{
_defaultMemManager = new WinMemoryManager();
@@ -84,7 +84,7 @@ namespace NTwain
ExpectedDsmPath = newDsmPath;
IsSupported = DsmExists = File.Exists(ExpectedDsmPath);
UseNewWinDSM = true;
Debug.WriteLine("Using new dsm in windows.");
Log.Debug("Using new dsm in windows.");
}
else
{
@@ -92,14 +92,14 @@ namespace NTwain
{
ExpectedDsmPath = newDsmPath;
UseNewWinDSM = IsSupported = DsmExists = true;
Debug.WriteLine("Using new dsm in windows.");
Log.Debug("Using new dsm in windows.");
}
else
{
ExpectedDsmPath = oldDsmPath;
IsSupported = DsmExists = File.Exists(ExpectedDsmPath);
UseNewWinDSM = false;
Debug.WriteLine("Using old dsm in windows.");
Log.Debug("Using old dsm in windows.");
}
}
}
@@ -186,13 +186,29 @@ namespace NTwain
{
get
{
if (_specifiedMemManager == null) { return _defaultMemManager; }
return _specifiedMemManager;
return _specifiedMemManager ?? _defaultMemManager;
}
internal set
{
_specifiedMemManager = value;
}
}
readonly ILog _defaultLog;
private ILog _log;
/// <summary>
/// Gets or sets the log used by NTwain.
/// </summary>
/// <value>
/// The log.
/// </value>
public ILog Log
{
get { return _log ?? _defaultLog; }
set { _log = value; }
}
}
}

View File

@@ -23,7 +23,7 @@ namespace NTwain
/// <summary>
/// The build release version number.
/// </summary>
public const string Build = "3.3.4"; // change this for each nuget release
public const string Build = "3.3.5"; // change this for each nuget release
}

View File

@@ -62,7 +62,7 @@ namespace NTwain
DataSource GetSourceInstance(ITwainSessionInternal session, TWIdentity sourceId)
{
DataSource source = null;
Debug.WriteLine("Source id = " + sourceId.Id);
PlatformInfo.Current.Log.Debug("Source id = {0}", sourceId.Id);
var key = string.Format(CultureInfo.InvariantCulture, "{0}|{1}|{2}|{3}", sourceId.Id, sourceId.Manufacturer, sourceId.ProductFamily, sourceId.ProductName);
if (_ownedSources.ContainsKey(key))
{
@@ -230,7 +230,7 @@ namespace NTwain
var rc = ReturnCode.Failure;
_msgLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: OpenManager.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: OpenManager.", Thread.CurrentThread.ManagedThreadId);
rc = ((ITwainSessionInternal)this).DGControl.Parent.OpenDsm(_msgLoopHook.Handle);
if (rc == ReturnCode.Success)
@@ -243,7 +243,7 @@ namespace NTwain
if (rc == ReturnCode.Success)
{
PlatformInfo.InternalCurrent.MemoryManager = entry;
Debug.WriteLine("Using TWAIN2 memory functions.");
PlatformInfo.Current.Log.Debug("Using TWAIN2 memory functions.");
}
else
{
@@ -264,7 +264,7 @@ namespace NTwain
var rc = ReturnCode.Failure;
_msgLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: CloseManager.", Thread.CurrentThread.ManagedThreadId);
rc = ((ITwainSessionInternal)this).DGControl.Parent.CloseDsm(_msgLoopHook.Handle);
if (rc == ReturnCode.Success)
@@ -360,7 +360,7 @@ namespace NTwain
/// <param name="targetState">State of the target.</param>
public void ForceStepDown(int targetState)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: ForceStepDown.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: ForceStepDown.", Thread.CurrentThread.ManagedThreadId);
bool origFlag = EnforceState;
EnforceState = false;
@@ -462,7 +462,7 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine("PropertyChanged event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("PropertyChanged event error.", ex);
}
}
else
@@ -476,7 +476,7 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine("PropertyChanged event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("PropertyChanged event error.", ex);
}
}, null);
}
@@ -533,7 +533,7 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine(handler.Method.Name + " event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("{0} event error.", ex, handler.Method.Name);
}
}
else
@@ -547,7 +547,7 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine(handler.Method.Name + " event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("{0} event error.", ex, handler.Method.Name);
}
}, null);
}
@@ -566,7 +566,7 @@ namespace NTwain
var syncer = SynchronizationContext;
if (syncer == null)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Trying to raise event {0} on thread {1} without sync.", e.GetType().Name, Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Trying to raise event {0} on thread {1} without sync.", e.GetType().Name, Thread.CurrentThread.ManagedThreadId);
try
{
@@ -575,12 +575,12 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine(handler.Method.Name + " event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("{0} event error.", ex, handler.Method.Name);
}
}
else
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Trying to raise event {0} on thread {1} with sync.", e.GetType().Name, Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Trying to raise event {0} on thread {1} with sync.", e.GetType().Name, Thread.CurrentThread.ManagedThreadId);
// on some consumer desktop scanner with poor drivers this can frequently hang. there's nothing I can do here.
syncer.Send(o =>
{
@@ -591,7 +591,7 @@ namespace NTwain
}
catch (Exception ex)
{
Debug.WriteLine(handler.Method.Name + " event error: " + ex.ToString());
PlatformInfo.Current.Log.Error("{0} event error.", ex, handler.Method.Name);
}
}, null);
}

View File

@@ -45,7 +45,7 @@ namespace NTwain
if (rc == ReturnCode.Success)
{
Debug.WriteLine("Registered callback2 OK.");
PlatformInfo.Current.Log.Debug("Registered callback2 OK.");
_callbackObj = cb;
}
}
@@ -59,7 +59,7 @@ namespace NTwain
if (rc == ReturnCode.Success)
{
Debug.WriteLine("Registered callback OK.");
PlatformInfo.Current.Log.Debug("Registered callback OK.");
_callbackObj = cb;
}
}
@@ -159,7 +159,7 @@ namespace NTwain
_msgLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: EnableSource with {1}.", Thread.CurrentThread.ManagedThreadId, mode));
PlatformInfo.Current.Log.Debug("Thread {0}: EnableSource with {1}.", Thread.CurrentThread.ManagedThreadId, mode);
_twui = new TWUserInterface();
@@ -190,7 +190,7 @@ namespace NTwain
{
_msgLoopHook.Invoke(() =>
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId));
PlatformInfo.Current.Log.Debug("Thread {0}: DisableSource.", Thread.CurrentThread.ManagedThreadId);
rc = ((ITwainSessionInternal)this).DGControl.UserInterface.DisableDS(_twui);
if (rc == ReturnCode.Success)
@@ -242,7 +242,7 @@ namespace NTwain
evt.pEvent = msgPtr;
if (handled = (((ITwainSessionInternal)this).DGControl.Event.ProcessEvent(evt) == ReturnCode.DSEvent))
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: HandleWndProcMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, evt.TWMessage));
PlatformInfo.Current.Log.Debug("Thread {0}: HandleWndProcMessage at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, evt.TWMessage);
HandleSourceMsg(evt.TWMessage);
}
@@ -264,7 +264,7 @@ namespace NTwain
{
if (origin != null && CurrentSource != null && origin.Id == CurrentSource.Identity.Id && _state >= 5)
{
Debug.WriteLine(string.Format(CultureInfo.InvariantCulture, "Thread {0}: CallbackHandler at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, msg));
PlatformInfo.Current.Log.Debug("Thread {0}: CallbackHandler at state {1} with MSG={2}.", Thread.CurrentThread.ManagedThreadId, State, msg);
// spec says we must handle this on the thread that enabled the DS.
// by using the internal dispatcher this will be the case.
@@ -282,6 +282,7 @@ namespace NTwain
// final method that handles msg from the source, whether it's from wndproc or callbacks
void HandleSourceMsg(Message msg)
{
PlatformInfo.Current.Log.Debug("Got TWAIN msg " + msg);
switch (msg)
{
case Message.XferReady:
@@ -301,7 +302,6 @@ namespace NTwain
break;
case Message.CloseDSReq:
case Message.CloseDSOK:
Debug.WriteLine("Got msg " + msg);
// even though it says closeDS it's really disable.
// dsok is sent if source is enabled with uionly