diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 2547dca..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-[*.cs]
-
-# CA1822: Member als statisch markieren
-dotnet_diagnostic.CA1822.severity = none
diff --git a/ExeToBat.sln b/ExeToBat.sln
index 34cdaa3..24ea6f9 100644
--- a/ExeToBat.sln
+++ b/ExeToBat.sln
@@ -1,14 +1,9 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.3.32929.385
+# Visual Studio 15
+VisualStudioVersion = 15.0.28010.2036
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExeToBat", "ExeToBat\ExeToBat.csproj", "{97ED5369-CCC1-4EAD-B316-97FB983E0A62}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1E4294A3-12F4-4F45-93B3-05D31958042B}"
- ProjectSection(SolutionItems) = preProject
- .editorconfig = .editorconfig
- EndProjectSection
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExeToBat", "ExeToBat\ExeToBat.csproj", "{04F45237-23C8-4EE6-B61C-6C47B9979A4B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -16,15 +11,15 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Release|Any CPU.Build.0 = Release|Any CPU
+ {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {9F9811F2-7CC0-4D74-8D4A-51D126D13ECD}
+ SolutionGuid = {4AA99DAC-6B37-42AF-8FB7-8394329BD79A}
EndGlobalSection
EndGlobal
diff --git a/ExeToBat/App.config b/ExeToBat/App.config
new file mode 100644
index 0000000..731f6de
--- /dev/null
+++ b/ExeToBat/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ExeToBat/BatGen.cs b/ExeToBat/BatGen.cs
new file mode 100644
index 0000000..71d65da
--- /dev/null
+++ b/ExeToBat/BatGen.cs
@@ -0,0 +1,720 @@
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace ExeToBat
+{
+ static class Generator
+ {
+ public const int chunk = 8000;
+
+ public static List Sources = new List();
+
+ static void Main() => MainMenu();
+
+ static void MainMenu()
+ {
+ Dictionary options = new Dictionary {
+ { "Files", ChooseSource },
+ { "Generate", () => BuildBat(Sources, "output.bat") }
+ };
+
+ new ListMenu(options.Keys.ToList())
+ {
+ DisplayTitle = (List Options) => Console.WriteLine("ExeToBat > Main"),
+ DisplayEntry = (List Options, int index, int i) =>
+ {
+ Console.WriteLine("[{0}] {1}", i, Options[index]);
+ },
+ HandleEntry = (List Options, int index) =>
+ {
+ if (options.ContainsKey(Options[index]))
+ {
+ options[Options[index]]();
+ }
+ else
+ {
+ ResetInput();
+ }
+
+ return false;
+ },
+ ExitEntry = "Exit",
+
+ }.Show();
+ }
+
+ static void ChooseSource()
+ {
+ new ListMenu(Sources)
+ {
+ DisplayTitle = (List sources) =>
+ {
+ Console.WriteLine("ExeToBat > Main > Files");
+ Console.WriteLine("[{0}] ({1})", Convert.ToString(0).PadLeft(Convert.ToString(sources.Count).Length, ' '), "Add Files");
+ },
+ DisplayEntry = (List sources, int index, int i) =>
+ Console.WriteLine("[{0}] {1}",
+ Convert.ToString(i).PadLeft(
+ Convert.ToString(sources.Count).Length, ' '),
+ Path.GetFileName(sources[index].File)),
+ ZeroEntry = (List sources) =>
+ {
+ AddSource();
+ return false;
+ },
+ HandleEntry = (List sources, int index) =>
+ {
+ ManageSource(sources[index]);
+ return false;
+ },
+ RefreshEntries = (List sources) => Sources,
+
+ }.Show();
+ }
+
+ static void AddSource()
+ {
+ bool IsInputValid = false;
+ while (!IsInputValid)
+ {
+
+ Console.Clear();
+ Console.WriteLine("ExeToBat > Main > Files > Add");
+ Console.Write("\n");
+ Console.Write("{0}> ", "File/Folder");
+ string input = Console.ReadLine();
+
+ input.Trim();
+ input = input.Replace("\"", "");
+ if (!string.IsNullOrEmpty(input))
+ {
+ switch (input)
+ {
+ case var i when Directory.Exists(i):
+ IsInputValid = true;
+ foreach (string file in Directory.GetFiles(input))
+ {
+ Sources.Add(new SourceFile(file));
+ }
+ break;
+
+ case var i when File.Exists(i):
+ IsInputValid = true;
+ Sources.Add(new SourceFile(input));
+ break;
+
+ default:
+ ResetInput();
+ break;
+ }
+ }
+ else
+ {
+ IsInputValid = true;
+ }
+ }
+ }
+
+ static void ManageSource(SourceFile source)
+ {
+ Dictionary> options = new Dictionary>
+ {
+ {"Edit", () => {
+ ModifySource(source);
+ return false;
+ }
+ },
+ { "Position", () => {
+ EditPosition(source);
+ return false;
+ }
+ },
+ { "Delete", () => {
+ Sources.Remove(source);
+ return true;
+ }
+ },
+ };
+
+ new ListMenu(options.Keys.ToList())
+ {
+ DisplayTitle = (List Options) => Console.WriteLine("ExeToBat > Main > Files > {0}", Path.GetFileName(source.File)),
+ DisplayEntry = (List Options, int index, int i) => Console.WriteLine("[{0}] {1}", i, Options[index]),
+ HandleEntry = (List Options, int index) =>
+ {
+ if (options.ContainsKey(Options[index]))
+ {
+ return options[Options[index]]();
+ }
+ else
+ {
+ ResetInput();
+ }
+
+ return false;
+ },
+
+ }.Show();
+ }
+
+ static void ModifySource(SourceFile source)
+ {
+
+ // this could be solved better with an enum
+
+ Dictionary options()
+ {
+ Dictionary opts = new Dictionary {
+ {"File", () => { } },
+ {"Extraction directory", () => EditExtraction(source)},
+ {"Execute after extraction", () => source.Execute = !source.Execute },
+ };
+ if (source.Execute)
+ {
+ opts.Add("Parameters", () => EditParameters(source));
+ opts.Add("Wait for exit", () => source.Wait = !source.Wait);
+ }
+ if (source.Execute && source.Wait) { opts.Add("Delete after execution", () => source.Delete = !source.Delete); }
+ return opts;
+ }
+
+ Dictionary ValueMap = new Dictionary
+ {
+ { "File", "File" },
+ { "Extraction directory", "Directory" },
+ { "Execute after extraction", "Execute" },
+ { "Parameters", "Parameters" },
+ { "Wait for exit", "Wait"},
+ { "Delete after execution", "Delete"},
+ };
+
+ new ListMenu(options().Keys.ToList())
+ {
+ DisplayTitle = (List Options) => Console.WriteLine("ExeToBat > Main > Files > {0} > Edit", Path.GetFileName(source.File)),
+ DisplayEntry = (List Options, int index, int i) =>
+ {
+ int MaxLength = options().Keys.Select(x => x.Length).Max();
+ Console.WriteLine("[{0}] {1} | {2}", i, Options[index].PadRight(MaxLength, ' '), source.GetType().GetProperty(ValueMap[Options[index]]).GetValue(source).ToString());
+ },
+ HandleEntry = (List Options, int index) =>
+ {
+ if (options().ContainsKey(Options[index]))
+ {
+ options()[Options[index]]();
+ }
+ else
+ {
+ ResetInput();
+ }
+
+ return false;
+ },
+ RefreshEntries = (List Options) => options().Keys.ToList(),
+
+ }.Show();
+
+ }
+
+ static void EditExtraction(SourceFile source)
+ {
+ bool IsInputValid = false;
+ while (!IsInputValid)
+ {
+ Console.Clear();
+ Console.WriteLine("ExeToBat > Main > Files > {0} > Edit > Extraction", Path.GetFileName(source.File));
+ Console.Write("\n");
+ Console.WriteLine("Documentation: ");
+ Console.WriteLine("https://ss64.com/nt/syntax-variables.html");
+ Console.WriteLine("https://ss64.com/nt/syntax-args.html");
+ Console.Write("\n");
+ Console.Write("{0}> ", "Directory");
+ string input = Console.ReadLine();
+
+ input.Trim();
+ if (!string.IsNullOrEmpty(input))
+ {
+ source.Directory = input;
+ IsInputValid = true;
+ }
+ else
+ {
+ IsInputValid = true;
+ }
+ }
+ }
+
+ static void EditParameters(SourceFile source)
+ {
+ bool IsInputValid = false;
+ while (!IsInputValid)
+ {
+ Console.Clear();
+ Console.WriteLine("ExeToBat > Main > Files > {0} > Edit > Parameters", Path.GetFileName(source.File));
+ Console.Write("\n");
+ Console.Write("{0}> ", "Parameters");
+ string input = Console.ReadLine();
+
+ input.Trim();
+ if (!string.IsNullOrEmpty(input))
+ {
+ source.Parameters = input;
+ IsInputValid = true;
+ }
+ else
+ {
+ IsInputValid = true;
+ }
+ }
+ }
+
+ static void EditPosition(SourceFile source)
+ {
+ bool IsInputValid = false;
+ while (!IsInputValid)
+ {
+ Console.Clear();
+ Console.WriteLine("ExeToBat > Main > Files > {0} > Position : {1}", Path.GetFileName(source.File), Sources.IndexOf(source));
+
+ Console.Write("\n");
+ Console.Write("{0}> ", "New index");
+ string input = Console.ReadLine();
+
+ if (int.TryParse(input, out int index))
+ {
+ if (index < Sources.Count)
+ {
+ Sources.Remove(source);
+ Sources.Insert(index, source);
+ IsInputValid = true;
+ }
+ else
+ {
+ ResetInput();
+ }
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(input))
+ {
+ IsInputValid = true;
+ }
+ else
+ {
+ ResetInput();
+ }
+ }
+ }
+ }
+
+ static void BuildBat(List sources, string outputFile)
+ {
+ Console.Clear();
+ Console.WriteLine("ExeToBat > Main > Generate");
+
+ if (Sources.Any())
+ {
+ using (StreamWriter writer = new StreamWriter(outputFile))
+ {
+ Console.WriteLine("[Preparing] basic batch structure...");
+ writer.WriteLine("@echo off");
+ writer.WriteLine(":: Auto-generated batch file by ExeToBat ::");
+ writer.WriteLine("");
+
+ foreach (SourceFile source in sources)
+ {
+ Console.WriteLine("[ Reading ] {0}", source.File);
+ List fileChunks = Convert.ToBase64String(File.ReadAllBytes(source.File)).Chunks(chunk).ToList();
+ string tempFile = Path.Combine("%temp%", source.Resource);
+ writer.WriteLine("(");
+
+ int pos = 0;
+ foreach (string part in fileChunks)
+ {
+ pos++;
+ Console.Write("[ Writing ] {0} part {1}/{2}\r", Path.GetFileName(source.File), pos.ToString().PadLeft(fileChunks.Count.ToString().Length, '0'), fileChunks.Count);
+ writer.WriteLine(string.Format("echo {0}", part));
+ }
+
+ Console.WriteLine();
+ writer.WriteLine(string.Format(") >> \"{0}\"", tempFile));
+ writer.WriteLine("");
+
+ Console.WriteLine("[ Writing ] decode mechanism");
+ writer.WriteLine(string.Format("certutil -decode \"{0}\" \"{1}\" >nul 2>&1", tempFile, Path.Combine(source.Directory, Path.GetFileName(source.File))));
+ writer.WriteLine(string.Format("del /f /q \"{0}\" >nul 2>&1", tempFile));
+ writer.WriteLine("");
+
+ if (source.Execute)
+ {
+ string wait;
+ if (source.Wait) { wait = " /wait"; } else { wait = " "; }
+ Console.WriteLine("[ Writing ] execute mechanism");
+ writer.WriteLine(string.Format("start{0} \"\" \"cmd /c {1}\" {2}", wait, Path.Combine(source.Directory, Path.GetFileName(source.File)), source.Parameters));
+ if (source.Wait)
+ {
+ Console.WriteLine("[ Writing ] wait mechanism");
+ if (source.Delete)
+ {
+ Console.WriteLine("[ Writing ] delete mechanism");
+ writer.WriteLine(string.Format("del /f /q \"{0}\" >nul 2>&1", Path.Combine(source.Directory, Path.GetFileName(source.File))));
+ writer.WriteLine("");
+ }
+ }
+
+ writer.WriteLine("");
+
+ }
+
+ writer.Flush();
+ Console.WriteLine("[Generated] {0}", Path.GetFileName(source.File));
+
+ }
+
+ Console.WriteLine("[Generated] All done");
+
+ Console.WriteLine("Press anything...");
+ Console.ReadKey();
+
+ }
+ }
+ else
+ {
+ Console.WriteLine("No files specified");
+ Wait(500);
+
+ }
+
+
+ }
+
+ public class SourceFile
+ {
+ public string File { get; set; }
+ public bool Execute { get; set; } = false;
+ public bool Wait { get; set; } = false;
+ public bool Delete { get; set; } = false;
+ public string Resource { get; set; } = GenTemp();
+ public string Directory { get; set; } = "%~dp0";
+ public string Parameters { get; set; } = "";
+
+
+ public SourceFile(string file)
+ {
+ File = file;
+ }
+
+ static public string GenTemp()
+ {
+ return string.Format($"res_{new Random().Next(1000, 10000)}.b64");
+ }
+
+ }
+
+ static string[] Chunks(this string toSplit, int chunkSize)
+ {
+ int stringLength = toSplit.Length;
+
+ int chunksRequired = (int)Math.Ceiling(stringLength / (decimal)chunkSize);
+ var stringArray = new string[chunksRequired];
+
+ int lengthRemaining = stringLength;
+
+ for (int i = 0; i < chunksRequired; i++)
+ {
+ int lengthToUse = Math.Min(lengthRemaining, chunkSize);
+ int startIndex = chunkSize * i;
+ stringArray[i] = toSplit.Substring(startIndex, lengthToUse);
+
+ lengthRemaining -= lengthToUse;
+ }
+
+ return stringArray;
+ }
+
+
+
+ public static void Wait(int ms)
+ {
+ using (System.Threading.ManualResetEvent wait = new System.Threading.ManualResetEvent(false))
+ {
+ wait.WaitOne(ms);
+ }
+ }
+
+ public class ListMenu
+ {
+
+ ///
+ /// CLOE (Command-line List Options Enumerator).
+ /// Turns a List into a menu of options. Each list item is asigned a number. Provides several callbacks to customise the menu.
+ ///
+ /// List of objects you want to display
+ public ListMenu(List entries)
+ {
+ Entries = entries;
+ }
+
+ ///
+ /// The prompt that is displayed to the user.
+ ///
+ public string Prompt = "Choose";
+
+ ///
+ /// The string to be displayed for the option to exit the menu.
+ ///
+ public string ExitEntry = "Back";
+
+ ///
+ /// The key the user has to press to exit the menu.
+ ///
+ public char ExitKey = 'q';
+
+ ///
+ /// Wether or not the user can exit the menu.
+ ///
+ public bool UserCanExit = true;
+
+
+ private List Entries;
+
+ ///
+ /// The function that processes the chosen menu entries.
+ ///
+ public Func, int, bool> HandleEntry = (entries, index) =>
+ {
+ Console.Clear();
+ Console.WriteLine(entries[index]);
+ Wait(200);
+ return false;
+ };
+
+ ///
+ /// The function that displays the menu title.
+ ///
+ public Action> DisplayTitle = (entries) => { };
+
+ ///
+ /// The function that displays the entry to the user.
+ ///
+ public Action, int, int> DisplayEntry = (entries, index, num) =>
+ {
+ Console.WriteLine("[{0}] {1}", Convert.ToString(num).PadLeft(Convert.ToString(entries.Count).Length, ' '), entries[index]);
+ };
+
+ ///
+ /// The function to update the list of entries.
+ ///
+ public Func, List> RefreshEntries = (entries) =>
+ {
+ return entries;
+ };
+
+ ///
+ /// The function that is called when 0th entry in the list is chosen.
+ /// Display this entry with the title function.
+ ///
+ public Func, bool> ZeroEntry = (entries) =>
+ {
+ ResetInput();
+ return false;
+ };
+
+ ///
+ /// Display the menu.
+ ///
+ ///
+ public ListMenu Show()
+ {
+ string readInput = string.Empty;
+ bool MenuExitIsPending = false;
+ while (!MenuExitIsPending)
+ {
+ Console.Clear();
+ int printedEntries = 0;
+ Entries = RefreshEntries(Entries);
+ DisplayTitle(Entries);
+ if (Entries.Any())
+ {
+ int num = 0;
+ foreach (T entry in Entries)
+ {
+ num++;
+ if (string.IsNullOrEmpty(readInput) || Convert.ToString(num).StartsWith(readInput))
+ {
+ DisplayEntry(Entries, Entries.IndexOf(entry), num);
+ printedEntries++;
+ }
+
+ if (Entries.Count > Console.WindowHeight - 5)
+ {
+ if (printedEntries >= Console.WindowHeight - (5 + 1))
+ {
+ Console.WriteLine("[{0}] +{1}", ".".PadLeft(Convert.ToString(Entries.Count).Length, '.'), Entries.Count);
+ break;
+ }
+ }
+ else
+ {
+ if (printedEntries == Console.WindowHeight - 5)
+ {
+ break;
+ }
+ }
+
+ }
+ }
+
+ if (UserCanExit)
+ {
+ Console.WriteLine("[{0}] {1}", Convert.ToString(ExitKey).PadLeft(Convert.ToString(Entries.Count).Length, ' '), ExitEntry);
+ }
+
+ Console.WriteLine();
+
+ bool InputIsValid = false;
+ while (!InputIsValid)
+ {
+ Console.Write("{0}> {1}", Prompt, readInput);
+ ConsoleKeyInfo input = Console.ReadKey();
+ Wait(20);
+ int choiceNum = -1;
+ switch (input)
+ {
+ case var key when key.KeyChar.Equals(ExitKey):
+ if (UserCanExit)
+ {
+ Console.WriteLine();
+ InputIsValid = true;
+ MenuExitIsPending = true;
+ }
+ else
+ {
+ Console.WriteLine();
+ ResetInput();
+ }
+ break;
+
+ case var key when key.Key.Equals(ConsoleKey.Backspace):
+ if (!string.IsNullOrEmpty(readInput))
+ {
+ Console.Write("\b");
+ readInput = readInput.Remove(readInput.Length - 1);
+ }
+ InputIsValid = true;
+ break;
+
+ case var key when key.Key.Equals(ConsoleKey.Enter):
+ if (!string.IsNullOrEmpty(readInput))
+ {
+ if (HandleEntry(Entries, (Convert.ToInt32(readInput) - 1)))
+ {
+ MenuExitIsPending = true;
+ }
+ readInput = string.Empty;
+ }
+ InputIsValid = true;
+ break;
+
+ case var key when int.TryParse(key.KeyChar.ToString(), out choiceNum):
+ Console.WriteLine();
+ if (string.IsNullOrEmpty(readInput) && choiceNum.Equals(0))
+ {
+ InputIsValid = true;
+ if (ZeroEntry(Entries))
+ {
+ MenuExitIsPending = true;
+ }
+ }
+ else
+ {
+ if (Convert.ToInt32(readInput + Convert.ToString(choiceNum)) <= Entries.Count)
+ {
+ InputIsValid = true;
+ int matchingEntries = 0;
+ readInput = new System.Text.StringBuilder().Append(readInput).Append(Convert.ToString(choiceNum)).ToString();
+ for (int i = 0; i < Entries.Count; i++)
+ {
+ if (Convert.ToString(i + 1).StartsWith(readInput) || Convert.ToString(i + 1) == readInput) { matchingEntries++; }
+ }
+ if ((readInput.Length == Convert.ToString(Entries.Count).Length) || (matchingEntries == 1))
+ {
+ if (HandleEntry(Entries, (Convert.ToInt32(readInput) - 1)))
+ {
+ MenuExitIsPending = true;
+ }
+ readInput = string.Empty;
+ }
+ }
+ else
+ {
+ ResetInput();
+ }
+ }
+ break;
+
+ default:
+ Console.WriteLine();
+ ResetInput();
+ break;
+ }
+ }
+ }
+ return this;
+ }
+ }
+
+ ///
+ /// A simple template to create Yes or No menus.
+ ///
+ /// The title of the menu.
+ /// The function to be called upon Yes
+ /// The function to be called upon No
+ public static void YesNoMenu(string title, Action Yes, Action No)
+ {
+ bool IsInputValid = false;
+ while (!IsInputValid)
+ {
+ Console.Write("{0}? [{1}]> ", title, "Y/N");
+ string Input = Console.ReadKey().KeyChar.ToString();
+ Wait(20);
+ Console.Write("\n");
+ if (string.Equals(Input, "Y", StringComparison.OrdinalIgnoreCase))
+ {
+ IsInputValid = true;
+ Yes();
+
+ }
+ else if (string.Equals(Input, "N", StringComparison.OrdinalIgnoreCase))
+ {
+ IsInputValid = true;
+ No();
+ }
+ else
+ {
+ ResetInput();
+ }
+ }
+ }
+
+ public static void ResetInput(string error = "Input Invalid")
+ {
+ Console.Write(string.Format("[{0}] {1}", "Error", error));
+ Wait(150);
+ ClearCurrentConsoleLine();
+ Console.SetCursorPosition(0, Console.CursorTop - 1);
+ ClearCurrentConsoleLine();
+ }
+
+ public static void ClearCurrentConsoleLine()
+ {
+ int currentLineCursor = Console.CursorTop;
+ Console.SetCursorPosition(0, Console.CursorTop);
+ Console.Write(new string(' ', Console.BufferWidth));
+ Console.SetCursorPosition(0, currentLineCursor);
+ }
+
+ }
+
+}
diff --git a/ExeToBat/Console.cs b/ExeToBat/Console.cs
deleted file mode 100644
index 2742be4..0000000
--- a/ExeToBat/Console.cs
+++ /dev/null
@@ -1,485 +0,0 @@
-using static ExeToBat.Generator;
-using static System.ConsoleUtils;
-using Mono.Options;
-using System.Text.Json;
-using System.Reflection;
-
-namespace ExeToBat
-{
- class Console
- {
- public static void Main(string[] args) => new Console().Show(args);
-
- public Console() { }
-
- private readonly Generator generator = new();
-
- public void Show(string[] args)
- {
- string? config = null;
- bool help = false;
-
- OptionSet options =
- new()
- {
- {
- "c|config=",
- "the config file used for automatic generation",
- v => config = v
- },
- { "h|help", "show this message and exit", v => help = v != null },
- };
-
- try
- {
- List extra = options.Parse(args);
- if (help)
- {
- Help(options);
- }
- else if (config != null)
- {
- try
- {
- generator.LoadConfig(GeneratorConfig.FromJson(File.ReadAllText(config)));
- Generate(interactive: false);
- }
- catch (Exception e) when (e is IOException || e is JsonException)
- {
- System.Console.WriteLine("Failed to load config {0}:\n{1}", config, e.Message);
- }
- }
- else
- {
- MainMenu();
- }
- }
- catch (OptionException e)
- {
- System.Console.WriteLine("Invalid arguments: {0}", e.Message);
- Help(options);
- }
- }
-
- public void Show() => MainMenu();
-
- private void Help(OptionSet options)
- {
- string version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "";
- System.Console.WriteLine();
- System.Console.WriteLine(string.Format("ExeToBat {0}", version));
- System.Console.WriteLine();
- System.Console.WriteLine("From github.com/clragon/ExeToBat");
- System.Console.WriteLine("Licensed under GNUPL v3");
- System.Console.WriteLine();
- System.Console.WriteLine("Usage:");
- options.WriteOptionDescriptions(System.Console.Out);
- }
-
- private void MainMenu()
- {
- Dictionary options =
- new()
- {
- { "Files", ChooseSource },
- { "Save config", SaveConfig },
- { "Load config", LoadConfig },
- { "Generate", Generate },
- };
-
- new ListMenu(options.Keys.ToList())
- {
- DisplayTitle = (Options) => System.Console.WriteLine("ExeToBat"),
- DisplayEntry = (Options, index, i) =>
- {
- System.Console.WriteLine("[{0}] {1}", i, Options[index]);
- },
- HandleEntry = (Options, index) =>
- {
- options[Options[index]]();
- return false;
- },
- ExitEntry = "Exit",
- }.Show();
- }
-
- private void SaveConfig()
- {
- bool IsInputValid = false;
- while (!IsInputValid)
- {
- System.Console.Clear();
- System.Console.WriteLine("ExeToBat > Config > Save");
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "Output File");
- string? input = System.Console.ReadLine();
-
- input = input?.Trim()?.Replace("\"", "");
- if (!string.IsNullOrEmpty(input))
- {
- try
- {
- File.WriteAllText(input, generator.SaveConfig().ToJson());
- IsInputValid = true;
- }
- catch (IOException e)
- {
- System.Console.WriteLine("Failed to save config:\n{0}", e.Message);
- ResetInput();
- }
- }
- }
- }
-
- private void LoadConfig()
- {
- bool IsInputValid = false;
- while (!IsInputValid)
- {
- System.Console.Clear();
- System.Console.WriteLine("ExeToBat > Config > Load");
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "Config File");
- string? input = System.Console.ReadLine();
-
- input = input?.Trim()?.Replace("\"", "");
- if (!string.IsNullOrEmpty(input))
- {
- try
- {
- generator.LoadConfig(GeneratorConfig.FromJson(File.ReadAllText(input)));
- IsInputValid = true;
- }
- catch (Exception e) when (e is IOException || e is JsonException)
- {
- System.Console.WriteLine("Failed to load config {0}:\n{1}", input, e.Message);
- ResetInput();
- }
- }
- }
- }
-
- private void ChooseSource()
- {
- new ListMenu(generator.Sources)
- {
- DisplayTitle = (sources) =>
- {
- System.Console.WriteLine("ExeToBat > Files");
- System.Console.WriteLine(
- "[{0}] ({1})",
- Convert.ToString(0).PadLeft(Convert.ToString(sources.Count).Length, ' '),
- "Add Files"
- );
- },
- DisplayEntry = (sources, index, i) =>
- System.Console.WriteLine(
- "[{0}] {1}",
- Convert.ToString(i).PadLeft(Convert.ToString(sources.Count).Length, ' '),
- Path.GetFileName(sources[index].Path)
- ),
- ZeroEntry = (sources) =>
- {
- AddSource();
- return false;
- },
- HandleEntry = (sources, index) =>
- {
- ManageSource(sources[index]);
- return false;
- },
- RefreshEntries = (sources) => generator.Sources,
- }.Show();
- }
-
- private void AddSource()
- {
- bool IsInputValid = false;
- while (!IsInputValid)
- {
- System.Console.Clear();
- System.Console.WriteLine("ExeToBat > Files > Add");
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "File/Folder");
- string? input = System.Console.ReadLine();
-
- input = input?.Trim()?.Replace("\"", "");
- switch (input)
- {
- case var i when string.IsNullOrEmpty(i):
- IsInputValid = true;
- break;
- case var i when Directory.Exists(i):
- IsInputValid = true;
- foreach (string file in Directory.GetFiles(i))
- {
- generator.Sources.Add(new SourceFile(file));
- }
- break;
- case var i when File.Exists(i):
- IsInputValid = true;
- generator.Sources.Add(new SourceFile(i));
- break;
-
- default:
- ResetInput();
- break;
- }
- }
- }
-
- private void ManageSource(SourceFile source)
- {
- Dictionary> options =
- new()
- {
- {
- "Edit",
- () =>
- {
- ModifySource(source);
- return false;
- }
- },
- {
- "Position",
- () =>
- {
- EditPosition(source);
- return false;
- }
- },
- {
- "Delete",
- () =>
- {
- generator.Sources.Remove(source);
- return true;
- }
- },
- };
-
- new ListMenu(options.Keys.ToList())
- {
- DisplayTitle = (Options) =>
- System.Console.WriteLine(
- "ExeToBat > Files > {0}",
- Path.GetFileName(source.Path)
- ),
- DisplayEntry = (Options, index, i) =>
- System.Console.WriteLine("[{0}] {1}", i, Options[index]),
- HandleEntry = (Options, index) => options[Options[index]](),
- }.Show();
- }
-
- private void ModifySource(SourceFile source)
- {
- List<(string, string, Action)> options()
- {
- List<(string, string, Action)> result =
- new()
- {
- ("File", source.Path, () => { }),
- ("Extraction directory", source.Directory, () => EditExtraction(source)),
- (
- "Execute after extraction",
- source.Execute.ToString(),
- () => source.Execute = !source.Execute
- ),
- };
- if (source.Execute)
- {
- result.Add(("Parameters", source.Parameters, () => EditParameters(source)));
- result.Add(
- ("Wait for exit", source.Wait.ToString(), () => source.Wait = !source.Wait)
- );
- }
- if (source.Execute && source.Wait)
- {
- result.Add(
- (
- "Delete after execution",
- source.Delete.ToString(),
- () => source.Delete = !source.Delete
- )
- );
- }
- return result;
- }
-
- new ListMenu<(string, string, Action)>(options())
- {
- DisplayTitle = (Options) =>
- System.Console.WriteLine(
- "ExeToBat > Files > {0} > Edit",
- Path.GetFileName(source.Path)
- ),
- DisplayEntry = (Options, index, i) =>
- {
- int MaxLength = options().ConvertAll(e => e.Item1.Length).Max();
- System.Console.WriteLine(
- "[{0}] {1} | {2}",
- i,
- Options[index].Item1.PadRight(MaxLength, ' '),
- Options[index].Item2
- );
- },
- HandleEntry = (Options, index) =>
- {
- Options[index].Item3();
- return false;
- },
- RefreshEntries = (Options) => options(),
- }.Show();
- }
-
- private void EditExtraction(SourceFile source)
- {
- System.Console.Clear();
- System.Console.WriteLine(
- "ExeToBat > Files > {0} > Edit > Extraction",
- Path.GetFileName(source.Path)
- );
- System.Console.WriteLine();
- System.Console.WriteLine("Documentation: ");
- System.Console.WriteLine("https://ss64.com/nt/syntax-variables.html");
- System.Console.WriteLine("https://ss64.com/nt/syntax-args.html");
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "Directory");
- string? input = System.Console.ReadLine();
-
- if (!string.IsNullOrEmpty(input))
- {
- source.Directory = input;
- }
- }
-
- private void EditParameters(SourceFile source)
- {
- System.Console.Clear();
- System.Console.WriteLine(
- "ExeToBat > Files > {0} > Edit > Parameters",
- Path.GetFileName(source.Path)
- );
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "Parameters");
- string? input = System.Console.ReadLine();
-
- input = input?.Trim();
- if (!string.IsNullOrEmpty(input))
- {
- source.Parameters = input;
- }
- }
-
- private void EditPosition(SourceFile source)
- {
- bool IsInputValid = false;
- while (!IsInputValid)
- {
- System.Console.Clear();
- System.Console.WriteLine(
- "ExeToBat > Files > {0} > Position : {1}",
- Path.GetFileName(source.Path),
- generator.Sources.IndexOf(source)
- );
-
- System.Console.WriteLine();
- System.Console.Write("{0}> ", "New index");
- string? input = System.Console.ReadLine();
-
- if (int.TryParse(input, out int index))
- {
- if (index < generator.Sources.Count)
- {
- generator.Sources.Remove(source);
- generator.Sources.Insert(index, source);
- IsInputValid = true;
- }
- else
- {
- ResetInput();
- }
- }
- else
- {
- if (string.IsNullOrEmpty(input))
- {
- IsInputValid = true;
- }
- else
- {
- ResetInput();
- }
- }
- }
- }
-
- private void Generate() => Generate(true);
-
- private void Generate(bool interactive)
- {
- System.Console.Clear();
- System.Console.WriteLine("ExeToBat > Generate");
-
- generator.Generation += OnGenerate;
-
- generator.Generate("output.bat");
-
- generator.Generation -= OnGenerate;
-
- if (interactive)
- {
- System.Console.WriteLine("Press anything...");
- System.Console.ReadKey();
- }
- }
-
- private void OnGenerate(object? sender, GeneratorEvent e)
- {
- switch (e)
- {
- case GenerationStartEvent s:
- System.Console.WriteLine("Starting generation...");
- System.Console.WriteLine("{0} files scheduled", s.Files.Count);
- break;
- case ReadingFileEvent s:
- System.Console.WriteLine("[{0}] Reading file", s.File.Path);
- break;
- case WritingFilePartEvent s:
- System.Console.Write(
- "[{0}] writing part {1}/{2}\r",
- s.File.Path,
- s.Part.ToString().PadLeft(s.Max.ToString().Length, '0'),
- s.Max
- );
- break;
- case WritingFileDecoderEvent s:
- System.Console.WriteLine();
- System.Console.WriteLine("[{0}] Writing decode mechanism", s.File.Path);
- break;
- case WritingFileExecuteEvent s:
- System.Console.WriteLine("[{0}] Writing execute mechanism", s.File.Path);
- break;
- case WritingFileWaitEvent s:
- System.Console.WriteLine("[{0}] Writing wait mechanism", s.File.Path);
- break;
- case WritingFileDeleteEvent s:
- System.Console.WriteLine("[{0}] Writing delete mechanism", s.File.Path);
- break;
- case WritingFileCompleteEvent s:
- System.Console.WriteLine("[{0}] Finshed generating!", s.File.Path);
- break;
- case GenerationCompleteEvent s:
- System.Console.WriteLine("Finished generation! Result written to {0}", s.Path);
- break;
- case GenerationEmptyEvent _:
- System.Console.WriteLine("No files specified");
- break;
- case GenerationFailedEvent s:
- System.Console.WriteLine("Generation failed with:\n{0}", s.Error.Message);
- break;
- }
- }
- }
-}
diff --git a/ExeToBat/ConsoleUtils.cs b/ExeToBat/ConsoleUtils.cs
deleted file mode 100644
index 77c0d20..0000000
--- a/ExeToBat/ConsoleUtils.cs
+++ /dev/null
@@ -1,328 +0,0 @@
-namespace System
-{
- public static class ConsoleUtils
- {
- ///
- /// Pauses the thread for a duration.
- ///
- /// The duration to pause.
- public static void Wait(int ms)
- {
- using (Threading.ManualResetEvent wait = new Threading.ManualResetEvent(false))
- {
- wait.WaitOne(ms);
- }
- }
-
- ///
- /// Clears the current line of the Console.
- ///
- public static void ClearCurrentConsoleLine()
- {
- int currentLineCursor = Console.CursorTop;
- Console.SetCursorPosition(0, Console.CursorTop);
- Console.Write(new string(' ', Console.BufferWidth));
- Console.SetCursorPosition(0, currentLineCursor);
- }
-
- ///
- /// Deletes the last line of the console and displays an error for a short duration.
- ///
- /// The error to display.
- public static void ResetInput(string error = "Input Invalid")
- {
- Console.Write(string.Format("[{0}] {1}", "Error", error));
- Wait(150);
- ClearCurrentConsoleLine();
- Console.SetCursorPosition(0, Console.CursorTop - 1);
- ClearCurrentConsoleLine();
- }
-
- ///
- /// A simple template to create Yes or No menus.
- ///
- /// The title of the menu.
- /// The function to be called upon Yes
- /// The function to be called upon No
- public static void YesNoMenu(string title, Action Yes, Action No)
- {
- bool IsInputValid = false;
- while (!IsInputValid)
- {
- Console.Write("{0}? [{1}]> ", title, "Y/N");
- string Input = Console.ReadKey().KeyChar.ToString();
- Wait(20);
- Console.Write("\n");
- if (string.Equals(Input, "Y", StringComparison.OrdinalIgnoreCase))
- {
- IsInputValid = true;
- Yes();
- }
- else if (string.Equals(Input, "N", StringComparison.OrdinalIgnoreCase))
- {
- IsInputValid = true;
- No();
- }
- else
- {
- ResetInput();
- }
- }
- }
-
- public class ListMenu
- {
- ///
- /// Command-line List Options Enumerator
- /// Turns a List into a menu of options. Each list item is asigned a number. Provides several callbacks to customise the menu.
- ///
- /// List of objects you want to display
- public ListMenu(List entries)
- {
- Entries = entries;
- }
-
- ///
- /// The prompt that is displayed to the user.
- ///
- public string Prompt = "Choose";
-
- ///
- /// The string to be displayed for the option to exit the menu.
- ///
- public string ExitEntry = "Back";
-
- ///
- /// The key the user has to press to exit the menu.
- ///
- public char ExitKey = 'q';
-
- ///
- /// Wether or not the user can exit the menu.
- ///
- public bool UserCanExit = true;
-
- private List Entries;
-
- ///
- /// The function that processes the chosen menu entries.
- ///
- public Func, int, bool> HandleEntry = (entries, index) =>
- {
- Console.Clear();
- Console.WriteLine(entries[index]);
- Wait(200);
- return false;
- };
-
- ///
- /// The function that displays the menu title.
- ///
- public Action> DisplayTitle = (entries) => { };
-
- ///
- /// The function that displays the entry to the user.
- ///
- public Action, int, int> DisplayEntry = (entries, index, num) =>
- {
- Console.WriteLine(
- "[{0}] {1}",
- Convert.ToString(num).PadLeft(Convert.ToString(entries.Count).Length, ' '),
- entries[index]
- );
- };
-
- ///
- /// The function to update the list of entries.
- ///
- public Func, List> RefreshEntries = (entries) => entries;
-
- ///
- /// The function that is called when 0th entry in the list is chosen.
- /// Display this entry with the title function.
- ///
- public Func, bool> ZeroEntry = (entries) =>
- {
- ResetInput();
- return false;
- };
-
- ///
- /// Display the menu.
- ///
- ///
- public ListMenu Show()
- {
- string readInput = string.Empty;
- bool MenuExitIsPending = false;
- while (!MenuExitIsPending)
- {
- Console.Clear();
- int printedEntries = 0;
- Entries = RefreshEntries(Entries);
- DisplayTitle(Entries);
- if (Entries.Any())
- {
- int num = 0;
- foreach (T entry in Entries)
- {
- num++;
- if (
- string.IsNullOrEmpty(readInput)
- || Convert.ToString(num).StartsWith(readInput)
- )
- {
- DisplayEntry(Entries, Entries.IndexOf(entry), num);
- printedEntries++;
- }
-
- if (Entries.Count > Console.WindowHeight - 5)
- {
- if (printedEntries >= Console.WindowHeight - (5 + 1))
- {
- Console.WriteLine(
- "[{0}] +{1}",
- ".".PadLeft(Convert.ToString(Entries.Count).Length, '.'),
- Entries.Count
- );
- break;
- }
- }
- else
- {
- if (printedEntries == Console.WindowHeight - 5)
- {
- break;
- }
- }
- }
- }
-
- if (UserCanExit)
- {
- Console.WriteLine(
- "[{0}] {1}",
- Convert
- .ToString(ExitKey)
- .PadLeft(Convert.ToString(Entries.Count).Length, ' '),
- ExitEntry
- );
- }
-
- Console.WriteLine();
-
- bool InputIsValid = false;
- while (!InputIsValid)
- {
- Console.Write("{0}> {1}", Prompt, readInput);
- ConsoleKeyInfo input = Console.ReadKey();
- Wait(20);
- int choiceNum = -1;
- switch (input)
- {
- case var key when key.KeyChar.Equals(ExitKey):
- if (UserCanExit)
- {
- Console.WriteLine();
- InputIsValid = true;
- MenuExitIsPending = true;
- }
- else
- {
- Console.WriteLine();
- ResetInput();
- }
- break;
-
- case var key when key.Key.Equals(ConsoleKey.Backspace):
- if (!string.IsNullOrEmpty(readInput))
- {
- Console.Write("\b");
- readInput = readInput.Remove(readInput.Length - 1);
- }
- InputIsValid = true;
- break;
-
- case var key when key.Key.Equals(ConsoleKey.Enter):
- if (!string.IsNullOrEmpty(readInput))
- {
- if (HandleEntry(Entries, (Convert.ToInt32(readInput) - 1)))
- {
- MenuExitIsPending = true;
- }
- readInput = string.Empty;
- }
- InputIsValid = true;
- break;
-
- case var key when int.TryParse(key.KeyChar.ToString(), out choiceNum):
- Console.WriteLine();
- if (string.IsNullOrEmpty(readInput) && choiceNum.Equals(0))
- {
- InputIsValid = true;
- if (ZeroEntry(Entries))
- {
- MenuExitIsPending = true;
- }
- }
- else
- {
- if (
- Convert.ToInt32(readInput + Convert.ToString(choiceNum))
- <= Entries.Count
- )
- {
- InputIsValid = true;
- int matchingEntries = 0;
- readInput = new System.Text.StringBuilder()
- .Append(readInput)
- .Append(Convert.ToString(choiceNum))
- .ToString();
- for (int i = 0; i < Entries.Count; i++)
- {
- if (
- Convert.ToString(i + 1).StartsWith(readInput)
- || Convert.ToString(i + 1) == readInput
- )
- {
- matchingEntries++;
- }
- }
- if (
- (
- readInput.Length
- == Convert.ToString(Entries.Count).Length
- ) || (matchingEntries == 1)
- )
- {
- if (
- HandleEntry(
- Entries,
- (Convert.ToInt32(readInput) - 1)
- )
- )
- {
- MenuExitIsPending = true;
- }
- readInput = string.Empty;
- }
- }
- else
- {
- ResetInput();
- }
- }
- break;
-
- default:
- Console.WriteLine();
- ResetInput();
- break;
- }
- }
- }
- return this;
- }
- }
- }
-}
diff --git a/ExeToBat/ExeToBat.csproj b/ExeToBat/ExeToBat.csproj
index 3a0003b..fcf647c 100644
--- a/ExeToBat/ExeToBat.csproj
+++ b/ExeToBat/ExeToBat.csproj
@@ -1,29 +1,53 @@
-
-
+
+
+
+ Debug
+ AnyCPU
+ {04F45237-23C8-4EE6-B61C-6C47B9979A4B}
Exe
- true
- true
- net6.0
- enable
- enable
- 2.0.0.0
+ ExeToBat
+ ExeToBat
+ v4.6.1
+ 512
+ true
+ true
-
-
- $(WarningsAsErrors);NU1605;CS8600;CS8601;CS8602;CS8603;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633;CS8767;
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
-
-
- $(WarningsAsErrors);NU1605;CS8600;CS8601;CS8602;CS8603;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633;CS8767;
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/ExeToBat/Generator.cs b/ExeToBat/Generator.cs
deleted file mode 100644
index ee361f4..0000000
--- a/ExeToBat/Generator.cs
+++ /dev/null
@@ -1,311 +0,0 @@
-using System.Text.Json;
-
-namespace ExeToBat
-{
- public class Generator
- {
- public Generator() { }
-
- public Generator(GeneratorConfig config)
- {
- LoadConfig(config);
- }
-
- public const int ChunkSize = 8000;
-
- public List Sources = new();
-
- public class SourceFile
- {
- ///
- /// Represents a file that is later embedded in a bat.
- ///
- /// The path of the file.
- public SourceFile(string path)
- {
- Path = path;
- }
-
- public string Path { get; set; }
- public bool Execute { get; set; } = false;
- public bool Wait { get; set; } = false;
- public bool Delete { get; set; } = false;
- public string Resource { get; set; } = GetTempFileName();
- public string Directory { get; set; } = "%~dp0";
- public string Parameters { get; set; } = "";
-
- static public string GetTempFileName()
- {
- return string.Format($"res_{new Random().Next(1000, 10000)}.b64");
- }
- }
-
- public class GeneratorConfig
- {
- ///
- /// The configuration for a Generator.
- ///
- ///
- public GeneratorConfig(List sources)
- {
- Sources = sources;
- }
-
- public List Sources { get; private set; }
-
- public string ToJson()
- {
- return JsonSerializer.Serialize(this);
- }
-
- public static GeneratorConfig FromJson(string raw)
- {
- return JsonSerializer.Deserialize(raw)
- ?? new GeneratorConfig(new());
- }
- }
-
- ///
- /// Exports the variables of this Generator as a configuration.
- ///
- ///
- public GeneratorConfig SaveConfig()
- {
- return new GeneratorConfig(Sources);
- }
-
- ///
- /// Loads a configuration into this Generator.
- ///
- ///
- public void LoadConfig(GeneratorConfig config)
- {
- Sources = config.Sources;
- }
-
- ///
- /// Sends progress updates about ongoing generation task.
- ///
- public event EventHandler? Generation;
-
- protected virtual void OnGeneration(GeneratorEvent e)
- {
- EventHandler? handler = Generation;
- handler?.Invoke(this, e);
- }
-
- ///
- /// Generates a batch file with all specified source files.
- ///
- /// Target output file path.
- public void Generate(string outputFile)
- {
- if (Sources.Any())
- {
- using StreamWriter writer = new(outputFile);
- OnGeneration(new GenerationStartEvent(Sources));
- writer.WriteLine("@echo off");
- writer.WriteLine(":: Auto-generated batch file by ExeToBat ::");
- writer.WriteLine("");
-
- foreach (SourceFile source in Sources)
- {
- OnGeneration(new ReadingFileEvent(source));
- List fileChunks = Convert
- .ToBase64String(File.ReadAllBytes(source.Path))
- .Chunks(ChunkSize)
- .ToList();
- string tempFile = Path.Combine("%temp%", source.Resource);
- writer.WriteLine("(");
-
- int pos = 0;
- foreach (string part in fileChunks)
- {
- pos++;
- OnGeneration(new WritingFilePartEvent(source, pos, fileChunks.Count));
- writer.WriteLine(string.Format("echo {0}", part));
- }
-
- writer.WriteLine(string.Format(") >> \"{0}\"", tempFile));
- writer.WriteLine("");
-
- OnGeneration(new WritingFileDecoderEvent(source));
- writer.WriteLine(
- string.Format(
- "certutil -decode \"{0}\" \"{1}\" >nul 2>&1",
- tempFile,
- Path.Combine(source.Directory, Path.GetFileName(source.Path))
- )
- );
- writer.WriteLine(string.Format("del /f /q \"{0}\" >nul 2>&1", tempFile));
- writer.WriteLine("");
-
- if (source.Execute)
- {
- string wait;
- if (source.Wait)
- {
- wait = " /wait";
- }
- else
- {
- wait = " ";
- }
-
- OnGeneration(new WritingFileExecuteEvent(source));
- writer.WriteLine(
- string.Format(
- "start{0} \"\" \"cmd /c {1}\" {2}",
- wait,
- Path.Combine(source.Directory, Path.GetFileName(source.Path)),
- source.Parameters
- )
- );
- if (source.Wait)
- {
- OnGeneration(new WritingFileWaitEvent(source));
- if (source.Delete)
- {
- OnGeneration(new WritingFileDeleteEvent(source));
- writer.WriteLine(
- string.Format(
- "del /f /q \"{0}\" >nul 2>&1",
- Path.Combine(
- source.Directory,
- Path.GetFileName(source.Path)
- )
- )
- );
- writer.WriteLine("");
- }
- }
-
- writer.WriteLine("");
- }
-
- writer.Flush();
- OnGeneration(new WritingFileCompleteEvent(source));
- }
-
- OnGeneration(new GenerationCompleteEvent(outputFile));
- }
- else
- {
- OnGeneration(new GenerationEmptyEvent());
- }
- }
-
- public abstract class GeneratorEvent : EventArgs { }
-
- public abstract class GeneratorFileEvent : GeneratorEvent
- {
- public GeneratorFileEvent(SourceFile file)
- {
- File = file;
- }
-
- public SourceFile File { get; private set; }
- }
-
- public class GenerationStartEvent : GeneratorEvent
- {
- public GenerationStartEvent(List files)
- {
- Files = files;
- }
-
- public List Files { get; private set; }
- }
-
- public class ReadingFileEvent : GeneratorFileEvent
- {
- public ReadingFileEvent(SourceFile file) : base(file) { }
- }
-
- public class WritingFilePartEvent : GeneratorFileEvent
- {
- public WritingFilePartEvent(SourceFile file, int part, int max) : base(file)
- {
- Part = part;
- Max = max;
- }
-
- public int Part { get; private set; }
- public int Max { get; private set; }
- }
-
- public class WritingFileDecoderEvent : GeneratorFileEvent
- {
- public WritingFileDecoderEvent(SourceFile file) : base(file) { }
- }
-
- public class WritingFileExecuteEvent : GeneratorFileEvent
- {
- public WritingFileExecuteEvent(SourceFile file) : base(file) { }
- }
-
- public class WritingFileWaitEvent : GeneratorFileEvent
- {
- public WritingFileWaitEvent(SourceFile file) : base(file) { }
- }
-
- public class WritingFileDeleteEvent : GeneratorFileEvent
- {
- public WritingFileDeleteEvent(SourceFile file) : base(file) { }
- }
-
- public class WritingFileCompleteEvent : GeneratorFileEvent
- {
- public WritingFileCompleteEvent(SourceFile file) : base(file) { }
- }
-
- public class GenerationCompleteEvent : GeneratorEvent
- {
- public GenerationCompleteEvent(string path)
- {
- Path = path;
- }
-
- public string Path { get; private set; }
- }
-
- public class GenerationEmptyEvent : GeneratorEvent
- {
- public GenerationEmptyEvent() { }
- }
-
- public class GenerationFailedEvent : GeneratorEvent
- {
- public GenerationFailedEvent(Exception error)
- {
- Error = error;
- }
-
- public Exception Error { get; private set; }
- }
- }
-
- internal static class StringChunks
- {
- public static string[] Chunks(this string toSplit, int chunkSize)
- {
- int stringLength = toSplit.Length;
-
- int chunksRequired = (int)Math.Ceiling(stringLength / (decimal)chunkSize);
- var stringArray = new string[chunksRequired];
-
- int lengthRemaining = stringLength;
-
- for (int i = 0; i < chunksRequired; i++)
- {
- int lengthToUse = Math.Min(lengthRemaining, chunkSize);
- int startIndex = chunkSize * i;
- stringArray[i] = toSplit.Substring(startIndex, lengthToUse);
-
- lengthRemaining -= lengthToUse;
- }
-
- return stringArray;
- }
- }
-}
diff --git a/ExeToBat/Properties/AssemblyInfo.cs b/ExeToBat/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..6af03c8
--- /dev/null
+++ b/ExeToBat/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Allgemeine Informationen über eine Assembly werden über die folgenden
+// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
+// die einer Assembly zugeordnet sind.
+[assembly: AssemblyTitle("ExeToBat")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ExeToBat")]
+[assembly: AssemblyCopyright("Copyright © 2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
+// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
+// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
+[assembly: ComVisible(false)]
+
+// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
+[assembly: Guid("04f45237-23c8-4ee6-b61c-6c47b9979a4b")]
+
+// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
+//
+// Hauptversion
+// Nebenversion
+// Buildnummer
+// Revision
+//
+// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
+// übernehmen, indem Sie "*" eingeben:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]