Refactored process event handler class + added new "random password" icon.
This commit is contained in:
parent
65f08d43a5
commit
9b0d109336
BIN
gui/Resources/Die.png
Normal file
BIN
gui/Resources/Die.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 681 B |
@ -192,6 +192,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Resource Include="Resources\Refresh.png" />
|
<Resource Include="Resources\Refresh.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Resources\Die.png" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PostBuildEvent>copy /Y "$(SolutionDir)\etc\deps\cpu-capabilities\*.dll" "$(TargetDir)"</PostBuildEvent>
|
<PostBuildEvent>copy /Y "$(SolutionDir)\etc\deps\cpu-capabilities\*.dll" "$(TargetDir)"</PostBuildEvent>
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<BitmapImage x:Key="ImageSource_Eye1" UriSource="Resources/Eye_1.png"/>
|
<BitmapImage x:Key="ImageSource_Eye1" UriSource="Resources/Eye_1.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_Eye2" UriSource="Resources/Eye_2.png"/>
|
<BitmapImage x:Key="ImageSource_Eye2" UriSource="Resources/Eye_2.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_Info" UriSource="Resources/Info.png"/>
|
<BitmapImage x:Key="ImageSource_Info" UriSource="Resources/Info.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_Refresh" UriSource="Resources/Refresh.png"/>
|
<BitmapImage x:Key="ImageSource_Die" UriSource="Resources/Die.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_Start" UriSource="Resources/Start.png"/>
|
<BitmapImage x:Key="ImageSource_Start" UriSource="Resources/Start.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_TabHd1" UriSource="Resources/Tab_Encrypt.png"/>
|
<BitmapImage x:Key="ImageSource_TabHd1" UriSource="Resources/Tab_Encrypt.png"/>
|
||||||
<BitmapImage x:Key="ImageSource_TabHd2" UriSource="Resources/Tab_Decrypt.png"/>
|
<BitmapImage x:Key="ImageSource_TabHd2" UriSource="Resources/Tab_Decrypt.png"/>
|
||||||
@ -94,7 +94,7 @@
|
|||||||
<TextBlock FontWeight="SemiBold" Text="Passphrase:" Margin="0,10,0,0"/>
|
<TextBlock FontWeight="SemiBold" Text="Passphrase:" Margin="0,10,0,0"/>
|
||||||
<DockPanel Margin="0,5,0,0">
|
<DockPanel Margin="0,5,0,0">
|
||||||
<ctrls:ImageToggleButton DockPanel.Dock="Right" Margin="3,0,0,0" x:Name="Button_Encrypt_Toggle" ImageSourceDefault="{StaticResource ImageSource_Eye1}" ImageSourceChecked="{StaticResource ImageSource_Eye2}" ToolTipDefault="Show password" ToolTipChecked="Hide password"/>
|
<ctrls:ImageToggleButton DockPanel.Dock="Right" Margin="3,0,0,0" x:Name="Button_Encrypt_Toggle" ImageSourceDefault="{StaticResource ImageSource_Eye1}" ImageSourceChecked="{StaticResource ImageSource_Eye2}" ToolTipDefault="Show password" ToolTipChecked="Hide password"/>
|
||||||
<ctrls:ImageButton DockPanel.Dock="Right" Margin="3,0,0,0" Clicked="Button_GeneratePasswd_Click" ImageSource="{StaticResource ImageSource_Refresh}" ButtonToolTip="Generate random password"/>
|
<ctrls:ImageButton DockPanel.Dock="Right" Margin="3,0,0,0" Clicked="Button_GeneratePasswd_Click" ImageSource="{StaticResource ImageSource_Die}" ButtonToolTip="Generate random password"/>
|
||||||
<ctrls:PasswordToggleBox DockPanel.Dock="Left" EditPadding="3,5,3,5" x:Name="Edit_Encrypt_Password" EditFontFamily="{StaticResource Monospace}" IsRevealed="{Binding IsChecked, ElementName=Button_Encrypt_Toggle}" PasswordChar="*" MaxLength="{x:Static local:SlunkCryptGUI.MAX_PASSWD_LENGTH}" Entered="Edit_Password_Entered"/>
|
<ctrls:PasswordToggleBox DockPanel.Dock="Left" EditPadding="3,5,3,5" x:Name="Edit_Encrypt_Password" EditFontFamily="{StaticResource Monospace}" IsRevealed="{Binding IsChecked, ElementName=Button_Encrypt_Toggle}" PasswordChar="*" MaxLength="{x:Static local:SlunkCryptGUI.MAX_PASSWD_LENGTH}" Entered="Edit_Password_Entered"/>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -158,11 +158,11 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
{
|
{
|
||||||
using (BusyManager busy = new BusyManager(this))
|
using (BusyManager busy = new BusyManager(this))
|
||||||
{
|
{
|
||||||
Edit_Encrypt_Password.Password = string.Empty;
|
Button_Encrypt_Toggle.IsChecked = true;
|
||||||
|
Edit_Encrypt_Password.Password = "...";
|
||||||
string password;
|
string password;
|
||||||
if (!string.IsNullOrEmpty(password = await GeneratePassword()))
|
if (!string.IsNullOrEmpty(password = await GeneratePassword()))
|
||||||
{
|
{
|
||||||
Button_Encrypt_Toggle.IsChecked = true;
|
|
||||||
Edit_Encrypt_Password.Password = password;
|
Edit_Encrypt_Password.Password = password;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -851,6 +851,8 @@ namespace com.muldersoft.slunkcrypt.gui
|
|||||||
.AppendLine(VersionInfo.VersionStr)
|
.AppendLine(VersionInfo.VersionStr)
|
||||||
.AppendLine("This work has been released under the \u201CCC0 1.0\u201D license!")
|
.AppendLine("This work has been released under the \u201CCC0 1.0\u201D license!")
|
||||||
.AppendLine()
|
.AppendLine()
|
||||||
|
.AppendLine("Official web-site: http://slunkcrypt.osdn.io/")
|
||||||
|
.AppendLine()
|
||||||
.AppendLine(Environment.OSVersion.VersionString)
|
.AppendLine(Environment.OSVersion.VersionString)
|
||||||
.AppendLine(string.Format("Operating System Bitness: {0:D}, Process Bitness: {1:D}", Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32))
|
.AppendLine(string.Format("Operating System Bitness: {0:D}, Process Bitness: {1:D}", Environment.Is64BitOperatingSystem ? 64 : 32, Environment.Is64BitProcess ? 64 : 32))
|
||||||
.AppendLine(".NET Runtime Version: " + Environment.Version)
|
.AppendLine(".NET Runtime Version: " + Environment.Version)
|
||||||
|
@ -26,9 +26,9 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
public const bool STDOUT = false, STDERR = true;
|
public const bool STDOUT = false, STDERR = true;
|
||||||
|
|
||||||
private readonly Process m_process = new Process();
|
private readonly Process m_process = new Process();
|
||||||
private readonly TaskCompletionSource<int> m_hasExited = new TaskCompletionSource<int>();
|
|
||||||
private readonly Dispatcher m_dispatcher;
|
private readonly Dispatcher m_dispatcher;
|
||||||
private readonly ProcessPriorityClass? m_priorityClass;
|
private readonly ProcessPriorityClass? m_priorityClass;
|
||||||
|
private readonly Task<int> m_hasExited;
|
||||||
|
|
||||||
private volatile bool m_running = false, m_finished = false, m_aborted = false, m_disposed = false;
|
private volatile bool m_running = false, m_finished = false, m_aborted = false, m_disposed = false;
|
||||||
|
|
||||||
@ -50,6 +50,40 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Event handler class
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
private class ProcessExitHandler
|
||||||
|
{
|
||||||
|
private readonly TaskCompletionSource<int> completionSource = new TaskCompletionSource<int>();
|
||||||
|
|
||||||
|
public ProcessExitHandler(Process process)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(process, null))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Process must not be null!");
|
||||||
|
}
|
||||||
|
process.Exited += OnProcessExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> Task
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return completionSource.Task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnProcessExit(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is Process)
|
||||||
|
{
|
||||||
|
completionSource.TrySetResult(((Process)sender).ExitCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Constructor
|
// Constructor
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -64,7 +98,7 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
{
|
{
|
||||||
throw new ArgumentException("The given ProcessPriorityClass is undefined!");
|
throw new ArgumentException("The given ProcessPriorityClass is undefined!");
|
||||||
}
|
}
|
||||||
InitializeProcess(m_process, m_hasExited, true);
|
m_hasExited = InitializeProcess(m_process, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ProcessRunner()
|
~ProcessRunner()
|
||||||
@ -101,11 +135,11 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
|
|
||||||
public static async Task<Tuple<int, string[]>> ExecAsnyc(string executableFile, string[] arguments = null, IReadOnlyDictionary<string, string> environmentVariables = null, ProcessPriorityClass? priorityClass = null, TimeSpan? timeout = null)
|
public static async Task<Tuple<int, string[]>> ExecAsnyc(string executableFile, string[] arguments = null, IReadOnlyDictionary<string, string> environmentVariables = null, ProcessPriorityClass? priorityClass = null, TimeSpan? timeout = null)
|
||||||
{
|
{
|
||||||
TaskCompletionSource<int> completionSource = new TaskCompletionSource<int>();
|
|
||||||
using (Process process = new Process())
|
using (Process process = new Process())
|
||||||
{
|
{
|
||||||
InitializeProcess(process, completionSource);
|
Task<int> hasExitedTask = InitializeProcess(process);
|
||||||
return await DoExecAsnyc(process, completionSource.Task, executableFile, arguments, environmentVariables, priorityClass, timeout);
|
return await DoExecAsnyc(process, hasExitedTask, executableFile, arguments, environmentVariables, priorityClass, timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +180,7 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
// Internal methods
|
// Internal methods
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
private static void InitializeProcess(Process process, TaskCompletionSource<int> completionSource = null, bool redirStdErr = false)
|
private static Task<int> InitializeProcess(Process process, bool redirStdErr = false)
|
||||||
{
|
{
|
||||||
process.StartInfo.UseShellExecute = false;
|
process.StartInfo.UseShellExecute = false;
|
||||||
process.StartInfo.CreateNoWindow = true;
|
process.StartInfo.CreateNoWindow = true;
|
||||||
@ -157,11 +191,8 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
process.StartInfo.RedirectStandardError = true;
|
process.StartInfo.RedirectStandardError = true;
|
||||||
process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
|
process.StartInfo.StandardErrorEncoding = Encoding.UTF8;
|
||||||
}
|
}
|
||||||
if (!ReferenceEquals(completionSource, null))
|
|
||||||
{
|
|
||||||
process.EnableRaisingEvents = true;
|
process.EnableRaisingEvents = true;
|
||||||
process.Exited += (sndr, e) => completionSource.TrySetResult(process.ExitCode);
|
return new ProcessExitHandler(process).Task;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<int> DoExecAsnyc(string executablePath, string[] arguments, IReadOnlyDictionary<string, string> environmentVariables)
|
private async Task<int> DoExecAsnyc(string executablePath, string[] arguments, IReadOnlyDictionary<string, string> environmentVariables)
|
||||||
@ -205,15 +236,15 @@ namespace com.muldersoft.slunkcrypt.gui.utils
|
|||||||
{
|
{
|
||||||
Task readStdOutTask = Task.Run(() => ReadProcessOutput(m_process.StandardOutput, (line) => HandleOutput(line, STDOUT)));
|
Task readStdOutTask = Task.Run(() => ReadProcessOutput(m_process.StandardOutput, (line) => HandleOutput(line, STDOUT)));
|
||||||
Task readStdErrTask = Task.Run(() => ReadProcessOutput(m_process.StandardError, (line) => HandleOutput(line, STDERR)));
|
Task readStdErrTask = Task.Run(() => ReadProcessOutput(m_process.StandardError, (line) => HandleOutput(line, STDERR)));
|
||||||
Task<int> hasExited = m_hasExited.Task;
|
await Task.WhenAll(readStdOutTask, readStdErrTask, m_hasExited);
|
||||||
await Task.WhenAll(readStdOutTask, readStdErrTask, hasExited);
|
|
||||||
if (m_aborted || m_disposed)
|
if (m_aborted || m_disposed)
|
||||||
{
|
{
|
||||||
NotifyOutputAvailable("\u2192 Process has been aborted !!!", true);
|
NotifyOutputAvailable("\u2192 Process has been aborted !!!", true);
|
||||||
throw new ProcessInterruptedException("Process has been aborted!");
|
throw new ProcessInterruptedException("Process has been aborted!");
|
||||||
}
|
}
|
||||||
NotifyOutputAvailable(string.Format("\u2192 Process terminated normally [Exit status: {0:D}]", hasExited.Result), false);
|
int processExitCode = m_hasExited.Result;
|
||||||
return hasExited.Result;
|
NotifyOutputAvailable(string.Format("\u2192 Process terminated normally [Exit status: {0:D}]", processExitCode), false);
|
||||||
|
return processExitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string[]> WaitForExit(Process process, Task<int> hasExited, TimeSpan timeout)
|
private static async Task<string[]> WaitForExit(Process process, Task<int> hasExited, TimeSpan timeout)
|
||||||
|
Loading…
Reference in New Issue
Block a user