Skip to content

Commit db23a67

Browse files
mcpolo99RandomCrocodile
andauthored
refactor: replace custom ILogger with Serilog + Microsoft.Extensions.Logging (#85)
* refactor: extract IProgressReporter from ILogger (#64) Separate progress reporting (Progress, EndProgress, Finish) from logging into a new IProgressReporter interface. This is the first step toward replacing the custom ILogger with Microsoft.Extensions.Logging + Serilog. - Add IProgressReporter interface and NullProgressReporter - Remove Progress, EndProgress, Finish from ILogger and all implementations - Remove dead BeginModule/EndModule from NullLogger - Add ProgressReporter property to ConfuserParameters and ConfuserContext - Replace PackerLogger (full ILogger decorator) with PackerProgressReporter - Update all WithProgress call sites to use context.ProgressReporter - Fix MSBuildLogger.Finish bug (was setting HasError=false on failure) - Seal NullLogger class * feature: add M.E.L abstraction and MelLoggerAdapter (#64) Add Microsoft.Extensions.Logging.Abstractions to Confuser.Core (netstandard2.0 compatible) and a MelLoggerAdapter that bridges M.E.L ILogger to the internal Confuser.Core.ILogger interface. This allows callers to pass a standard M.E.L logger (backed by Serilog or any other provider) into ConfuserEngine without changing any internal code yet. * feature: replace CLI ConsoleLogger with Serilog (#64) Wire up Serilog as the logging provider in the CLI via Microsoft.Extensions.Logging and MelLoggerAdapter. - Add Serilog, Serilog.Extensions.Logging, Serilog.Sinks.Console - Delete custom ConsoleLogger — Serilog handles all console output - Add --verbose (-v, -vv, -vvv) and --quiet (-q) CLI flags - Default: Information level; -q: Warning; -v: Debug; -vv+: Verbose * feature: replace GUI logger with Serilog FlowDocument sink (#64) Wire up Serilog in the WPF GUI via a custom FlowDocumentSink that renders color-coded log output to the protection log panel. - Add Serilog and Serilog.Extensions.Logging to ConfuserEx - Create FlowDocumentSink — custom Serilog sink for WPF Paragraph - Remove ILogger from ProtectTabVM — now uses MelLoggerAdapter - ProtectTabVM keeps only IProgressReporter (progress bar + finish) - Delete ~40 lines of manual ILogger boilerplate * chore: add local-ci.sh script mirroring GitHub Actions pipeline Full local CI script that replicates lint.yml, ci.yml, and test.yml: - lint: whitespace, style, and analyzer checks via dotnet format - build: dotnet build for SDK projects + MSBuild.exe for C++/CLI - test: discovers all *.Test.csproj, runs with coverage, summary - package: creates CLI, GUI, and combined zip archives Usage: ./scripts/local-ci.sh [lint|build|test|package|all] * refactor: replace Confuser.Core.ILogger with Microsoft.Extensions.Logging.ILogger (#64) Complete migration from the custom 13-method ILogger interface to the standard M.E.L ILogger abstraction across all projects. - Change ConfuserContext.Logger and ConfuserParameters.Logger to M.E.L ILogger - Convert all ~80 call sites: Debug→LogDebug, Info→LogInformation, Warn→LogWarning, Error→LogError, *Exception→swap parameter order - Rewrite MSBuildLogger as MSBuildMelLogger implementing M.E.L ILogger - Rewrite XUnitLogger implementing M.E.L ILogger + IProgressReporter - Remove MelLoggerAdapter (no longer needed — M.E.L is the native type) - Delete Confuser.Core.ILogger, NullLogger (replaced by M.E.L NullLogger) - Add test-results/ and coverage/ to .gitignore * chore: fix import ordering to pass CI lint (#64) * fix: dispose GUI logger factory after async protection completes (#64) DoProtect used 'using var loggerFactory' which disposed the factory (and the Serilog logger via dispose:true) as soon as DoProtect returned. Since ConfuserEngine.Run executes asynchronously on a background thread, this disposed the logger before the protection actually used it, silently dropping log output mid-run. Move disposal into the ContinueWith continuation so the factory lives for the full protection lifetime. * test: fix flaky GUI protect test — deterministic tab navigation (#64) Gui_ProtectSampleApp_ShowsSuccess intermittently failed at the Protect! button lookup (~1 in 3 runs). Two root causes: 1. ByText("Protect!") ambiguously matched both the tab header and the Protect! button (they share the caption), so the wrong element could be clicked and the tab never actually got selected. 2. WPF virtualizes inactive tab content — the Protect! button does not enter the UIA tree until the tab is selected AND rendered. The 5s button-find timeout was too short under load. Fix: match the tab by TabItem control type + name, Select() it and wait for IsSelected, then find the button with a 15s timeout. 5/5 consecutive full-suite runs now pass 3/3 (previously ~1/3 failed). --------- Co-authored-by: RandomCrocodile <mawi@polosab.com>
1 parent 922e1a7 commit db23a67

50 files changed

Lines changed: 871 additions & 593 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,8 @@ packages/
3939
gh-pages/
4040

4141
.idea/
42-
**/*out*
42+
**/*out*
43+
44+
# Local CI artifacts
45+
test-results/
46+
coverage/

Confuser.CLI/Confuser.CLI.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
<ItemGroup Label="Nuget Dependencies">
1818
<PackageReference Include="NDesk.Options.Core" Version="1.2.5" />
19+
<PackageReference Include="Serilog" Version="4.*" />
20+
<PackageReference Include="Serilog.Extensions.Logging" Version="9.*" />
21+
<PackageReference Include="Serilog.Sinks.Console" Version="6.*" />
1922
</ItemGroup>
2023

2124
<ItemGroup Label="Project Dependencies">

Confuser.CLI/Program.cs

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
using System.Xml;
77
using Confuser.Core;
88
using Confuser.Core.Project;
9+
using Microsoft.Extensions.Logging;
910
using NDesk.Options;
11+
using Serilog;
12+
using Serilog.Events;
1013

1114
namespace Confuser.CLI {
1215
internal class Program {
@@ -21,6 +24,8 @@ static int Main(string[] args) {
2124
try {
2225
bool noPause = false;
2326
bool debug = false;
27+
bool quiet = false;
28+
int verbosity = 0;
2429
string outDir = null;
2530
string snKeyPath = null;
2631
string snKeyPass = null;
@@ -48,6 +53,12 @@ static int Main(string[] args) {
4853
}, {
4954
"snkeypass=", "specifies strong name key password.",
5055
value => { snKeyPass = value; }
56+
}, {
57+
"v|verbose", "increase verbosity (repeat for more: -v, -vv, -vvv).",
58+
value => { verbosity++; }
59+
}, {
60+
"q|quiet", "only show warnings and errors.",
61+
value => { quiet = (value != null); }
5162
}
5263
};
5364

@@ -130,7 +141,7 @@ static int Main(string[] args) {
130141
parameters.Project = proj;
131142
}
132143

133-
int retVal = RunProject(parameters);
144+
int retVal = RunProject(parameters, quiet, verbosity);
134145

135146
if (NeedPause() && !noPause) {
136147
Console.WriteLine("Press any key to continue...");
@@ -192,14 +203,34 @@ static void LoadTemplateProject(string templatePath, ConfuserProject proj, List<
192203
templateModules.Add(templateModule);
193204
}
194205

195-
static int RunProject(ConfuserParameters parameters) {
196-
var logger = new ConsoleLogger();
197-
parameters.Logger = logger;
198-
199-
Console.Title = "ConfuserEx - Running...";
206+
static int RunProject(ConfuserParameters parameters, bool quiet, int verbosity) {
207+
var levelSwitch = quiet
208+
? LogEventLevel.Warning
209+
: verbosity >= 3 ? LogEventLevel.Verbose
210+
: verbosity >= 2 ? LogEventLevel.Verbose
211+
: verbosity >= 1 ? LogEventLevel.Debug
212+
: LogEventLevel.Information;
213+
214+
Log.Logger = new LoggerConfiguration()
215+
.MinimumLevel.Is(levelSwitch)
216+
.WriteTo.Console(
217+
outputTemplate: "[{Level:u4}] {Message:lj}{NewLine}{Exception}")
218+
.CreateLogger();
219+
220+
using var loggerFactory = LoggerFactory.Create(builder =>
221+
builder.AddSerilog(dispose: false));
222+
var melLogger = loggerFactory.CreateLogger("ConfuserEx");
223+
224+
var progressReporter = new ConsoleProgressReporter();
225+
parameters.Logger = melLogger;
226+
parameters.ProgressReporter = progressReporter;
227+
228+
if (OperatingSystem.IsWindows())
229+
Console.Title = "ConfuserEx - Running...";
200230
ConfuserEngine.Run(parameters).GetAwaiter().GetResult();
201231

202-
return logger.ReturnValue;
232+
Log.CloseAndFlush();
233+
return progressReporter.ReturnValue;
203234
}
204235

205236
static bool NeedPause() {
@@ -217,6 +248,8 @@ static void PrintUsage() {
217248
WriteLine(" -debug : specifies debug symbol generation.");
218249
WriteLine(" -snkey : specifies strong name key file path.");
219250
WriteLine(" -snkeypass : specifies strong name key password.");
251+
WriteLine(" -v|verbose : increase verbosity (-v debug, -vv trace).");
252+
WriteLine(" -q|quiet : only show warnings and errors.");
220253
}
221254

222255
static void WriteLineWithColor(ConsoleColor color, string txt) {
@@ -234,57 +267,15 @@ static void WriteLine() {
234267
Console.WriteLine();
235268
}
236269

237-
class ConsoleLogger : ILogger {
270+
class ConsoleProgressReporter : IProgressReporter {
238271
readonly DateTime begin;
239272

240-
public ConsoleLogger() {
273+
public ConsoleProgressReporter() {
241274
begin = DateTime.Now;
242275
}
243276

244277
public int ReturnValue { get; private set; }
245278

246-
public void Debug(string msg) {
247-
WriteLineWithColor(ConsoleColor.Gray, "[DEBUG] " + msg);
248-
}
249-
250-
public void DebugFormat(string format, params object[] args) {
251-
WriteLineWithColor(ConsoleColor.Gray, "[DEBUG] " + string.Format(format, args));
252-
}
253-
254-
public void Info(string msg) {
255-
WriteLineWithColor(ConsoleColor.White, " [INFO] " + msg);
256-
}
257-
258-
public void InfoFormat(string format, params object[] args) {
259-
WriteLineWithColor(ConsoleColor.White, " [INFO] " + string.Format(format, args));
260-
}
261-
262-
public void Warn(string msg) {
263-
WriteLineWithColor(ConsoleColor.Yellow, " [WARN] " + msg);
264-
}
265-
266-
public void WarnFormat(string format, params object[] args) {
267-
WriteLineWithColor(ConsoleColor.Yellow, " [WARN] " + string.Format(format, args));
268-
}
269-
270-
public void WarnException(string msg, Exception ex) {
271-
WriteLineWithColor(ConsoleColor.Yellow, " [WARN] " + msg);
272-
WriteLineWithColor(ConsoleColor.Yellow, "Exception: " + ex);
273-
}
274-
275-
public void Error(string msg) {
276-
WriteLineWithColor(ConsoleColor.Red, "[ERROR] " + msg);
277-
}
278-
279-
public void ErrorFormat(string format, params object[] args) {
280-
WriteLineWithColor(ConsoleColor.Red, "[ERROR] " + string.Format(format, args));
281-
}
282-
283-
public void ErrorException(string msg, Exception ex) {
284-
WriteLineWithColor(ConsoleColor.Red, "[ERROR] " + msg);
285-
WriteLineWithColor(ConsoleColor.Red, "Exception: " + ex);
286-
}
287-
288279
public void Progress(int progress, int overall) { }
289280

290281
public void EndProgress() { }

Confuser.Core/Confuser.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<ItemGroup Label="Nuget Dependencies">
1818
<PackageReference Include="dnlib" Version="3.6.0" />
1919
<PackageReference Include="Microsoft.DiaSymReader.Native" Version="1.7.0" />
20+
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.*" />
2021
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
2122
</ItemGroup>
2223

Confuser.Core/ConfuserContext.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using Confuser.Core.Project;
55
using dnlib.DotNet;
66
using dnlib.DotNet.Writer;
7+
using Microsoft.Extensions.Logging;
78

89
namespace Confuser.Core {
910
/// <summary>
@@ -18,7 +19,13 @@ public class ConfuserContext {
1819
/// Gets the logger used for logging events.
1920
/// </summary>
2021
/// <value>The logger.</value>
21-
public ILogger Logger { get; internal set; }
22+
public Microsoft.Extensions.Logging.ILogger Logger { get; internal set; }
23+
24+
/// <summary>
25+
/// Gets the progress reporter used for reporting protection progress.
26+
/// </summary>
27+
/// <value>The progress reporter.</value>
28+
public IProgressReporter ProgressReporter { get; internal set; }
2229

2330
/// <summary>
2431
/// Gets the project being processed.

0 commit comments

Comments
 (0)