99 lines
3.6 KiB
C#
99 lines
3.6 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.Build.Framework;
|
|
using Microsoft.Build.Utilities;
|
|
|
|
namespace ShrinkSDK.CodeGen;
|
|
|
|
public sealed class ShrinkWeaveTask : Task
|
|
{
|
|
[Required]
|
|
public string AssemblyPath { get; set; } = string.Empty;
|
|
|
|
public string? PdbPath { get; set; }
|
|
public ITaskItem[] ReferencePaths { get; set; } = Array.Empty<ITaskItem>();
|
|
public string? StrongNameKeyFile { get; set; }
|
|
|
|
[Output] public bool Changed { get; private set; }
|
|
[Output] public int InstanceSubscriberCount { get; private set; }
|
|
[Output] public int StaticSubscriberCount { get; private set; }
|
|
[Output] public int RegistryEntryCount { get; private set; }
|
|
|
|
public override bool Execute()
|
|
{
|
|
if (!File.Exists(AssemblyPath))
|
|
{
|
|
Log.LogError($"[ShrinkSDK.CodeGen] Intermediate assembly does not exist: {AssemblyPath}");
|
|
return false;
|
|
}
|
|
|
|
var assemblyDirectory = Path.GetDirectoryName(Path.GetFullPath(AssemblyPath))!;
|
|
var temporaryAssembly = Path.Combine(assemblyDirectory, $".{Path.GetFileName(AssemblyPath)}.{Guid.NewGuid():N}.tmp");
|
|
var hasPdb = !string.IsNullOrWhiteSpace(PdbPath) && File.Exists(PdbPath);
|
|
var temporaryPdb = hasPdb
|
|
? Path.Combine(assemblyDirectory, $".{Path.GetFileName(PdbPath)}.{Guid.NewGuid():N}.tmp")
|
|
: null;
|
|
try
|
|
{
|
|
var result = ShrinkAssemblyWeaver.Weave(
|
|
AssemblyPath,
|
|
hasPdb ? PdbPath : null,
|
|
ReferencePaths.Select(item => item.ItemSpec),
|
|
temporaryAssembly,
|
|
temporaryPdb,
|
|
ShrinkCodeGenPlatform.EngineNeutral,
|
|
StrongNameKeyFile);
|
|
foreach (var diagnostic in result.Diagnostics)
|
|
{
|
|
switch (diagnostic.Severity)
|
|
{
|
|
case ShrinkCodeGenDiagnosticSeverity.Warning:
|
|
Log.LogWarning($"[ShrinkSDK.CodeGen] {diagnostic.Message}");
|
|
break;
|
|
case ShrinkCodeGenDiagnosticSeverity.Error:
|
|
Log.LogError($"[ShrinkSDK.CodeGen] {diagnostic.Message}");
|
|
break;
|
|
default:
|
|
Log.LogMessage(MessageImportance.Low, $"[ShrinkSDK.CodeGen] {diagnostic.Message}");
|
|
break;
|
|
}
|
|
}
|
|
if (!result.Succeeded)
|
|
return false;
|
|
|
|
Changed = result.Changed;
|
|
InstanceSubscriberCount = result.InstanceSubscribers;
|
|
StaticSubscriberCount = result.StaticSubscribers;
|
|
RegistryEntryCount = result.RegistryEntries;
|
|
if (Changed)
|
|
{
|
|
File.Move(temporaryAssembly, AssemblyPath, true);
|
|
if (hasPdb && temporaryPdb != null)
|
|
File.Move(temporaryPdb, PdbPath!, true);
|
|
}
|
|
Log.LogMessage(MessageImportance.High,
|
|
$"[ShrinkSDK.CodeGen] {Path.GetFileName(AssemblyPath)} woven: instance={InstanceSubscriberCount}, static={StaticSubscriberCount}, registry={RegistryEntryCount}.");
|
|
return true;
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Log.LogErrorFromException(exception, true);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
TryDelete(temporaryAssembly);
|
|
if (temporaryPdb != null) TryDelete(temporaryPdb);
|
|
}
|
|
}
|
|
|
|
private static void TryDelete(string path)
|
|
{
|
|
try { if (File.Exists(path)) File.Delete(path); }
|
|
catch { }
|
|
}
|
|
}
|