Commit 38e7286ed407d031e0902155319fb827016f1d51

Authored by Schwirg László
1 parent 027cf126

v 1.34.0

- CompareDirectories funkció beépítése
Vrh.Log4Pro.MaintenanceConsole/ConsoleFunction - CommandLineParser.cs
... ... @@ -288,12 +288,18 @@ namespace Vrh.Log4Pro.MaintenanceConsole.CommandLineParserNS
288 288 public static class Functions
289 289 {
290 290 public const string CMD_PACKAGES = "-PACKAGES";
291   - public static class CreateBackupPackage
  291 + public const string CMD_DIR1 = "-DIR1";
  292 + public const string CMD_DIR2 = "-DIR2";
  293 + public static class CreateBackupPackage
292 294 {
293 295 public const string KEY = "CRE";
294 296 }
295   - }
296   - }
  297 + public static class CompareDirectories
  298 + {
  299 + public const string KEY = "COM";
  300 + }
  301 + }
  302 + }
297 303 public static class SQLDataBaseManager
298 304 {
299 305 public const string KEY = "SQL";
... ...
Vrh.Log4Pro.MaintenanceConsole/Manager - BackupPackageManager.cs
... ... @@ -22,6 +22,7 @@ using Vrh.XmlProcessing;
22 22 using VRH.Common;
23 23 using System.Xml.Linq;
24 24 using System.Text.RegularExpressions;
  25 +using System.Security.Cryptography;
25 26  
26 27 namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS
27 28 {
... ... @@ -42,7 +43,8 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS
42 43  
43 44 var menufunctions = new Menu("Manage Backup Packages", "Select the management function!")
44 45 .AddMenuItem(new Menu.Item(CLP.Module.BackupPackageManager.Functions.CreateBackupPackage.KEY, "Create backup package", CreateBackupPackage,ep))
45   - .SetSelectionMode(Menu.SelectionMode.Single)
  46 + .AddMenuItem(new Menu.Item(CLP.Module.BackupPackageManager.Functions.CompareDirectories.KEY, "Compare directories", CompareDirectories, ep))
  47 + .SetSelectionMode(Menu.SelectionMode.Single)
46 48 .SetMenuHeaderDisplayer(BackupPackageListDisplayer);
47 49 menufunctions.ExecuteMenu(functionkey);
48 50 return o2;
... ... @@ -50,7 +52,173 @@ namespace Vrh.Log4Pro.MaintenanceConsole.BackupPackageManagerNS
50 52 #endregion Execute
51 53  
52 54 #region First level Executors with UI
53   - private static object CreateBackupPackage(object parameter, object o)
  55 + internal static object CompareDirectories(object parameter, object o)
  56 + {
  57 + var config = parameter==null?null:((parameter as Menu.ExecutorParameter).GetConfig<BackupPackageManagerXmlProcessor>());
  58 + var args = parameter == null ? null : ((parameter as Menu.ExecutorParameter).Args);
  59 +
  60 + var dir1= CommandLine.GetCommandLineArgument(args, CLP.Module.BackupPackageManager.Functions.CMD_DIR1);
  61 + var dir2 = CommandLine.GetCommandLineArgument(args, CLP.Module.BackupPackageManager.Functions.CMD_DIR2);
  62 +
  63 +
  64 + string rootWORKING = ColorConsole.ReadLine("Enter path to WORKING INSTALLATION directory:", defaultvalue: dir1 ?? "", required: true); //@"C:\Path\To\Folder1";
  65 + string rootUPGRADE = ColorConsole.ReadLine("Enter path to UPGRADE INSTALLATION directory:", defaultvalue: dir1 ?? "", required: true); //@"C:\Path\To\Folder2";
  66 + string searchpatterncsvlist = ColorConsole.ReadLine("Enter search pattern (csv list):", defaultvalue: "*.dll,*.exe", required: true); //@"C:\Path\To\Folder2";
  67 +
  68 + rootWORKING = rootWORKING + @"\"; rootWORKING.Replace(@"/", @"\").Replace(@"\\", @"\");
  69 + rootUPGRADE = rootUPGRADE + @"\"; rootUPGRADE.Replace(@"/", @"\").Replace(@"\\", @"\");
  70 +
  71 + ColorConsole.WriteLine("Comparing folders...");
  72 + ColorConsole.WriteLine($" WORKING INSTALLATION: {rootWORKING}");
  73 + ColorConsole.WriteLine($" UPGRADE INSTALLATION: {rootUPGRADE}");
  74 + ColorConsole.WriteLine($" Search patterns: {searchpatterncsvlist}");
  75 + ColorConsole.WriteLine();
  76 +
  77 +
  78 + var folder1Files = GetFilesWithRelativePaths(rootWORKING, searchpatterncsvlist);
  79 + var folder2Files = GetFilesWithRelativePaths(rootUPGRADE, searchpatterncsvlist);
  80 +
  81 + var allKeys = new HashSet<string>(folder1Files.Keys);
  82 + allKeys.UnionWith(folder2Files.Keys);
  83 +
  84 + var savedcursortop = Console.CursorTop;
  85 + Console.WriteLine();
  86 + var actualcursortop = Console.CursorTop;
  87 + var numberofprocessedfiles = 0;
  88 + var upgradefiles = new Dictionary<string, CompareDirectoriesActions>();
  89 + foreach (var relativePath in allKeys.OrderBy(p => p))
  90 + {
  91 + numberofprocessedfiles++;
  92 + if (numberofprocessedfiles < 25)
  93 + {
  94 + actualcursortop = Console.CursorTop;
  95 + ColorConsole.SetCursorPosition(0, savedcursortop); ColorConsole.Write(relativePath, suffix: new string(' ', 20));
  96 + ColorConsole.SetCursorPosition(0, actualcursortop);
  97 + }
  98 + bool inWORKFolder = folder1Files.TryGetValue(relativePath, out string file1);
  99 + bool inUPGRADEFolder = folder2Files.TryGetValue(relativePath, out string file2);
  100 +
  101 + if (inWORKFolder && inUPGRADEFolder)
  102 + {
  103 + if (!FilesAreEqual(file1, file2, out string difftext))
  104 + {
  105 + //ColorConsole.WriteLine($"DIFFERENT ({difftext}): {relativePath}", ConsoleColor.Yellow);
  106 + ColorConsole.WriteLine($"< {relativePath} ({difftext}):", ConsoleColor.Yellow);
  107 + upgradefiles.Add(relativePath, CompareDirectoriesActions.CopyFROMUPGRADE);
  108 + }
  109 + }
  110 + else if (inWORKFolder)
  111 + {
  112 + //ColorConsole.WriteLine($"ONLY IN Folder1: {relativePath}", ConsoleColor.Yellow);
  113 + ColorConsole.WriteLine($"-- {relativePath}", ConsoleColor.Yellow);
  114 + upgradefiles.Add(relativePath, CompareDirectoriesActions.DeleteINWORKING);
  115 + }
  116 + else if (inUPGRADEFolder)
  117 + {
  118 + //ColorConsole.WriteLine($"ONLY IN Folder2: {relativePath}", ConsoleColor.Yellow);
  119 + ColorConsole.WriteLine($"<< {relativePath}", ConsoleColor.Yellow);
  120 + upgradefiles.Add(relativePath, CompareDirectoriesActions.CopyFROMUPGRADE);
  121 + }
  122 + }
  123 + ColorConsole.WriteLine();
  124 + string movefiles = ColorConsole.ReadLine("Do You want to upgrade WORKING INSTALLATION with UPGRADE INSTALLATION:",validitylist: new List<string>{"yes","no","YES","NO", }, defaultvalue: "no", required: true); //@"C:\Path\To\Folder1";
  125 + if (movefiles.ToUpper() == "YES")
  126 + {
  127 + foreach (var uf in upgradefiles)
  128 + {
  129 + if (uf.Value == CompareDirectoriesActions.CopyFROMUPGRADE) { File.Copy(Path.Combine(rootUPGRADE, uf.Key), Path.Combine(rootWORKING, uf.Key)); }
  130 + else if (uf.Value == CompareDirectoriesActions.DeleteINWORKING) { File.Delete(Path.Combine(rootWORKING,uf.Key)); }
  131 + }
  132 + }
  133 + return o;
  134 + }
  135 + private enum CompareDirectoriesActions { CopyFROMUPGRADE, DeleteINWORKING,}
  136 + private static Dictionary<string, string> GetFilesWithRelativePaths(string root,string searchpattern="*")
  137 + {
  138 + var searchpatternlist = searchpattern.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
  139 + List<string> files = new List<string>() { };
  140 + foreach (var sp in searchpatternlist)
  141 + {
  142 + files.AddRange(Directory.GetFiles(root, sp, SearchOption.AllDirectories));
  143 + }
  144 + var dict = new Dictionary<string, string>();
  145 + foreach (var file in files)
  146 + {
  147 + string relativePath = GetRelativePath(root, file);
  148 + dict[relativePath] = file;
  149 + }
  150 + return dict;
  151 + }
  152 + /// <summary>
  153 + /// Creates a relative path from one file or folder to another.
  154 + /// </summary>
  155 + /// <param name="fromPath">Contains the directory that defines the start of the relative path.</param>
  156 + /// <param name="toPath">Contains the path that defines the endpoint of the relative path.</param>
  157 + /// <returns>The relative path from the start directory to the end path or <c>toPath</c> if the paths are not related.</returns>
  158 + /// <exception cref="ArgumentNullException"></exception>
  159 + /// <exception cref="UriFormatException"></exception>
  160 + /// <exception cref="InvalidOperationException"></exception>
  161 + public static string GetRelativePath(String fromPath, String toPath)
  162 + {
  163 + if (String.IsNullOrEmpty(fromPath)) throw new ArgumentNullException("fromPath");
  164 + if (String.IsNullOrEmpty(toPath)) throw new ArgumentNullException("toPath");
  165 +
  166 + Uri fromUri = new Uri(fromPath);
  167 + Uri toUri = new Uri(toPath);
  168 +
  169 + if (fromUri.Scheme != toUri.Scheme) { return toPath; } // path can't be made relative.
  170 +
  171 + Uri relativeUri = fromUri.MakeRelativeUri(toUri);
  172 + String relativePath = Uri.UnescapeDataString(relativeUri.ToString());
  173 +
  174 + if (toUri.Scheme.Equals("file", StringComparison.InvariantCultureIgnoreCase))
  175 + {
  176 + relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
  177 + }
  178 +
  179 + return relativePath;
  180 + }
  181 + private static bool FilesAreEqual(string WORKINGfilePath, string UPGRADEfilePath,out string differencetext)
  182 + {
  183 + differencetext = null;
  184 + var fiW = new FileInfo(WORKINGfilePath);
  185 + var fiU = new FileInfo(UPGRADEfilePath);
  186 +
  187 + var fvW = FileVersionInfo.GetVersionInfo(WORKINGfilePath);
  188 + var fvU = FileVersionInfo.GetVersionInfo(UPGRADEfilePath);
  189 + var fvW1=GetVersionNumber(fvW, out string fvW2);
  190 + var fvU1 = GetVersionNumber(fvU, out string fvU2);
  191 + var fveresiondifftext = "";// $" {fvW1}<>{fvU1};{fvW2}<>{fvU2}";
  192 + var pvW1 = GetVersionNumber(fvW, out string pvW2,true);
  193 + var pvU1 = GetVersionNumber(fvU, out string pvU2,true);
  194 + var pveresiondifftext = "";// $" {pvW1}<>{pvU1};{pvW2}<>{pvU2}";
  195 + if (fvW.FileVersion != fvU.FileVersion) { string oldertext = fvW1 > fvU1 ? "DOWNGRADE":"UPGRADE"; differencetext = $"{oldertext} FileVersion: {fveresiondifftext} {fvW.FileVersion} <--> {fvU.FileVersion}"; return false; }
  196 + if (fvW.ProductVersion != fvU.ProductVersion) { string oldertext = pvW1 > pvU1 ? "DOWNGRADE" : "UPGRADE"; differencetext = $"{oldertext} ProductVersion: {pveresiondifftext} {fvW.ProductVersion} <--> {fvU.ProductVersion}"; return false; }
  197 + //if (fi1.CreationTime != fi2.CreationTime) return false;
  198 + //if (fi1.LastWriteTimeUtc != fi2.LastWriteTimeUtc) { differencetext = "LastWriteTimeUTC"; return false; }
  199 + if (fiW.Length != fiU.Length) { string oldertext = fiW.Length > fiU.Length?"DOWNSIZE":"UPSIZE"; differencetext = $"Length: {oldertext} {fiW.Length} <--> {fiU.Length}"; return false; }
  200 + using (var sha256 = SHA256.Create())
  201 + using (var stream1 = File.OpenRead(WORKINGfilePath))
  202 + using (var stream2 = File.OpenRead(UPGRADEfilePath))
  203 + {
  204 + var hash1 = sha256.ComputeHash(stream1);
  205 + var hash2 = sha256.ComputeHash(stream2);
  206 +
  207 + if (!hash1.SequenceEqual(hash2)) { differencetext = "Hash/Content"; return false; }
  208 + }
  209 + return true;
  210 + }
  211 + private static long GetVersionNumber(FileVersionInfo vi,out string vt,bool useproductversion=false)
  212 + {
  213 + vt = useproductversion
  214 + ? $"{vi.ProductMajorPart}.{vi.ProductMinorPart}.{vi.ProductBuildPart}.{vi.ProductPrivatePart}"
  215 + : $"{vi.FileMajorPart}.{vi.FileMinorPart}.{vi.FileBuildPart}.{vi.FilePrivatePart}";
  216 + long numberbase = 10000;
  217 + return useproductversion
  218 + ? vi.ProductMajorPart * numberbase * numberbase * numberbase + vi.ProductMinorPart * numberbase * numberbase + vi.ProductBuildPart * numberbase + vi.ProductPrivatePart
  219 + : vi.FileMajorPart * numberbase * numberbase * numberbase + vi.FileMinorPart * numberbase * numberbase + vi.FileBuildPart * numberbase + vi.FilePrivatePart;
  220 + }
  221 + private static object CreateBackupPackage(object parameter, object o)
54 222 {
55 223 var config = (parameter as Menu.ExecutorParameter).GetConfig< BackupPackageManagerXmlProcessor>();
56 224 var args = (parameter as Menu.ExecutorParameter).Args;
... ...
Vrh.Log4Pro.MaintenanceConsole/Properties/AssemblyInfo.cs
... ... @@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
32 32 // You can specify all the values or you can default the Build and Revision Numbers
33 33 // by using the '*' as shown below:
34 34 // [assembly: AssemblyVersion("1.0.*")]
35   -[assembly: AssemblyVersion("1.33.0.0")]
36   -[assembly: AssemblyFileVersion("1.33.0.0")]
  35 +[assembly: AssemblyVersion("1.34.0.0")]
  36 +[assembly: AssemblyFileVersion("1.34.0.0")]
... ...