OSDN Git Service

Refactored the ProcessRunner and PasswordGen classes.
[slunkcrypt/SlunkCrypt.git] / gui / Process / PasswordGen.cs
index 9592b0f..cb13037 100644 (file)
@@ -4,19 +4,19 @@
 /******************************************************************************/
 
 using System;
-using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
-using System.Text;
 using System.Threading.Tasks;
 
+using com.muldersoft.slunkcrypt.gui.utils;
+
 namespace com.muldersoft.slunkcrypt.gui.process
 {
     public static class PasswordGen
     {
-        private static readonly TimeSpan TIMEOUT_MSEC = TimeSpan.FromSeconds(90);
+        private static readonly TimeSpan TIMEOUT = TimeSpan.FromSeconds(180);
 
-        private const string COMMAND_PASSWRD = "-p {0:D}";
+        private const string COMMAND_PASSWRD = "-p";
 
         // =============================================================================
         // Exception classes
@@ -24,7 +24,7 @@ namespace com.muldersoft.slunkcrypt.gui.process
 
         public class GenerationFailedException : IOException
         {
-            public GenerationFailedException(string message, Exception innerException) : base(message, innerException)
+            public GenerationFailedException(string message) : base(message)
             {
             }
         }
@@ -35,21 +35,25 @@ namespace com.muldersoft.slunkcrypt.gui.process
 
         public static async Task<string> GeneratePassword(int length)
         {
+            if (length <= 0)
+            {
+                throw new ArgumentOutOfRangeException("Password length must be a positive value!");
+            }
             using (FileStream executableFile = ExecutableHelper.GetExecutableFile())
             {
-                try
+                string[] arguments = new string[] { COMMAND_PASSWRD, string.Format("{0:D}", length) };
+                Tuple<int, string[]> result = await ProcessRunner.ExecAsnyc(executableFile.Name, arguments, null, ProcessPriorityClass.BelowNormal, TIMEOUT);
+                if (result.Item1 == 0)
                 {
-                    string password = await StartProcess(executableFile, length);
-                    if (IsWeakPassword(password))
+                    foreach (string password in result.Item2)
                     {
-                        throw new InvalidDataException("The generated password string is invalid!");
+                        if ((password.Length >= length) && (!IsWeakPassword(password)))
+                        {
+                            return password;
+                        }
                     }
-                    return password;
-                }
-                catch (Exception e)
-                {
-                    throw new GenerationFailedException("Failed to generate password string!", e);
                 }
+                throw new GenerationFailedException("Failed to generate password string!");
             }
         }
 
@@ -72,68 +76,5 @@ namespace com.muldersoft.slunkcrypt.gui.process
             }
             return (flags != 0xF);
         }
-
-        // =============================================================================
-        // Internal methods
-        // =============================================================================
-
-        private static async Task<string> StartProcess(FileStream executableFile, int length)
-        {
-            using (Process process = new Process())
-            {
-                process.StartInfo.UseShellExecute = false;
-                process.StartInfo.CreateNoWindow = true;
-                process.StartInfo.RedirectStandardOutput = true;
-                process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
-                process.StartInfo.FileName = executableFile.Name;
-                process.StartInfo.Arguments = string.Format(COMMAND_PASSWRD, length);
-                process.Start();
-
-                Stack<string> outputLines = await WaitForExit(process, TIMEOUT_MSEC);
-
-                if (process.ExitCode == 0)
-                {
-                    while (outputLines.Count > 0)
-                    {
-                        string line = outputLines.Pop();
-                        if (line.Length >= length)
-                        {
-                            return line;
-                        }
-                    }
-                }
-                return string.Empty;
-            }
-        }
-
-        private static async Task<Stack<string>> WaitForExit(Process process, TimeSpan timeout)
-        {
-            Task<Stack<string>> readTask;
-            await Task.WhenAny(readTask = Task.Run(() => ReadOutput(process)), Task.Delay(timeout));
-            if (!process.WaitForExit(125))
-            {
-                process.Kill();
-                process.WaitForExit();
-            }
-            return await readTask;
-        }
-
-        private static Stack<string> ReadOutput(Process process)
-        {
-            Stack<string> result = new Stack<string>();
-            using (StreamReader reader = process.StandardOutput)
-            {
-                string line;
-                while ((line = reader.ReadLine()) != null)
-                {
-                    line = line.Trim();
-                    if (line.Length != 0)
-                    {
-                        result.Push(line.Trim());
-                    }
-                }
-            }
-            return result;
-        }
     }
 }