From 174da0e85437a1786780304b8eb91e1a931484e0 Mon Sep 17 00:00:00 2001 From: dawn-lc Date: Tue, 6 Jul 2021 19:55:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchivePasswordTestTool.csproj | 13 +- ConsoleExpandModule.cs | 234 ++++++++++-------- Main.cs | 420 ++++++++++++++++++--------------- Program.cs | 84 +------ 4 files changed, 381 insertions(+), 370 deletions(-) diff --git a/ArchivePasswordTestTool.csproj b/ArchivePasswordTestTool.csproj index a32d721..4e00782 100644 --- a/ArchivePasswordTestTool.csproj +++ b/ArchivePasswordTestTool.csproj @@ -12,25 +12,30 @@ zh-Hans https://github.com/dawn-lc/ArchivePasswordTestTool false - 1.0.10.0 - 1.0.10.0 - 1.0.10 + 1.0.12.0 + 1.0.12.0 + 1.0.12 false true Always - favicon-20190111022740169.ico + icon.ico AnyCPU false + none + false AnyCPU 5 + DEBUG;TRACE + portable + true diff --git a/ConsoleExpandModule.cs b/ConsoleExpandModule.cs index 5c51f16..a03dbf4 100644 --- a/ConsoleExpandModule.cs +++ b/ConsoleExpandModule.cs @@ -1,6 +1,10 @@ using System; +using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Linq; using System.Threading; +using System.Threading.Tasks; namespace module.dawnlc.me { @@ -9,96 +13,151 @@ namespace module.dawnlc.me /// class ConsoleExpand : IDisposable { - private bool isDisposed = false; - private bool isDisposing = false; - private bool RenderCacheLock = false; - /// - /// Console 高 - /// - public static int High = Console.WindowHeight; - /// - /// Console 宽 - /// - public static int Width = Console.WindowWidth; - - public static Thread RenderThread; - - public static List RenderCache1 = new List(); - public static List RenderCache2 = new List(); - - public class Content + public class Render : IDisposable { - public int Row { get; set; } - public int Col { get; set; } - public string ContentString { get; set; } - public Content(int row, int col, string content) + public class Content { - Row = row; - Col = col; - ContentString = content; - } - } - - public ConsoleExpand() - { - Console.SetCursorPosition(0,0); - Console.Clear(); - RenderThread = new Thread(OutputCanvas) - { - IsBackground = true - }; - RenderThread.Start(); - } - - public void OutputCanvas() - { - while (!isDisposing) - { - RenderCacheLock = true; - List Rendering = new List(RenderCache1); - foreach (var item in Rendering) + public int Row { get; set; } + public int Col { get; set; } + public bool Cover { get; set; } + public string ContentString { get; set; } + public Content(int row, int col, string content,bool cover = true) { - if (item != null) - { - Console.SetCursorPosition(0, item.Row); - Console.Write(new string(' ', Width)); - Console.SetCursorPosition(item.Col, item.Row); - Console.Write(item.ContentString); - } - + Row = row; + Col = col; + Cover = cover; + ContentString = content; } - Rendering.Clear(); - RenderCache1.Clear(); + } + public class RenderCache : ConcurrentQueue + { + public ConcurrentQueue Contents { get; set; } + public bool CacheLock { get; set; } - RenderCache1.AddRange(RenderCache2); - RenderCacheLock = false; + public object SyncRoot => ((ICollection)Contents).SyncRoot; - RenderCache2.Clear(); + public bool IsSynchronized => ((ICollection)Contents).IsSynchronized; - Thread.Sleep(32); + public RenderCache() + { + CacheLock = false; + Contents = new ConcurrentQueue(); + } + public void Lock() + { + CacheLock = true; + } + public void Unlock() + { + CacheLock = false; + } } - } - - public void Print(int Col, int Row, string Content) - { - try + private bool isDisposed = false; + public int High = Console.WindowHeight; + public int Width = Console.WindowWidth; + public int Left = Console.CursorLeft; + public int Top = Console.CursorTop; + public Task RenderTask { get; set; } + public CancellationTokenSource RenderTaskTokenSource { get; set; } + public List Pool { get; set; } + public int RenderInterval { get; set; } + public void Push(Content content) { - if (RenderCacheLock) + try { - RenderCache2.Add(new Content(Row, Col, Content)); + Pool.Where(p => !p.CacheLock).First().Enqueue(content); } - else + catch (Exception ex) { - RenderCache1.Add(new Content(Row, Col, Content)); + throw new Exception("缺少可用的输出缓存区!"+ex.ToString()); } } - catch (Exception) + public Render(int FPS = 10,int PoolCount = 2) { - //这里如果报错,肯定是破解速度过快.(跑完了7zip test并返回了结果只花了不到10毫秒) - //不过不影响,漏显示一行不算什么大问题(笑 - //摸了 + RenderInterval = 1000 / FPS; + Pool = new List(); + for (int i = 0; i < PoolCount; i++) + { + Pool.Add(new RenderCache()); + } + RenderTaskTokenSource = new CancellationTokenSource(); + RenderTask = Task.Factory.StartNew(() => { + try + { + while (true) + { + foreach (var item in Pool.Where(p => p.Count != 0)) + { + item.Lock(); + for (int i = 0; i < item.Count; i++) + { + if (item.TryDequeue(out Content content)) + { + if (content.Cover) + { + Console.SetCursorPosition(0, content.Row); + Console.Write(new string(' ', Width)); + } + Console.SetCursorPosition(content.Col, content.Row); + Console.Write(content.ContentString); + } + } + item.Unlock(); + } + RenderTaskTokenSource.Token.ThrowIfCancellationRequested(); + Thread.Sleep(RenderInterval); + } + } + catch (OperationCanceledException) + { + //外部取消 + return; + } + catch (Exception ex) + { + throw ex; + } + }, RenderTaskTokenSource.Token); + } + public void Close() + { + Dispose(true); + } + ~Render() + { + Dispose(false); + } + void IDisposable.Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + protected virtual void Dispose(bool disposing) + { + if (!isDisposed) + { + if (disposing) + { + //释放 + RenderTaskTokenSource.Cancel(); + RenderTask.Wait(); + Console.SetCursorPosition(Left,Top); + } + } + isDisposed = true; } } + + private bool isDisposed = false; + private Render RenderTask { get; set; } + public ConsoleExpand() + { + RenderTask = new Render(25); + } + public void Print(int row, int col, string content) + { + RenderTask.Push(new Render.Content(col, row, content)); + } public void Close() { Dispose(true); @@ -118,33 +177,12 @@ protected virtual void Dispose(bool disposing) { if (disposing) { - RenderThread.Abort(); - isDisposing = true; - foreach (var item in RenderCache1) - { - if (item != null) - { - Console.SetCursorPosition(0, item.Row); - Console.Write(new string(' ', Width)); - Console.SetCursorPosition(item.Col, item.Row); - Console.Write(item.ContentString); - } - } - foreach (var item in RenderCache2) - { - if (item != null) - { - Console.SetCursorPosition(0, item.Row); - Console.Write(new string(' ', Width)); - Console.SetCursorPosition(item.Col, item.Row); - Console.Write(item.ContentString); - } - } - - isDisposing = false; + //释放 + RenderTask.Close(); } } - isDisposed = true; // 标识此对象已释放 + isDisposed = true; } + } } diff --git a/Main.cs b/Main.cs index c599247..c1867e4 100644 --- a/Main.cs +++ b/Main.cs @@ -11,10 +11,80 @@ using System.Threading.Tasks; using System.IO; using module.dawnlc.me; -using System.Security.Cryptography; +using System.Reflection; namespace ArchivePasswordTestTool { + + public class ProgramParameter + { + public readonly string AppName = Assembly.GetExecutingAssembly().FullName.Substring(0, Assembly.GetExecutingAssembly().FullName.IndexOf(",")); + public readonly string AppPath = Environment.CurrentDirectory + "\\"; + public readonly int[] Version = new int[] { 1, 0, 12 }; + public readonly string VersionType = "Release"; + public readonly string AppHomePage = "https://www.bilibili.com/read/cv6101558"; + public readonly string Developer = "dawn-lc"; + public bool DebugMode = false; + public FileInfo ArchiveDecryptionProgram { get; set; } + public FileInfo ArchiveFile { get; set; } + public FileInfo Dictionary { get; set; } + public string EncryptArchivePassword { get; set; } + public int DecryptArchiveThreadCount { get; set; } + + public ProgramParameter() + { + try + { + if (!Directory.Exists(AppPath + "Bin\\")) + { + Directory.CreateDirectory(AppPath + "Bin\\"); + } + if (!File.Exists(AppPath + "Bin\\7z.exe")) + { + IO.ExtractResFile(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Resources.7z.exe", AppPath + "Bin\\7z.exe"); + } + else + { + using (FileStream data = new FileStream(AppPath + "Bin\\7z.exe", FileMode.Open, FileAccess.Read)) + { + if (!IO.ComparisonFile(Assembly.GetExecutingAssembly().GetManifestResourceStream(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Resources.7z.exe"), data)) + { + while (true) + { + Console.WriteLine("注意!校验到7Zip与本程序自带的不一致,可能会导致程序无法正常工作。"); + Console.Write("是否使用本程序自带的7Zip版本将其覆盖?(按Y覆盖/按N不覆盖): "); + switch (Console.ReadKey().Key) + { + case ConsoleKey.Y: + Console.Clear(); + File.Delete(AppPath + "Bin\\7z.exe"); + IO.ExtractResFile(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".7z.exe", AppPath + "Bin\\7z.exe"); + break; + case ConsoleKey.N: + break; + default: + Console.Clear(); + continue; + } + break; + } + } + } + } + ArchiveDecryptionProgram = new FileInfo(AppPath + "Bin\\7z.exe"); + } + catch (Exception) + { + Console.WriteLine("自检时出现错误!请确认读写权限是否开放或磁盘空间是否不足。(按任意键退出程序)"); + Console.ReadKey(); + Environment.Exit(0); + } + EncryptArchivePassword = null; + DecryptArchiveThreadCount = 1; + } + } + + public class Parameter { public Parameter(int Thread, string PassWord) @@ -28,9 +98,28 @@ public Parameter(int Thread, string PassWord) } - public class Main + public class MainProgram { - static ProgramParameter programParameter { get; set; } + public static ProgramParameter Parameter = new ProgramParameter(); + + public class ParameterCompared : IEqualityComparer + { + public bool Equals(Parameter x, Parameter y) + { + if (x.PassWord == null && y.PassWord == null) + return true; + if (x.PassWord == y.PassWord) + return true; + return false; + } + + public int GetHashCode(Parameter obj) + { + return obj.PassWord.GetHashCode(); + } + } + + /// /// 判断键值是否存在 /// @@ -38,14 +127,8 @@ public class Main /// 存在返回true,不存在返回false public static bool IsExsits(RegistryKey key) { - if (key == null) - { - return false; - } - else - { - return true; - } + if (key == null) return false; + return true; } /// @@ -56,33 +139,18 @@ public static bool IsExsits(RegistryKey key) /// 如果Registry.LocalMachine中不包含Key或Key.Value不存在,返回null. 如果Registry.LocalMachine中包含Key且Key.Value存在,返回Key.Value. private static object ReadRegeditValue(string Key, string Value) { - if (IsExsits(Registry.LocalMachine.OpenSubKey(Key))) - { - return Registry.LocalMachine.OpenSubKey(Key).GetValue(Value); - } - else - { - return null; - } + if (IsExsits(Registry.LocalMachine.OpenSubKey(Key))) return Registry.LocalMachine.OpenSubKey(Key).GetValue(Value); + return null; } public static void WriteLine(string s = null) { - if (s == null) - { - Console.WriteLine(); - } - else - { - Console.WriteLine("[" + DateTime.Now.ToLocalTime().ToString() +"] "+ s); - } + if (s == null) Console.WriteLine(); + Console.WriteLine("[" + DateTime.Now.ToLocalTime().ToString() + "] " + s); } public static void Write(string s = null) { - if (s != null) - { - Console.Write("[" + DateTime.Now.ToLocalTime().ToString() + "] " + s); - } + if (s != null) Console.Write("[" + DateTime.Now.ToLocalTime().ToString() + "] " + s); } private static bool StartupParametersCheck(List StartupParameters, string ParameterFlag) @@ -103,7 +171,7 @@ private static bool StartupParametersCheck(List StartupParameters, strin catch (Exception ex) { WriteLine("启动参数存在错误!请检查参数:[" + ParameterFlag + "]"); - if (programParameter.DebugMode) { WriteLine(ex.ToString()); } + if (Parameter.DebugMode) { WriteLine(ex.ToString()); } throw ex; } } @@ -123,16 +191,11 @@ private static bool Initialize(string[] args) switch (Console.ReadKey().Key) { case ConsoleKey.Y: - programParameter.DebugMode = true; + Parameter.DebugMode = true; Debugger.Launch(); break; case ConsoleKey.N: break; - case ConsoleKey.F: - programParameter.DebugMode = true; - programParameter.FastDebugMode = true; - Debugger.Launch(); - break; default: WriteLine(); WriteLine("输入错误!"); @@ -143,17 +206,12 @@ private static bool Initialize(string[] args) } } - if (Debugger.IsAttached || programParameter.DebugMode) + if (Debugger.IsAttached || Parameter.DebugMode) { - //programParameter.DebugMode = true; Console.Title += " - DEBUG "; - if (programParameter.FastDebugMode) - { - Console.Title += "[Fast]"; - } } - using (FileStream configFile = new FileStream(programParameter.AppPath + "config.json", FileMode.OpenOrCreate, FileAccess.ReadWrite)) + using (FileStream configFile = new FileStream(Parameter.AppPath + "config.json", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { JObject config = new JObject(); if (configFile.Length == 0) @@ -163,14 +221,14 @@ private static bool Initialize(string[] args) configFile.Flush(); configFile.Seek(0, SeekOrigin.Begin); } - using (StreamReader configString = new StreamReader(configFile,Encoding.UTF8)) + using (StreamReader configString = new StreamReader(configFile, Encoding.UTF8)) { config = JsonConvert.DeserializeObject(configString.ReadToEnd()); WriteLine("上次检查更新: " + config["CheckUpgrade"].ToObject().ToLocalTime().ToString()); - if (config["CheckUpgrade"].ToObject() < (DateTime.Now - new TimeSpan(1, 0, 0))) + if (config["CheckUpgrade"].ToObject() < (DateTime.Now - new TimeSpan(1, 0, 0, 0))) { WriteLine("正在从github.com获取最新版本信息..."); - if (Upgrade.CheckUpgrade(new Uri("https://api.github.com/repos/" + programParameter.Developer + "/" + programParameter.AppName + "/releases/latest"), Http.Method.GET, new Dictionary() { ["user-agent"] = programParameter.AppName + " " + string.Join(".", programParameter.Version) + ";" },programParameter.Version,programParameter.VersionType)) + if (Upgrade.CheckUpgrade(new Uri("https://api.github.com/repos/" + Parameter.Developer + "/" + Parameter.AppName + "/releases/latest"), Http.Method.GET, new Dictionary() { ["user-agent"] = Parameter.AppName + " " + string.Join(".", Parameter.Version) + ";" }, Parameter.Version, Parameter.VersionType)) { WriteLine("当前本地程序已是最新版本。"); config["CheckUpgrade"] = DateTime.Now; @@ -188,16 +246,17 @@ private static bool Initialize(string[] args) } } + try { if (StartupParametersCheck(StartupParameters, "-F")) { - programParameter.ArchiveFile = new FileInfo(Path.GetFullPath(StartupParameters[StartupParameters.IndexOf("-F") + 1])); - while (!programParameter.ArchiveFile.Exists) + Parameter.ArchiveFile = new FileInfo(Path.GetFullPath(StartupParameters[StartupParameters.IndexOf("-F") + 1])); + while (!Parameter.ArchiveFile.Exists) { - WriteLine("没有找到您的压缩包[" + programParameter.ArchiveFile.FullName + "]!"); + WriteLine("没有找到您的压缩包[" + Parameter.ArchiveFile.FullName + "]!"); WriteLine("请将压缩包拖放到本窗口,或手动输入文件地址。(操作完成后, 按回车键继续)"); - programParameter.ArchiveFile = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"",null))); + Parameter.ArchiveFile = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"",null))); } } else @@ -206,13 +265,13 @@ private static bool Initialize(string[] args) { WriteLine("您似乎没有提供需要进行测试的压缩包地址!"); WriteLine("请将压缩包拖放到本窗口,或手动输入文件地址。(操作完成后, 按回车键继续)"); - programParameter.ArchiveFile = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); - } while (!programParameter.ArchiveFile.Exists); + Parameter.ArchiveFile = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); + } while (!Parameter.ArchiveFile.Exists); } } catch (Exception ex) { - WriteLine("尝试读取压缩包信息时出现错误!"); + WriteLine("尝试读取压缩包信息时出现错误,提供的路径有误或程序没有足够的权限读取文件!"); throw ex; } @@ -222,12 +281,12 @@ private static bool Initialize(string[] args) if (StartupParametersCheck(StartupParameters, "-D")) { - programParameter.Dictionary = new FileInfo(Path.GetFullPath(StartupParameters[StartupParameters.IndexOf("-D") + 1])); - while (!programParameter.Dictionary.Exists) + Parameter.Dictionary = new FileInfo(Path.GetFullPath(StartupParameters[StartupParameters.IndexOf("-D") + 1])); + while (!Parameter.Dictionary.Exists) { - WriteLine("没有找到您的密码字典[" + programParameter.Dictionary.FullName + "]!"); + WriteLine("没有找到您的密码字典[" + Parameter.Dictionary.FullName + "]!"); WriteLine("请将密码字典拖放到本窗口,或手动输入文件地址。(操作完成后, 按回车键继续)"); - programParameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); + Parameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); } } else @@ -237,9 +296,9 @@ private static bool Initialize(string[] args) switch (Console.ReadKey(true).Key) { case ConsoleKey.Y: - if (File.Exists(programParameter.AppPath + "PasswordDictionary.txt")) + if (File.Exists(Parameter.AppPath + "PasswordDictionary.txt")) { - programParameter.Dictionary = new FileInfo(Path.GetFullPath(programParameter.AppPath + "PasswordDictionary.txt")); + Parameter.Dictionary = new FileInfo(Path.GetFullPath(Parameter.AppPath + "PasswordDictionary.txt")); } else { @@ -247,16 +306,16 @@ private static bool Initialize(string[] args) do { WriteLine("请将密码字典拖放到本窗口,或手动输入文件地址。(操作完成后, 按回车键继续)"); - programParameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); - } while (!programParameter.Dictionary.Exists); + Parameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); + } while (!Parameter.Dictionary.Exists); } break; case ConsoleKey.N: do { WriteLine("请将密码字典拖放到本窗口,或手动输入文件地址。(操作完成后, 按回车键继续)"); - programParameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); - } while (!programParameter.Dictionary.Exists); + Parameter.Dictionary = new FileInfo(Path.GetFullPath(Console.ReadLine().Replace("\"", null))); + } while (!Parameter.Dictionary.Exists); break; default: break; @@ -266,7 +325,7 @@ private static bool Initialize(string[] args) } catch (Exception ex) { - WriteLine("尝试读取密码字典时出现错误!"); + WriteLine("尝试读取密码字典时出现错误!,提供的路径有误或程序没有足够的权限读取文件!"); throw ex; } @@ -275,18 +334,18 @@ private static bool Initialize(string[] args) { try { - programParameter.DecryptArchiveThreadCount = Convert.ToInt32(StartupParameters[StartupParameters.IndexOf("-T") + 1]); + Parameter.DecryptArchiveThreadCount = Convert.ToInt32(StartupParameters[StartupParameters.IndexOf("-T") + 1]); } catch (Exception ex) { Write("启动参数存在错误!请检查参数:[-T]"); - if (programParameter.DebugMode) { WriteLine(ex.ToString()); } + if (Parameter.DebugMode) { WriteLine(ex.ToString()); } throw ex; } - if (programParameter.DecryptArchiveThreadCount > (Environment.ProcessorCount - 1)) + if (Parameter.DecryptArchiveThreadCount > (Environment.ProcessorCount - 1)) { WriteLine("测试密码线程数过高! (已调整为最大线程[" + (Environment.ProcessorCount - 1).ToString() + "])"); - programParameter.DecryptArchiveThreadCount = Environment.ProcessorCount - 1; + Parameter.DecryptArchiveThreadCount = Environment.ProcessorCount - 1; } } else @@ -302,7 +361,7 @@ private static bool Initialize(string[] args) } while (string.IsNullOrEmpty(DecryptArchiveThreadCountTemp)); try { - programParameter.DecryptArchiveThreadCount = Convert.ToInt32(DecryptArchiveThreadCountTemp); + Parameter.DecryptArchiveThreadCount = Convert.ToInt32(DecryptArchiveThreadCountTemp); break; } catch (Exception) @@ -311,92 +370,23 @@ private static bool Initialize(string[] args) continue; } } while (true); - if (programParameter.DecryptArchiveThreadCount > (Environment.ProcessorCount - 1)) + if (Parameter.DecryptArchiveThreadCount > (Environment.ProcessorCount - 1)) { WriteLine("进行测试线程数过高! 已调整为最大线程(" + (Environment.ProcessorCount - 1).ToString() + ")"); - programParameter.DecryptArchiveThreadCount = Environment.ProcessorCount - 1; + Parameter.DecryptArchiveThreadCount = Environment.ProcessorCount - 1; } } return true; } - private static Dictionary> RunProgram(FileInfo Program, string[] Arguments) - { - using (Process p = new Process()) - { - List Error = new List(); - List Output = new List(); - void StoreError(object o, DataReceivedEventArgs e) - { - Error.Add(e.Data); - } - void StoreOutput(object o, DataReceivedEventArgs e) - { - Output.Add(e.Data); - } - try - { - p.StartInfo.FileName = Program.FullName; - p.StartInfo.Arguments = string.Join(" ", Arguments); - p.StartInfo.CreateNoWindow = true; - - p.StartInfo.UseShellExecute = false; - p.StartInfo.RedirectStandardInput = true; - p.StartInfo.RedirectStandardOutput = true; - p.StartInfo.RedirectStandardError = true; - - p.OutputDataReceived += StoreOutput; - p.ErrorDataReceived += StoreError; - - p.Start(); - - p.BeginErrorReadLine(); - p.BeginOutputReadLine(); - - using (StreamWriter sr = p.StandardInput) - { - p.StandardInput.AutoFlush = true; - sr.WriteLine(); - } - - p.WaitForExit(); - - if (programParameter.DebugMode && !programParameter.FastDebugMode) - { - Console.Write(string.Join(Environment.NewLine, Output.ToArray())); - Console.Write(string.Join(Environment.NewLine, Error.ToArray())); - } - return new Dictionary> { ["Output"] = Output, ["Error"] = Error }; - } - catch (Exception ex) - { - if (programParameter.DebugMode && !programParameter.FastDebugMode) - { - Console.Write(string.Join(Environment.NewLine, Output.ToArray())); - Console.Write(string.Join(Environment.NewLine, Error.ToArray())); - WriteLine(ex.ToString()); - } - WriteLine("执行 "+ Program.FullName + string.Join(" ", Arguments)+ " 失败!"); - throw ex; - - } - finally - { - p.OutputDataReceived -= StoreOutput; - p.ErrorDataReceived -= StoreError; - p.Close(); - } - } - } - public Main(string[] args, ProgramParameter Parameter) + public MainProgram(string[] args) { - programParameter = Parameter; RavenClient ravenClient = new RavenClient("https://9361b53d22da420c95bdb43d1b78eb1e@o687854.ingest.sentry.io/5773141"); try { if (Initialize(args)) { - MainProgram(); + Program(); } else { @@ -406,38 +396,19 @@ public Main(string[] args, ProgramParameter Parameter) catch (Exception ex) { SentryEvent sentry = new SentryEvent(ex); - string test = JsonConvert.SerializeObject(programParameter); + string test = JsonConvert.SerializeObject(Parameter); sentry.Extra = test.ToString(); ravenClient.Capture(sentry); WriteLine("错误信息已上报(按任意键退出程序)"); Console.ReadKey(); - Process.Start(programParameter.AppHomePage); + Process.Start(Parameter.AppHomePage); } return; } - - public class ParameterCompared : IEqualityComparer - { - public bool Equals(Parameter x, Parameter y) - { - if (x.PassWord == null && y.PassWord == null) - return true; - if (x.PassWord == y.PassWord) - return true; - return false; - } - - public int GetHashCode(Parameter obj) - { - return obj.PassWord.GetHashCode(); - } - } - - private void MainProgram() + private void Program() { - - if (programParameter.ArchiveFile.Extension.ToLower().Contains("rar")) + if (Parameter.ArchiveFile.Extension.ToLower().Contains("rar")) { WriteLine("RAR格式压缩包!由于RAR专利问题需要调用完整版7Zip!"); WriteLine("本程序将会读取注册表中的7Zip安装路径,如果不想程序读取,请直接关闭本程序。"); @@ -452,11 +423,11 @@ private void MainProgram() } else { - programParameter.ArchiveDecryptionProgram = new FileInfo(ReadRegeditValue("SOFTWARE\\7-Zip", "Path").ToString() + "7z.exe"); + Parameter.ArchiveDecryptionProgram = new FileInfo(ReadRegeditValue("SOFTWARE\\7-Zip", "Path").ToString() + "7z.exe"); } } - if (!RunProgram(programParameter.ArchiveDecryptionProgram, new string[] { "t", "\"" + programParameter.ArchiveFile.FullName + "\"", "-p" }).TryGetValue("Output", out List Output)) + if (!RunProgram(Parameter.ArchiveDecryptionProgram, new string[] { "t", "\"" + Parameter.ArchiveFile.FullName + "\"", "-p" }).TryGetValue("Output", out List Output)) { WriteLine("压缩包损坏 或 不是支持的压缩包!"); throw new Exception("ArchiveFile Error!"); @@ -473,12 +444,12 @@ private void MainProgram() List Dictionary = new List(); - + try { Random r = new Random(); WriteLine("正在读取字典..."); - using (FileStream LocalDictionary = new FileStream(programParameter.AppPath + "PasswordDictionary.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) + using (FileStream LocalDictionary = new FileStream(Parameter.AppPath + "PasswordDictionary.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { using (StreamReader sr = new StreamReader(LocalDictionary, new UTF8Encoding(false))) { @@ -487,16 +458,16 @@ private void MainProgram() string item = sr.ReadLine(); if (item != null) { - Dictionary.Add(new Parameter(r.Next(0, programParameter.DecryptArchiveThreadCount), item)); + Dictionary.Add(new Parameter(r.Next(0, Parameter.DecryptArchiveThreadCount), item)); } } int DictionaryCount = Dictionary.Count; WriteLine("从默认字典中读取到[" + DictionaryCount + "]个密码"); - if (programParameter.Dictionary.FullName != programParameter.AppPath + "PasswordDictionary.txt") + if (Parameter.Dictionary.FullName != Parameter.AppPath + "PasswordDictionary.txt") { - using (FileStream DictionaryFile = new FileStream(programParameter.Dictionary.FullName, FileMode.Open, FileAccess.Read)) + using (FileStream DictionaryFile = new FileStream(Parameter.Dictionary.FullName, FileMode.Open, FileAccess.Read)) { using (StreamReader Reader = new StreamReader(DictionaryFile, new UTF8Encoding(false))) { @@ -505,7 +476,7 @@ private void MainProgram() string item = Reader.ReadLine(); if (item != null) { - Dictionary.Add(new Parameter(r.Next(0, programParameter.DecryptArchiveThreadCount), item)); + Dictionary.Add(new Parameter(r.Next(0, Parameter.DecryptArchiveThreadCount), item)); } } } @@ -533,7 +504,7 @@ private void MainProgram() catch (Exception ex) { WriteLine("尝试读取密码字典时出现错误!"); - if (programParameter.DebugMode) { WriteLine(ex.ToString()); } + if (Parameter.DebugMode) { WriteLine(ex.ToString()); } throw ex; } @@ -542,18 +513,23 @@ private void MainProgram() using (ConsoleExpand ConsoleCanvas = new ConsoleExpand()) { - for (int i = 0; i < programParameter.DecryptArchiveThreadCount; i++) + for (int i = 0; i < Parameter.DecryptArchiveThreadCount; i++) { ConsoleCanvas.Print(0, i, "[" + i + "] 启动中..."); } - Parallel.ForEach(Dictionary, new ParallelOptions() { MaxDegreeOfParallelism = programParameter.DecryptArchiveThreadCount }, (i, loopState) => { + + Random random = new Random(); + + Console.Clear(); + Parallel.ForEach(Dictionary, new ParallelOptions() { MaxDegreeOfParallelism = Parameter.DecryptArchiveThreadCount }, (i, loopState) => + { ConsoleCanvas.Print(0, i.Thread, "[" + i.Thread + "] 密码: [" + i.PassWord + "] 测试中..."); - if (RunProgram(programParameter.ArchiveDecryptionProgram, new string[] { "t", "\"" + programParameter.ArchiveFile.FullName + "\"", "-p\"" + i.PassWord + "\"" }).TryGetValue("Output", out List OutputInfo)) + if (RunProgram(Parameter.ArchiveDecryptionProgram, new string[] { "t", "\"" + Parameter.ArchiveFile.FullName + "\"", "-p\"" + i.PassWord + "\"" }).TryGetValue("Output", out List OutputInfo)) { if (OutputInfo.Where(p => p != null && p.Contains("Everything is Ok")).Any()) { - programParameter.EncryptArchivePassword = i.PassWord; + Parameter.EncryptArchivePassword = i.PassWord; loopState.Stop(); ConsoleCanvas.Print(0, i.Thread, "[" + i.Thread + "] 密码: [" + i.PassWord + "] 正确"); } @@ -573,9 +549,9 @@ private void MainProgram() Console.Clear(); - if (programParameter.EncryptArchivePassword != null) + if (Parameter.EncryptArchivePassword != null) { - WriteLine("已找到解压密码: " + programParameter.EncryptArchivePassword); + WriteLine("已找到解压密码: " + Parameter.EncryptArchivePassword); WriteLine("耗时: " + sw.Elapsed.ToString(@"hh\:mm\:ss\.ffff")); } else @@ -589,13 +565,13 @@ private void MainProgram() switch (Console.ReadKey(true).Key) { case ConsoleKey.Enter: - using (StreamWriter file = new StreamWriter(programParameter.AppPath + Path.GetFileName(programParameter.ArchiveFile.Name) + "[测试报告].txt", false)) + using (StreamWriter file = new StreamWriter(Parameter.AppPath + Path.GetFileName(Parameter.ArchiveFile.Name) + "[测试报告].txt", false)) { - file.WriteLine("加密压缩包: " + programParameter.ArchiveFile); - file.WriteLine("字典: " + programParameter.Dictionary); - if (programParameter.EncryptArchivePassword != null) + file.WriteLine("加密压缩包: " + Parameter.ArchiveFile); + file.WriteLine("字典: " + Dictionary); + if (Parameter.EncryptArchivePassword != null) { - file.WriteLine("解压密码: " + programParameter.EncryptArchivePassword); + file.WriteLine("解压密码: " + Parameter.EncryptArchivePassword); } else { @@ -604,7 +580,7 @@ private void MainProgram() file.Write("耗时: " + sw.Elapsed.ToString(@"hh\:mm\:ss\.ffff")); file.Close(); } - Process.Start("Explorer.exe", "/select, \"" + programParameter.AppPath + Path.GetFileName(programParameter.ArchiveFile.Name) + "[测试报告].txt" + "\""); + Process.Start("Explorer.exe", "/select, \"" + Parameter.AppPath + Path.GetFileName(Parameter.ArchiveFile.Name) + "[测试报告].txt" + "\""); break; default: break; @@ -612,5 +588,73 @@ private void MainProgram() return; } + private static Dictionary> RunProgram(FileInfo Program, string[] Arguments) + { + using (Process p = new Process()) + { + List Error = new List(); + List Output = new List(); + void StoreError(object o, DataReceivedEventArgs e) + { + Error.Add(e.Data); + } + void StoreOutput(object o, DataReceivedEventArgs e) + { + Output.Add(e.Data); + } + try + { + p.StartInfo.FileName = Program.FullName; + p.StartInfo.Arguments = string.Join(" ", Arguments); + p.StartInfo.CreateNoWindow = true; + + p.StartInfo.UseShellExecute = false; + p.StartInfo.RedirectStandardInput = true; + p.StartInfo.RedirectStandardOutput = true; + p.StartInfo.RedirectStandardError = true; + + p.OutputDataReceived += StoreOutput; + p.ErrorDataReceived += StoreError; + + p.Start(); + + p.BeginErrorReadLine(); + p.BeginOutputReadLine(); + + using (StreamWriter sr = p.StandardInput) + { + p.StandardInput.AutoFlush = true; + sr.WriteLine(); + } + + p.WaitForExit(); + + if (Parameter.DebugMode) + { + Console.Write(string.Join(Environment.NewLine, Output.ToArray())); + Console.Write(string.Join(Environment.NewLine, Error.ToArray())); + } + return new Dictionary> { ["Output"] = Output, ["Error"] = Error }; + } + catch (Exception ex) + { + WriteLine("执行 " + Program.FullName + string.Join(" ", Arguments) + " 失败!"); + if (Parameter.DebugMode) + { + Console.Write(string.Join(Environment.NewLine, Output.ToArray())); + Console.Write(string.Join(Environment.NewLine, Error.ToArray())); + WriteLine(ex.ToString()); + } + throw ex; + + } + finally + { + p.OutputDataReceived -= StoreOutput; + p.ErrorDataReceived -= StoreError; + p.Close(); + } + } + } } } diff --git a/Program.cs b/Program.cs index 3e62916..f63b5c4 100644 --- a/Program.cs +++ b/Program.cs @@ -1,91 +1,17 @@ using System; using System.IO; using System.Reflection; - +using System.Threading.Tasks; using module.dawnlc.me; - namespace ArchivePasswordTestTool { - public class ProgramParameter - { - public readonly string AppName = Assembly.GetExecutingAssembly().FullName.Substring(0, Assembly.GetExecutingAssembly().FullName.IndexOf(",")); - public readonly string AppPath = Environment.CurrentDirectory + "\\"; - public readonly int[] Version = new int[] { 1, 0, 11 }; - public readonly string VersionType = "Release"; - public readonly string AppHomePage = "https://www.bilibili.com/read/cv6101558"; - public readonly string Developer = "dawn-lc"; - public bool DebugMode { get; set; } - public bool FastDebugMode { get; set; } - public FileInfo ArchiveDecryptionProgram { get; set; } - public FileInfo ArchiveFile { get; set; } - public FileInfo Dictionary { get; set; } - public string EncryptArchivePassword { get; set; } - public int DecryptArchiveThreadCount { get; set; } - - public ProgramParameter() - { - DebugMode = false; - FastDebugMode = false; - - try - { - if (!Directory.Exists(AppPath + "Bin\\")) - { - Directory.CreateDirectory(AppPath + "Bin\\"); - } - if (!File.Exists(AppPath + "Bin\\7z.exe")) - { - IO.ExtractResFile(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Resources.7z.exe", AppPath + "Bin\\7z.exe"); - } - else - { - using (FileStream data = new FileStream(AppPath + "Bin\\7z.exe", FileMode.Open, FileAccess.Read)) - { - if (!IO.ComparisonFile(Assembly.GetExecutingAssembly().GetManifestResourceStream(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".Resources.7z.exe"), data)) - { - while (true) - { - Console.WriteLine("注意!校验到7Zip与本程序自带的不一致,可能会导致程序无法正常工作。"); - Console.Write("是否使用本程序自带的7Zip版本将其覆盖?(按Y覆盖/按N不覆盖): "); - switch (Console.ReadKey().Key) - { - case ConsoleKey.Y: - Console.Clear(); - File.Delete(AppPath + "Bin\\7z.exe"); - IO.ExtractResFile(MethodBase.GetCurrentMethod().DeclaringType.Namespace + ".7z.exe", AppPath + "Bin\\7z.exe"); - break; - case ConsoleKey.N: - break; - default: - Console.Clear(); - continue; - } - break; - } - } - } - } - ArchiveDecryptionProgram = new FileInfo(AppPath + "Bin\\7z.exe"); - } - catch (Exception) - { - Console.WriteLine("自检时出现错误!请确认读写权限是否开放或磁盘空间是否不足。(按任意键退出程序)"); - Console.ReadKey(); - Environment.Exit(0); - } - EncryptArchivePassword = null; - DecryptArchiveThreadCount = 1; - } - } - class Program { - public static ProgramParameter programParameter = new ProgramParameter(); public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string[] assemblyName = args.Name.Split(','); - DirectoryInfo DirectoryInfo = new DirectoryInfo(programParameter.AppPath + "Bin\\"); + DirectoryInfo DirectoryInfo = new DirectoryInfo(Environment.CurrentDirectory + "\\Bin\\"); try { if (!DirectoryInfo.Exists) @@ -111,7 +37,7 @@ public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEvent } catch (Exception ex) { - Console.WriteLine("加载程序集出错!请前往:" + programParameter.AppHomePage + " 提交错误信息。"); + Console.WriteLine("加载程序集出错!请向开发者提交以下错误信息。"); Console.WriteLine(ex.ToString()); } return null; @@ -121,9 +47,7 @@ public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEvent static void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); - - Main main = new Main(args, programParameter); - + new MainProgram(args); } }