From ccbf4e70611352524235b1c9efd4262c35814a53 Mon Sep 17 00:00:00 2001 From: Michael Butvinnik Date: Fri, 12 Sep 2025 19:27:23 +0300 Subject: [PATCH 1/3] Fix DllImport attribute for OutputDebugString function --- src/log4net/Util/NativeMethods.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/log4net/Util/NativeMethods.cs b/src/log4net/Util/NativeMethods.cs index 339a5427..88e43c4c 100644 --- a/src/log4net/Util/NativeMethods.cs +++ b/src/log4net/Util/NativeMethods.cs @@ -139,11 +139,7 @@ internal static extern int FormatMessage( /// Stub for OutputDebugString native method /// /// the string to output -#if NETSTANDARD2_0_OR_GREATER - [DllImport("CoreDll.dll")] -#else [DllImport("Kernel32.dll")] -#endif [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] internal static extern void OutputDebugString(string message); From 8034b0ce3b4487119c9ae606bf516f679e656209 Mon Sep 17 00:00:00 2001 From: Michael Butvinnik Date: Fri, 12 Sep 2025 20:45:13 +0300 Subject: [PATCH 2/3] Fix encoding issue, add test --- .../Appender/OutputDebugAppenderTest.cs | 71 +++++++++++++++++++ src/log4net/Util/NativeMethods.cs | 2 +- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/log4net.Tests/Appender/OutputDebugAppenderTest.cs diff --git a/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs b/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs new file mode 100644 index 00000000..d34cb244 --- /dev/null +++ b/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs @@ -0,0 +1,71 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#endregion + + +using System; +using System.Diagnostics; + +using log4net.Appender; +using log4net.Config; +using log4net.Core; +using log4net.Layout; +using log4net.Repository; +using NUnit.Framework; + +namespace log4net.Tests.Appender; + +/// +/// Used for internal unit testing the class. +/// +/// +/// Used for internal unit testing the class. +/// +[TestFixture] +public sealed class OutputDebugStringAppenderTest +{ + /// + /// Verifies that the OutputDebugString api is called by the appender without issues + /// + [Test] + public void AppendShouldNotCauseAnyErrors() + { + ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString()); + + OutputDebugStringAppender outputDebugStringAppender = new() + { + Layout = new SimpleLayout(), + ErrorHandler = new FailOnError() + }; + outputDebugStringAppender.ActivateOptions(); + + BasicConfigurator.Configure(rep, outputDebugStringAppender); + + ILog log = LogManager.GetLogger(rep.Name, GetType()); + log.Debug("Message - Сообщение - הודעה"); + + // need a way to check that the api is actually called and the string is properly marshalled. + } +} + +class FailOnError : IErrorHandler +{ + public void Error(string message, Exception? e, ErrorCode errorCode) => Assert.Fail($"Unexpected error: {message} exception: {e}, errorCode: {errorCode}"); + public void Error(string message, Exception e) => Assert.Fail($"Unexpected error: {message} exception: {e}"); + public void Error(string message) => Assert.Fail($"Unexpected error: {message}"); +} diff --git a/src/log4net/Util/NativeMethods.cs b/src/log4net/Util/NativeMethods.cs index 88e43c4c..96ca8918 100644 --- a/src/log4net/Util/NativeMethods.cs +++ b/src/log4net/Util/NativeMethods.cs @@ -139,7 +139,7 @@ internal static extern int FormatMessage( /// Stub for OutputDebugString native method /// /// the string to output - [DllImport("Kernel32.dll")] + [DllImport("Kernel32.dll", CharSet = CharSet.Unicode)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] internal static extern void OutputDebugString(string message); From 1b24ea6a8aed265030af3d6bd1d577df7235a805 Mon Sep 17 00:00:00 2001 From: Michael Butvinnik Date: Fri, 12 Sep 2025 23:36:51 +0300 Subject: [PATCH 3/3] Run OutputDebugStringAppenderTest on Windows only --- src/log4net.Tests/Appender/OutputDebugAppenderTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs b/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs index d34cb244..9659244c 100644 --- a/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs +++ b/src/log4net.Tests/Appender/OutputDebugAppenderTest.cs @@ -37,6 +37,7 @@ namespace log4net.Tests.Appender; /// Used for internal unit testing the class. /// [TestFixture] +[Platform(Include = "Win")] public sealed class OutputDebugStringAppenderTest { ///