Skip to content

Commit

Permalink
Make format of arguments more flexible
Browse files Browse the repository at this point in the history
  • Loading branch information
yangzhongke committed Mar 17, 2022
1 parent f6b8996 commit df99cd0
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 117 deletions.
54 changes: 54 additions & 0 deletions Zack.DotNetTrimmer/CmdLineArgsParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Zack.DotNetTrimmerLib;

namespace Zack.DotNetTrimmer
{
static class CmdLineArgsParser
{
public static TimmerOptions Parse(string[] args)
{
//--greedy --record d:/1.json --file d:/1.exe
//--record d:/1.json --greedy --file d:/1.exe a b
//--greedy --file d:/1.exe a b
//--file d:/1.exe
//--apply d:/1.json --greedy --file d:/1.exe
TimmerOptions options = new TimmerOptions();
int greedyIndex = FindArgIndex(args, "--greedy");
options.Greedy = greedyIndex >= 0;
int recordIndex = FindArgIndex(args, "--record");
int applyIndex = FindArgIndex(args, "--apply");
if (recordIndex >= 0)
{
options.Mode = TrimmingMode.Record;
options.RecordFileName = args[recordIndex + 1];
}
else if (applyIndex >= 0)
{
options.Mode = TrimmingMode.Apply;
options.RecordFileName = args[applyIndex + 1];
}
else
{
options.Mode = TrimmingMode.Direct;
}
int fileIndex = FindArgIndex(args, "--file");
if (fileIndex >= 0)
{
options.StartupFile = args[fileIndex + 1];
options.Arguments = args.Skip(fileIndex + 1).ToArray();
}
return options;
}

static int FindArgIndex(string[] args, string value)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i].Equals(value, StringComparison.OrdinalIgnoreCase))
{
return i;
}
}
return -1;
}
}
}
68 changes: 18 additions & 50 deletions Zack.DotNetTrimmer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,26 @@
//https://docs.microsoft.com/en-us/dotnet/core/dependency-loading/collect-details

using System.Reflection;
using Zack.DotNetTrimmer;
using Zack.DotNetTrimmerLib;
using static Zack.DotNetTrimmerLib.ConsoleHelpers;

var asmVer = Assembly.GetExecutingAssembly().GetName().Version;
WriteInfo($"Version:{asmVer}({Environment.OSVersion})");

if (args.Length <= 0)
var options = CmdLineArgsParser.Parse(args);
var startupFile = options.StartupFile;
if (startupFile == null)
{
WriteError("Usage: Zack.DotNetTrimmer.exe d:/a/test.exe arg1 arg2");
WriteError("Usage: Zack.DotNetTrimmer.exe --record d:/1.json d:/a/test.exe arg1 arg2");
WriteError("Usage: Zack.DotNetTrimmer.exe --apply d:/1.json d:/a/test.exe arg1 arg2");
WriteError($"Error: Please specify the full path of the application");
PrintUsage();
return;
}
//--record d:/1.json
//--apply d:/1.json
string firstParameter = args[0];
string? recordFileName = null;

string startupFile;
string[] arguments;
TrimmingMode mode;
if (firstParameter.StartsWith("--"))
{
if (firstParameter == "--record")
{
mode = TrimmingMode.Record;
}
else if (firstParameter == "--apply")
{
mode = TrimmingMode.Apply;
}
else
{
WriteError("Error: Invalid mode, only --record and --apply are allowed.");
return;
}
recordFileName = args[1];
startupFile = args[2];
arguments = args.Skip(3).ToArray();
}
else
{
mode = TrimmingMode.Direct;
startupFile = args[0];
arguments = args.Skip(1).ToArray();
}

if (!Path.IsPathRooted(startupFile))
{
WriteError($"Error: Please specify the full path instead of {startupFile}");
PrintUsage();
return;
}

Expand All @@ -71,18 +41,16 @@
WriteWarning($"Warning! It looks like {Path.GetFileName(startupFile)} is generated using 'Produce single file', which is not supported. ");
}
string backupDir = BackupHelper.BackupProject(startupFile);
TimmerOptions cmdOpts = new TimmerOptions { Mode = mode, RecordFileName = recordFileName, StartupFile = startupFile, Arguments = arguments };
Trimmer trimmer = new Trimmer(cmdOpts);
trimmer.MessageReceived += (s, e) =>
{
WriteInfo(e.Message);
};
trimmer.FileRemoved += (s, e) =>
{
WriteInfo($"File removed:{e.FileFullPath}");
};
Trimmer trimmer = new Trimmer(options);
trimmer.Run();
if (mode == TrimmingMode.Apply || mode == TrimmingMode.Direct)
{
WriteInfo($"Original files have been backup into {backupDir}");
WriteInfo($"Original files have been backup into {backupDir}");

void PrintUsage()
{
WriteInfo("Usage:");
WriteInfo("--greedy --record d:/1.json --file d:/1.exe ");
WriteInfo("--record d:/1.json --greedy --file d:/1.exe a b");
WriteInfo("--greedy --file d:/1.exe a b");
WriteInfo("--file d:/1.exe ");
WriteInfo("--apply d:/1.json --greedy --file d:/1.exe");
}
2 changes: 1 addition & 1 deletion Zack.DotNetTrimmer/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"配置文件 1": {
"commandName": "Project",
"commandLineArgs": "\"E:\\主同步盘\\我的坚果云\\MyCode\\DOTNET\\Zack.DotNetTrimmer\\ProjectsForTest\\WinForm.NET5TeeChart-NET-Pro-Samples\\bin\\publish\\TeeChart Examples.exe\" --urls=http://localhost:8888/"
"commandLineArgs": "--apply d:/1.json --greedy --file \"E:\\主同步盘\\我的坚果云\\MyCode\\DOTNET\\Zack.DotNetTrimmer\\ProjectsForTest\\WinForm.NET5TeeChart-NET-Pro-Samples\\bin\\publish\\TeeChart Examples.exe\" --urls=http://localhost:8888/"
}
}
}
10 changes: 7 additions & 3 deletions Zack.DotNetTrimmerLib/AssemblyTrimmer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using dnlib.DotNet;
using dnlib.DotNet.MD;

namespace Zack.DotNetTrimmerLib
{
Expand All @@ -12,7 +11,7 @@ public static void TrimAssemblies(string rootDir, HashSet<string> loadedTypes)
if (PEHelpers.IsManagedAssembly(asmFile))
{
TrimAssembly(asmFile, loadedTypes);
}
}
}
}

Expand All @@ -28,7 +27,11 @@ public static void TrimAssembly(string asmFile, HashSet<string> loadedTypes)
{
//Assembly contains more than IL code cannot be trimmed as expected.
//https://github.com/Washi1337/AsmResolver/issues/267
if (!module.IsILOnly) return;
if (!module.IsILOnly)
{
ConsoleHelpers.WriteInfo($"{asmFile} is not ILOnly, skipped.");
return;
}
List<TypeDef> typesToBeRemoved = new List<TypeDef>();
foreach (var type in module.Types)
{
Expand Down Expand Up @@ -56,6 +59,7 @@ public static void TrimAssembly(string asmFile, HashSet<string> loadedTypes)
}
memStream.Position = 0;
File.WriteAllBytes(asmFile, memStream.ToArray());
ConsoleHelpers.WriteInfo($"Unused codes of {asmFile} are trimmed.");
}
}
}
11 changes: 0 additions & 11 deletions Zack.DotNetTrimmerLib/FileRemovedEventArgs.cs

This file was deleted.

7 changes: 7 additions & 0 deletions Zack.DotNetTrimmerLib/IOHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ public static void RemoveFiles(string path, string searchPattern)
foreach (var file in files)
{
File.Delete(file);
ConsoleHelpers.WriteInfo($"{file} removed.");
}
}

public static long GetFolderSize(string dir)
{
var files = Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories);
return files.Sum(f => new FileInfo(f).Length);
}
}
}
28 changes: 28 additions & 0 deletions Zack.DotNetTrimmerLib/JsonHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Text.Json;

namespace Zack.DotNetTrimmerLib
{
static class JsonHelper
{
public static void SaveAsFile(string file, object value)
{
JsonSerializerOptions jsonOpt = new() { WriteIndented = true };
using FileStream fileStream = File.Open(file, FileMode.Create);
JsonSerializer.Serialize(fileStream, value, jsonOpt);
}

public static T LoadFromFile<T>(string file)
{
using FileStream fileStream = File.OpenRead(file);
var obj = JsonSerializer.Deserialize<T>(File.ReadAllText(file));
if (obj == null)
{
throw new IOException("loading error");
}
else
{
return obj;
}
}
}
}
11 changes: 0 additions & 11 deletions Zack.DotNetTrimmerLib/MessageReceivedEventArgs.cs

This file was deleted.

8 changes: 6 additions & 2 deletions Zack.DotNetTrimmerLib/TimmerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
{
public class TimmerOptions
{
/// <summary>
/// Remove unused code from loaded assemblies
/// </summary>
public bool Greedy { get; set; }
public TrimmingMode Mode { get; set; }
public string? RecordFileName { get; set; }
public string StartupFile { get; set; }
public string[] Arguments { get; set; }
public string? StartupFile { get; set; }
public string[] Arguments { get; set; } = new string[0];
}
}
Loading

0 comments on commit df99cd0

Please sign in to comment.