Merge pull request #5 from 4lexKislitsyn/master

Added options to provider
This commit is contained in:
Yaakov 2020-05-23 23:45:56 +10:00 committed by GitHub
commit 895ef8c01e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 96 additions and 24 deletions

View file

@ -2,6 +2,6 @@
{ {
interface IWindowFinder interface IWindowFinder
{ {
WindowInfo FindNotepadWindow(); WindowInfo FindNotepadWindow(string windowName);
} }
} }

View file

@ -1,4 +1,9 @@
using Notepad.Extensions.Logging; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Options;
using Notepad.Extensions.Logging;
using System;
namespace Microsoft.Extensions.Logging namespace Microsoft.Extensions.Logging
{ {
@ -6,7 +11,21 @@ namespace Microsoft.Extensions.Logging
{ {
public static ILoggingBuilder AddNotepad(this ILoggingBuilder builder) public static ILoggingBuilder AddNotepad(this ILoggingBuilder builder)
{ {
builder.AddProvider(NotepadLoggerProvider.Instance); builder.AddConfiguration();
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, NotepadLoggerProvider>());
LoggerProviderOptions.RegisterProviderOptions<NotepadLoggerOptions, NotepadLoggerProvider>(builder.Services);
return builder;
}
public static ILoggingBuilder AddNotepad(this ILoggingBuilder builder, Action<NotepadLoggerOptions> configure)
{
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
AddNotepad(builder);
builder.Services.Configure(configure);
return builder; return builder;
} }
} }

View file

@ -16,6 +16,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Logging.Configuration" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.4" /> <PackageReference Include="Microsoft.Extensions.ObjectPool" Version="3.1.4" />
</ItemGroup> </ItemGroup>

View file

@ -11,16 +11,18 @@ namespace Notepad.Extensions.Logging
{ {
class NotepadLogger : ILogger class NotepadLogger : ILogger
{ {
public NotepadLogger(ObjectPool<StringBuilder> stringBuilderPool, IWindowFinder windowFinder, string categoryName) public NotepadLogger(ObjectPool<StringBuilder> stringBuilderPool, IWindowFinder windowFinder, string categoryName, string windowName)
{ {
this.stringBuilderPool = stringBuilderPool ?? throw new ArgumentNullException(nameof(stringBuilderPool)); this.stringBuilderPool = stringBuilderPool ?? throw new ArgumentNullException(nameof(stringBuilderPool));
this.windowFinder = windowFinder ?? throw new ArgumentNullException(nameof(windowFinder)); this.windowFinder = windowFinder ?? throw new ArgumentNullException(nameof(windowFinder));
this.categoryName = categoryName; this.categoryName = categoryName;
this.windowName = windowName;
} }
readonly ObjectPool<StringBuilder> stringBuilderPool; readonly ObjectPool<StringBuilder> stringBuilderPool;
readonly IWindowFinder windowFinder; readonly IWindowFinder windowFinder;
readonly string categoryName; readonly string categoryName;
readonly string windowName;
public IDisposable BeginScope<TState>(TState state) => NullDisposable.Instance; public IDisposable BeginScope<TState>(TState state) => NullDisposable.Instance;
@ -90,18 +92,15 @@ namespace Notepad.Extensions.Logging
void WriteToNotepad(string message) void WriteToNotepad(string message)
{ {
var info = windowFinder.FindNotepadWindow(); var info = windowFinder.FindNotepadWindow(windowName);
switch (info.Kind) switch (info.Kind)
{ {
case WindowKind.Notepad: case WindowKind.Notepad:
SendMessage(info.Handle, EM_REPLACESEL, (IntPtr)1, message); SendMessage(info.Handle, EM_REPLACESEL, (IntPtr)1, message);
break; break;
case WindowKind.NotepadPlusPlus: case WindowKind.NotepadPlusPlus:
{
WriteToNotepadPlusPlus(info.Handle, message); WriteToNotepadPlusPlus(info.Handle, message);
break; break;
}
} }
} }

View file

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.Extensions.Logging
{
public class NotepadLoggerOptions
{
/// <summary>
/// Name of window to search.
/// </summary>
public string WindowName { get; set; }
}
}

View file

@ -1,9 +1,12 @@
using System.Text; using System;
using System.Text;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Options;
namespace Notepad.Extensions.Logging namespace Notepad.Extensions.Logging
{ {
[ProviderAlias("Notepad")]
class NotepadLoggerProvider : ILoggerProvider class NotepadLoggerProvider : ILoggerProvider
{ {
NotepadLoggerProvider() NotepadLoggerProvider()
@ -13,15 +16,32 @@ namespace Notepad.Extensions.Logging
windowFinder = new WindowFinder(); windowFinder = new WindowFinder();
} }
public static ILoggerProvider Instance { get; } = new NotepadLoggerProvider(); public NotepadLoggerProvider(IOptionsMonitor<NotepadLoggerOptions> options) : this()
{
// Filter would be applied on LoggerFactory level
optionsReloadToken = options.OnChange(ReloadLoggerOptions);
ReloadLoggerOptions(options.CurrentValue);
}
public NotepadLoggerProvider(NotepadLoggerOptions options) : this()
{
this.options = options;
}
readonly ObjectPool<StringBuilder> stringBuilderPool; readonly ObjectPool<StringBuilder> stringBuilderPool;
readonly IWindowFinder windowFinder; readonly IWindowFinder windowFinder;
readonly IDisposable optionsReloadToken;
NotepadLoggerOptions options;
public ILogger CreateLogger(string categoryName) => new NotepadLogger(stringBuilderPool, windowFinder, categoryName); public ILogger CreateLogger(string categoryName) => new NotepadLogger(stringBuilderPool, windowFinder, categoryName, options.WindowName);
public void Dispose() public void Dispose()
{ {
optionsReloadToken?.Dispose();
}
void ReloadLoggerOptions(NotepadLoggerOptions options)
{
this.options = options;
} }
} }
} }

View file

@ -16,11 +16,13 @@ namespace Notepad.Extensions.Logging
public IntPtr Handle { get; private set; } public IntPtr Handle { get; private set; }
public WindowKind WindowKind { get; private set; } public WindowKind WindowKind { get; private set; }
public string WindowName { get; internal set; }
public void Reset() public void Reset()
{ {
Handle = default; Handle = default;
WindowKind = default; WindowKind = default;
WindowName = default;
sb.Clear(); sb.Clear();
} }
@ -51,22 +53,38 @@ namespace Notepad.Extensions.Logging
bool IsKnownNotepadWindow(string titleText) bool IsKnownNotepadWindow(string titleText)
{ {
switch (titleText) if (!string.IsNullOrWhiteSpace(WindowName))
{ {
case "Untitled - Notepad": if (WindowName.Equals(titleText, StringComparison.Ordinal))
WindowKind = WindowKind.Notepad; {
Handle = NativeMethods.FindWindowEx(Handle, IntPtr.Zero, "EDIT", null); WindowKind = titleText.EndsWith(" - Notepad++") ? WindowKind.NotepadPlusPlus : WindowKind.Notepad;
return true; }
} }
else if (titleText.Equals("Untitled - Notepad", StringComparison.Ordinal))
if (notepadPlusPlusRegex.IsMatch(titleText)) {
WindowKind = WindowKind.Notepad;
}
else if (notepadPlusPlusRegex.IsMatch(titleText))
{ {
WindowKind = WindowKind.NotepadPlusPlus; WindowKind = WindowKind.NotepadPlusPlus;
Handle = NativeMethods.FindWindowEx(Handle, IntPtr.Zero, "Scintilla", null);
return true;
} }
return false; Handle = FindInnerWindow(WindowKind);
return WindowKind != default;
}
IntPtr FindInnerWindow(WindowKind windowKind)
{
switch (windowKind)
{
case WindowKind.Notepad:
return NativeMethods.FindWindowEx(Handle, IntPtr.Zero, "EDIT", null);
case WindowKind.NotepadPlusPlus:
return NativeMethods.FindWindowEx(Handle, IntPtr.Zero, "Scintilla", null);
default:
return Handle;
}
} }
} }
} }

View file

@ -12,11 +12,12 @@ namespace Notepad.Extensions.Logging
readonly ObjectPool<WindowEnumerationState> statePool; readonly ObjectPool<WindowEnumerationState> statePool;
public WindowInfo FindNotepadWindow() public WindowInfo FindNotepadWindow(string windowName)
{ {
var stateObject = statePool.Get(); var stateObject = statePool.Get();
try try
{ {
stateObject.WindowName = windowName;
NativeMethods.EnumWindows(enumWindowsDelegate, stateObject); NativeMethods.EnumWindows(enumWindowsDelegate, stateObject);
return new WindowInfo(stateObject.WindowKind, stateObject.Handle); return new WindowInfo(stateObject.WindowKind, stateObject.Handle);
} }