mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[AOT] Refactor Logger function to improve performance and mark managedCommon as AOT compatible (#36327)
* Use function to init static value * Replace GetFileName with GetFileNameWithoutExtension * Add exception catch for GetCallerInfo * Remove sourceLineNumber * Add kernal to allow list * Remove unused commit * Add new folder to place source generation context * update * fix build issue * Move line number back * Use fileName to replace full path --------- Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
This commit is contained in:
@@ -6,6 +6,7 @@ using System;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using ManagedCommon.Serialization;
|
||||||
|
|
||||||
namespace ManagedCommon
|
namespace ManagedCommon
|
||||||
{
|
{
|
||||||
@@ -35,7 +36,7 @@ namespace ManagedCommon
|
|||||||
inputStream.Close();
|
inputStream.Close();
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<OutGoingLanguageSettings>(data).LanguageTag;
|
return JsonSerializer.Deserialize<OutGoingLanguageSettings>(data, SourceGenerationContext.Default.OutGoingLanguageSettings).LanguageTag;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,15 +15,23 @@ namespace ManagedCommon
|
|||||||
{
|
{
|
||||||
public static class Logger
|
public static class Logger
|
||||||
{
|
{
|
||||||
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
|
||||||
private static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location).ProductVersion;
|
|
||||||
|
|
||||||
private static readonly string Error = "Error";
|
private static readonly string Error = "Error";
|
||||||
private static readonly string Warning = "Warning";
|
private static readonly string Warning = "Warning";
|
||||||
private static readonly string Info = "Info";
|
private static readonly string Info = "Info";
|
||||||
private static readonly string Debug = "Debug";
|
private static readonly string Debug = "Debug";
|
||||||
private static readonly string TraceFlag = "Trace";
|
private static readonly string TraceFlag = "Trace";
|
||||||
|
|
||||||
|
private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Please pay more attention!
|
||||||
|
* If you want to publish it with Native AOT enabled (or publish as a single file).
|
||||||
|
* You need to find another way to remove Assembly.Location usage.
|
||||||
|
*/
|
||||||
|
#pragma warning disable IL3000 // Avoid accessing Assembly file path when publishing as a single file
|
||||||
|
private static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location).ProductVersion;
|
||||||
|
#pragma warning restore IL3000 // Avoid accessing Assembly file path when publishing as a single file
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the logger and sets the path for logging.
|
/// Initializes the logger and sets the path for logging.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -53,18 +61,16 @@ namespace ManagedCommon
|
|||||||
Trace.AutoFlush = true;
|
Trace.AutoFlush = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogError(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogError(string message)
|
|
||||||
{
|
{
|
||||||
Log(message, Error);
|
Log(message, Error, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogError(string message, Exception ex, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogError(string message, Exception ex)
|
|
||||||
{
|
{
|
||||||
if (ex == null)
|
if (ex == null)
|
||||||
{
|
{
|
||||||
Log(message, Error);
|
Log(message, Error, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -83,38 +89,33 @@ namespace ManagedCommon
|
|||||||
"Stack trace: " + Environment.NewLine +
|
"Stack trace: " + Environment.NewLine +
|
||||||
ex.StackTrace;
|
ex.StackTrace;
|
||||||
|
|
||||||
Log(exMessage, Error);
|
Log(exMessage, Error, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogWarning(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogWarning(string message)
|
|
||||||
{
|
{
|
||||||
Log(message, Warning);
|
Log(message, Warning, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogInfo(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogInfo(string message)
|
|
||||||
{
|
{
|
||||||
Log(message, Info);
|
Log(message, Info, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogDebug(string message, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogDebug(string message)
|
|
||||||
{
|
{
|
||||||
Log(message, Debug);
|
Log(message, Debug, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
public static void LogTrace([System.Runtime.CompilerServices.CallerMemberName] string memberName = "", [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "", [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
|
||||||
public static void LogTrace()
|
|
||||||
{
|
{
|
||||||
Log(string.Empty, TraceFlag);
|
Log(string.Empty, TraceFlag, memberName, sourceFilePath, sourceLineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
private static void Log(string message, string type, string memberName, string sourceFilePath, int sourceLineNumber)
|
||||||
private static void Log(string message, string type)
|
|
||||||
{
|
{
|
||||||
Trace.WriteLine("[" + DateTime.Now.TimeOfDay + "] [" + type + "] " + GetCallerInfo());
|
Trace.WriteLine("[" + DateTime.Now.TimeOfDay + "] [" + type + "] " + GetCallerInfo(memberName, sourceFilePath, sourceLineNumber));
|
||||||
Trace.Indent();
|
Trace.Indent();
|
||||||
if (message != string.Empty)
|
if (message != string.Empty)
|
||||||
{
|
{
|
||||||
@@ -124,49 +125,27 @@ namespace ManagedCommon
|
|||||||
Trace.Unindent();
|
Trace.Unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
private static string GetCallerInfo(string memberName, string sourceFilePath, int sourceLineNumber)
|
||||||
private static string GetCallerInfo()
|
|
||||||
{
|
{
|
||||||
StackTrace stackTrace = new();
|
string callerFileName = "Unknown";
|
||||||
|
|
||||||
var callerMethod = GetCallerMethod(stackTrace);
|
|
||||||
|
|
||||||
return $"{callerMethod?.DeclaringType?.Name}::{callerMethod.Name}";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MethodBase GetCallerMethod(StackTrace stackTrace)
|
|
||||||
{
|
|
||||||
const int topFrame = 3;
|
|
||||||
|
|
||||||
var topMethod = stackTrace.GetFrame(topFrame)?.GetMethod();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (topMethod?.Name == nameof(IAsyncStateMachine.MoveNext) && typeof(IAsyncStateMachine).IsAssignableFrom(topMethod?.DeclaringType))
|
string fileName = Path.GetFileName(sourceFilePath);
|
||||||
|
if (!string.IsNullOrEmpty(fileName))
|
||||||
{
|
{
|
||||||
// Async method; return actual method as determined by heuristic:
|
callerFileName = fileName;
|
||||||
// "Nearest method on stack to async state-machine's MoveNext() in same namespace but in a different type".
|
|
||||||
// There are tighter ways of determining the actual method, but this is good enough and probably faster.
|
|
||||||
for (int deepFrame = topFrame + 1; deepFrame < stackTrace.FrameCount; deepFrame++)
|
|
||||||
{
|
|
||||||
var deepMethod = stackTrace.GetFrame(deepFrame)?.GetMethod();
|
|
||||||
|
|
||||||
if (deepMethod?.DeclaringType != topMethod?.DeclaringType && deepMethod?.DeclaringType?.Namespace == topMethod?.DeclaringType?.Namespace)
|
|
||||||
{
|
|
||||||
return deepMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
// Ignore exceptions in Release. The code above won't throw, but if it does, we don't want to crash the app.
|
callerFileName = "Unknown";
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw;
|
throw;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return topMethod;
|
return $"{callerFileName}::{memberName}::{sourceLineNumber}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
<!-- Look at Directory.Build.props in root for common stuff as well -->
|
||||||
<Import Project="..\..\Common.Dotnet.CsWinRT.props" />
|
<Import Project="..\..\Common.Dotnet.CsWinRT.props" />
|
||||||
|
<Import Project="..\..\Common.Dotnet.AotCompatibility.props" />
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>PowerToys ManagedCommon</Description>
|
<Description>PowerToys ManagedCommon</Description>
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ namespace ManagedCommon
|
|||||||
|
|
||||||
internal static int Size
|
internal static int Size
|
||||||
{
|
{
|
||||||
get { return Marshal.SizeOf(typeof(INPUT)); }
|
get { return Marshal.SizeOf<INPUT>(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,11 @@ namespace ManagedCommon
|
|||||||
{
|
{
|
||||||
public static class RunnerHelper
|
public static class RunnerHelper
|
||||||
{
|
{
|
||||||
public static void WaitForPowerToysRunner(int powerToysPID, Action act)
|
public static void WaitForPowerToysRunner(int powerToysPID, Action act, [System.Runtime.CompilerServices.CallerMemberName] string memberName = "")
|
||||||
{
|
{
|
||||||
var stackTrace = new StackTrace();
|
var stackTrace = new StackTrace();
|
||||||
var assembly = Assembly.GetCallingAssembly().GetName();
|
var assembly = Assembly.GetCallingAssembly().GetName();
|
||||||
var callingMethod = stackTrace.GetFrame(1).GetMethod().Name;
|
PowerToysTelemetry.Log.WriteEvent(new DebugEvent() { Message = $"[{assembly}][{memberName}]WaitForPowerToysRunner waiting for Event powerToysPID={powerToysPID}" });
|
||||||
PowerToysTelemetry.Log.WriteEvent(new DebugEvent() { Message = $"[{assembly}][{callingMethod}]WaitForPowerToysRunner waiting for Event powerToysPID={powerToysPID}" });
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
const uint INFINITE = 0xFFFFFFFF;
|
const uint INFINITE = 0xFFFFFFFF;
|
||||||
@@ -29,7 +28,7 @@ namespace ManagedCommon
|
|||||||
IntPtr powerToysProcHandle = NativeMethods.OpenProcess(SYNCHRONIZE, false, powerToysPID);
|
IntPtr powerToysProcHandle = NativeMethods.OpenProcess(SYNCHRONIZE, false, powerToysPID);
|
||||||
if (NativeMethods.WaitForSingleObject(powerToysProcHandle, INFINITE) == WAIT_OBJECT_0)
|
if (NativeMethods.WaitForSingleObject(powerToysProcHandle, INFINITE) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
PowerToysTelemetry.Log.WriteEvent(new DebugEvent() { Message = $"[{assembly}][{callingMethod}]WaitForPowerToysRunner Event Notified powerToysPID={powerToysPID}" });
|
PowerToysTelemetry.Log.WriteEvent(new DebugEvent() { Message = $"[{assembly}][{memberName}]WaitForPowerToysRunner Event Notified powerToysPID={powerToysPID}" });
|
||||||
act.Invoke();
|
act.Invoke();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using static ManagedCommon.LanguageHelper;
|
||||||
|
|
||||||
|
namespace ManagedCommon.Serialization;
|
||||||
|
|
||||||
|
[JsonSerializable(typeof(OutGoingLanguageSettings))]
|
||||||
|
internal sealed partial class SourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace ManagedCommon
|
|||||||
/// <param name="sender">Sender ThemeListener</param>
|
/// <param name="sender">Sender ThemeListener</param>
|
||||||
public delegate void ThemeChangedEvent(ThemeListener sender);
|
public delegate void ThemeChangedEvent(ThemeListener sender);
|
||||||
|
|
||||||
public class ThemeListener : IDisposable
|
public partial class ThemeListener : IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the App Theme.
|
/// Gets the App Theme.
|
||||||
|
|||||||
Reference in New Issue
Block a user