From 91f2445d673db17c4fd5c4766c2bb41ba90c546c Mon Sep 17 00:00:00 2001 From: "Denis Kuzmin [ GitHub/3F ]" Date: Tue, 9 Jun 2020 20:17:31 +0300 Subject: [PATCH] re-implemented logic of `CreateTempDirectory` and processing intermediate files when RunIlAsm related issue: #73 --- RGiesecke.DllExport/DllExportWeaver.cs | 72 ++++++++++++------- .../Extensions/StringExtension.cs | 27 +++++++ RGiesecke.DllExport/GenericDisposable.cs | 44 ------------ .../RGiesecke.DllExport.csproj | 3 +- RGiesecke.DllExport/Utilities.cs | 41 ++++++----- RGiesecke.DllExport/ValueDisposable.cs | 25 ------- 6 files changed, 96 insertions(+), 116 deletions(-) create mode 100644 RGiesecke.DllExport/Extensions/StringExtension.cs delete mode 100644 RGiesecke.DllExport/GenericDisposable.cs delete mode 100644 RGiesecke.DllExport/ValueDisposable.cs diff --git a/RGiesecke.DllExport/DllExportWeaver.cs b/RGiesecke.DllExport/DllExportWeaver.cs index b153c47..62d3605 100644 --- a/RGiesecke.DllExport/DllExportWeaver.cs +++ b/RGiesecke.DllExport/DllExportWeaver.cs @@ -7,11 +7,12 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Security.Permissions; using System.Text; +using RGiesecke.DllExport.Extensions; using RGiesecke.DllExport.Parsing; using RGiesecke.DllExport.Properties; +using TempDir = RGiesecke.DllExport.Utilities.TempDir; namespace RGiesecke.DllExport { @@ -70,38 +71,47 @@ public void Run() } } } - if(this.Exports.Count == 0) + + if(Exports.Count == 0) { return; } - using(this.GetNotifier().CreateContextName((object)this, Resources.CreateTempDirectoryContextName)) + + using(GetNotifier().CreateContextName(this, Resources.CreateTempDirectoryContextName)) + using(var dir = new TempDir()) { - using(ValueDisposable tempDirectory = Utilities.CreateTempDirectory()) + RunIlDasm(dir.FullPath); + + void _ilasm() => RunIlAsm(dir.FullPath); + + if(InputValues.LeaveIntermediateFiles.IsTrue()) { - this.RunIlDasm(tempDirectory.Value); - bool flag = ((IEnumerable)new string[2] { "true", "yes" }).Any((Func)(t => t.Equals(this.InputValues.LeaveIntermediateFiles, StringComparison.InvariantCultureIgnoreCase))); - if(flag) - { - using(this.GetNotifier().CreateContextName((object)this, Resources.CopyBeforeContextName)) - DllExportWeaver.CopyDirectory(tempDirectory.Value, Path.Combine(Path.GetDirectoryName(this.InputValues.OutputFileName), "Before"), true); - } - using(IlAsm ilAsm = this.PrepareIlAsm(tempDirectory.Value)) - this.RunIlAsm(ilAsm); - if(!flag) - { - return; - } - using(this.GetNotifier().CreateContextName((object)this, Resources.CopyAfterContextName)) - DllExportWeaver.CopyDirectory(tempDirectory.Value, Path.Combine(Path.GetDirectoryName(this.InputValues.OutputFileName), "After"), true); + MakeWithIntermediateFiles(dir, _ilasm); + return; } + + _ilasm(); } } - private IDllExportNotifier GetNotifier() + private void MakeWithIntermediateFiles(TempDir dir, Action ilasm) { - return this.ServiceProvider.GetService(); + const string _PRE = "Before"; + const string _POST = "After"; + + string fout = Path.GetDirectoryName(InputValues.OutputFileName); + + using(GetNotifier().CreateContextName(this, Resources.CopyBeforeContextName)) + CopyDirectory(dir.FullPath, Path.Combine(fout, _PRE), true); + + ilasm?.Invoke(); + + using(GetNotifier().CreateContextName(this, Resources.CopyAfterContextName)) + CopyDirectory(dir.FullPath, Path.Combine(fout, _POST), true); } + private IDllExportNotifier GetNotifier() => ServiceProvider.GetService(); + private static string GetCleanedDirectoryPath(string path) { if(path == null) @@ -144,16 +154,24 @@ private static void CopyDirectory(string sourceDirectory, string destinationDire } } - private void RunIlAsm(IlAsm ilAsm) + private void RunIlAsm(string tempDir) { - using(GetNotifier().CreateContextName(this, "RunIlAsm")) + using(IlAsm ilAsm = PrepareIlAsm(tempDir ?? throw new ArgumentNullException(nameof(tempDir)))) + { + RunIlAsm(ilAsm); + } + } + + private IlAsm RunIlAsm(IlAsm ilAsm) + { + using(GetNotifier().CreateContextName(this, nameof(RunIlAsm))) { if(InputValues.Cpu != CpuPlatform.AnyCpu) { - reassembleFile(ilAsm, InputValues.OutputFileName, "", InputValues.Cpu); - return; + reassembleFile(ilAsm, InputValues.OutputFileName, string.Empty, InputValues.Cpu); + return ilAsm; } - string dir = Path.GetDirectoryName(InputValues.OutputFileName) ?? ""; + string dir = Path.GetDirectoryName(InputValues.OutputFileName) ?? string.Empty; string fileName = Path.GetFileName(InputValues.OutputFileName); if(!Directory.Exists(dir)) { @@ -163,6 +181,8 @@ private void RunIlAsm(IlAsm ilAsm) reassembleFile(ilAsm, Path.Combine(Path.Combine(dir, "x86"), fileName), ".x86", CpuPlatform.X86); reassembleFile(ilAsm, Path.Combine(Path.Combine(dir, "x64"), fileName), ".x64", CpuPlatform.X64); } + + return ilAsm; } private IlAsm PrepareIlAsm(string tempDirectory) diff --git a/RGiesecke.DllExport/Extensions/StringExtension.cs b/RGiesecke.DllExport/Extensions/StringExtension.cs new file mode 100644 index 0000000..ef6c1a6 --- /dev/null +++ b/RGiesecke.DllExport/Extensions/StringExtension.cs @@ -0,0 +1,27 @@ +//# Author of original code ([Decompiled] MIT-License): Copyright (c) 2009-2015 Robert Giesecke +//# Use Readme & LICENSE files for details. + +//# Modifications: Copyright (c) 2016-2020 Denis Kuzmin < x-3F@outlook.com > GitHub/3F +//$ Distributed under the MIT License (MIT) + +namespace RGiesecke.DllExport.Extensions +{ + internal static class StringExtension + { + internal static bool IsTrue(this string str) + { + if(string.IsNullOrEmpty(str)) + { + return false; + } + + switch(str) + { + case "1": case "true": case "True": case "TRUE": return true; + /* legacy */ case "yes": case "Yes": case "YES": return true; + } + + return false; + } + } +} diff --git a/RGiesecke.DllExport/GenericDisposable.cs b/RGiesecke.DllExport/GenericDisposable.cs deleted file mode 100644 index 4bb59eb..0000000 --- a/RGiesecke.DllExport/GenericDisposable.cs +++ /dev/null @@ -1,44 +0,0 @@ -//# Author of original code ([Decompiled] MIT-License): Copyright (c) 2009-2015 Robert Giesecke -//# Use Readme & LICENSE files for details. - -//# Modifications: Copyright (c) 2016-2020 Denis Kuzmin < x-3F@outlook.com > GitHub/3F -//$ Distributed under the MIT License (MIT) - -using System; - -namespace RGiesecke.DllExport -{ - public class GenericDisposable: IDisposable - { - private readonly Action _Action; - - public GenericDisposable(Action action) - { - _Action = action ?? throw new ArgumentNullException(nameof(action)); - } - - #region IDisposable - - // To detect redundant calls - private bool disposed = false; - - // To correctly implement the disposable pattern. /CA1063 - public void Dispose() - { - Dispose(true); - } - - protected virtual void Dispose(bool disposing) - { - if(disposed) { - return; - } - disposed = true; - - //... - _Action(); - } - - #endregion - } -} diff --git a/RGiesecke.DllExport/RGiesecke.DllExport.csproj b/RGiesecke.DllExport/RGiesecke.DllExport.csproj index f6777c6..0af0612 100644 --- a/RGiesecke.DllExport/RGiesecke.DllExport.csproj +++ b/RGiesecke.DllExport/RGiesecke.DllExport.csproj @@ -49,11 +49,11 @@ + - @@ -74,7 +74,6 @@ - diff --git a/RGiesecke.DllExport/Utilities.cs b/RGiesecke.DllExport/Utilities.cs index af15f40..4af48ec 100644 --- a/RGiesecke.DllExport/Utilities.cs +++ b/RGiesecke.DllExport/Utilities.cs @@ -95,33 +95,36 @@ public static T TryInitialize(this T instance, Action call) where T : IDis } } - public static ValueDisposable CreateTempDirectory() + internal sealed class TempDir: IDisposable { - return new ValueDisposable(Utilities.CreateTempDirectoryCore(), (Action)(dir => Directory.Delete(dir, true))); - } + public string FullPath { get; } - private static string CreateTempDirectoryCore() - { - string path1 = (string)null; - try + public TempDir() { - string tempFileName = Path.GetTempFileName(); - if(!string.IsNullOrEmpty(tempFileName) && File.Exists(tempFileName)) - { - File.Delete(tempFileName); - } - string path2 = Path.Combine(Path.GetFullPath(Path.GetDirectoryName(tempFileName)), Path.GetFileNameWithoutExtension(tempFileName)); - Directory.CreateDirectory(path2); - return path2; + string path = Path.GetTempPath(); + string name = Guid.NewGuid().ToString(); + + FullPath = Path.Combine(path, $"dxp-{name}"); + Directory.CreateDirectory(FullPath); } - catch + + #region IDisposable + + private bool disposed; + + private void Dispose(bool _) { - if(!string.IsNullOrEmpty(path1) && Directory.Exists(path1)) + if(!disposed) { - Directory.Delete(path1, true); + if(Directory.Exists(FullPath)) Directory.Delete(FullPath, true); + + disposed = true; } - throw; } + + public void Dispose() => Dispose(true); + + #endregion } } } diff --git a/RGiesecke.DllExport/ValueDisposable.cs b/RGiesecke.DllExport/ValueDisposable.cs deleted file mode 100644 index b93bee4..0000000 --- a/RGiesecke.DllExport/ValueDisposable.cs +++ /dev/null @@ -1,25 +0,0 @@ -//# Author of original code ([Decompiled] MIT-License): Copyright (c) 2009-2015 Robert Giesecke -//# Use Readme & LICENSE files for details. - -//# Modifications: Copyright (c) 2016-2020 Denis Kuzmin < x-3F@outlook.com > GitHub/3F -//$ Distributed under the MIT License (MIT) - -using System; - -namespace RGiesecke.DllExport -{ - public class ValueDisposable: GenericDisposable - { - public T Value - { - get; - private set; - } - - public ValueDisposable(T value, Action action) - : base((Action)(() => action(value))) - { - this.Value = value; - } - } -}