9184eeee85
Changed to latest RyzStudio8 Changed build script
605 lines
18 KiB
C#
605 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using RyzStudio.IO;
|
|
using RyzStudio.Runtime.InteropServices;
|
|
using RyzStudio.Windows.Forms;
|
|
using RyzStudio.Windows.ThemedForms;
|
|
|
|
namespace RandomFileRunner
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
private readonly Random _randy;
|
|
private readonly FileSearcher _fileSearcher;
|
|
private CancellationTokenSource _cancellationToken = new CancellationTokenSource();
|
|
|
|
private bool _isBusy = false;
|
|
|
|
private List<string> _searchPaths = new List<string>();
|
|
private List<string> _foundFiles = new List<string>();
|
|
private Process _currentProcess = null;
|
|
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
textBox2.TextBox.ReadOnly = true;
|
|
|
|
_randy = new Random();
|
|
_fileSearcher = new FileSearcher();
|
|
_fileSearcher.OnDirectoryFound += fileSearcher_OnDirectoryFound;
|
|
_fileSearcher.OnFileFound += fileSearcher_OnFileFound;
|
|
_fileSearcher.OnSearchCompleted += fileSearcher_OnSearchCompleted;
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
|
|
this.ClearSession();
|
|
}
|
|
|
|
protected async override void OnShown(EventArgs e)
|
|
{
|
|
base.OnShown(e);
|
|
|
|
var args = RyzStudio.Windows.Forms.WinApplication.GetCommandLine();
|
|
|
|
string jsonfigFilename = args.Where(x => (x.Key.Equals("o") || x.Key.Equals("open"))).Select(x => x.Value).FirstOrDefault();
|
|
if (string.IsNullOrWhiteSpace(jsonfigFilename))
|
|
{
|
|
jsonfigFilename = Path.ChangeExtension(Application.ExecutablePath, "jsonfig");
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(jsonfigFilename) && System.IO.File.Exists(jsonfigFilename))
|
|
{
|
|
await LoadSessionFile(jsonfigFilename);
|
|
}
|
|
|
|
textBox2.Focus();
|
|
}
|
|
|
|
protected override void OnClosing(CancelEventArgs e)
|
|
{
|
|
base.OnClosing(e);
|
|
|
|
if (this.IsBusy)
|
|
{
|
|
e.Cancel = true;
|
|
return;
|
|
}
|
|
|
|
if (this.CurrentSession.ClosePrevOnNext)
|
|
{
|
|
CloseCurrentProcess(_currentProcess);
|
|
}
|
|
|
|
if (this.CurrentSession.NextHotKey != null)
|
|
{
|
|
if (this.CurrentSession.NextHotKey.KeyCode != Keys.None)
|
|
{
|
|
//#if !DEBUG
|
|
User32.UnregisterHotKey((IntPtr)Handle, 1);
|
|
//#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
switch (m.Msg)
|
|
{
|
|
case User32.WM_HOTKEY:
|
|
if (m.WParam.ToInt32() == 1)
|
|
{
|
|
button5_MouseClick(null, null);
|
|
}
|
|
|
|
break;
|
|
//case WM_QUERYENDSESSION:
|
|
// requestExit = true;
|
|
// //this.Close();
|
|
// Application.Exit();
|
|
|
|
// break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
base.WndProc(ref m);
|
|
}
|
|
|
|
|
|
public bool IsBusy
|
|
{
|
|
get => _isBusy;
|
|
set
|
|
{
|
|
_isBusy = value;
|
|
|
|
UIControl.SetValue(pictureBox1, (_isBusy ? RyzStudio.Windows.ThemedForms.Resource2.loading_block : null));
|
|
UIControl.SetEnable(textBox1, !_isBusy);
|
|
button2.LabelText = (_isBusy ? "&Cancel" : "&Search");
|
|
UIControl.SetEnable(button5, !_isBusy);
|
|
UIControl.SetEnable(button4, !_isBusy);
|
|
}
|
|
}
|
|
|
|
public AppSession CurrentSession { get; set; } = new AppSession();
|
|
|
|
public List<string> SearchPaths
|
|
{
|
|
get => _searchPaths;
|
|
set
|
|
{
|
|
_searchPaths = value;
|
|
|
|
textBox2.Text = string.Join(", ", _searchPaths.ToArray());
|
|
}
|
|
}
|
|
|
|
|
|
#region Main Menu
|
|
|
|
/// <summary>
|
|
/// New
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void newToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this.CurrentSession.ClosePrevOnNext)
|
|
{
|
|
CloseCurrentProcess(_currentProcess);
|
|
}
|
|
|
|
ClearSession();
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void openToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (openFileDialog2.ShowDialog() == DialogResult.OK)
|
|
{
|
|
await LoadSessionFile(openFileDialog2.FileName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save as
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
saveFileDialog1.Title = "Save session";
|
|
saveFileDialog1.Filter = "Session files (*.jsonfig)|*.jsonfig";
|
|
saveFileDialog1.DefaultExt = "jsonfig";
|
|
|
|
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
await SaveSessionFile(saveFileDialog1.FileName);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void exitToolStripMenuItem2_Click(object sender, EventArgs e)
|
|
{
|
|
this.Close();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Options
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var optionsForm = new OptionsForm(this.CurrentSession);
|
|
if (optionsForm.ShowDialog() == DialogResult.OK)
|
|
{
|
|
this.CurrentSession = optionsForm.Result;
|
|
|
|
InvalidateHotKey();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Help
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void viewHelpToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
RyzStudio.Diagnostics.Process.Execute(AppResource.AppHelpURL);
|
|
}
|
|
|
|
/// <summary>
|
|
/// About
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
|
|
{
|
|
var form = new RyzStudio.Windows.ThemedForms.AboutForm();
|
|
form.ProductURL = AppResource.AppProductURL;
|
|
form.AuthorURL = AppResource.AppAuthorURL;
|
|
form.CompanyURL = AppResource.AppCompanyURL;
|
|
form.ProductCopyrightStartYear = 2021;
|
|
form.ProductLogo = AppResource.icon_64;
|
|
|
|
form.ShowDialog();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Search Engine
|
|
|
|
private async Task fileSearcher_OnFileFound(FileSearcher sender, string searchPath, string fileName)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
_foundFiles.Add(fileName);
|
|
|
|
UIControl.SetText(label3, Path.GetFileName(fileName));
|
|
|
|
progressBar2.Maximum = (sender.FileCount + sender.NoAccessFileCount);
|
|
progressBar2.Value = sender.FileCount;
|
|
});
|
|
}
|
|
|
|
private async Task fileSearcher_OnDirectoryFound(FileSearcher sender, string searchPath, string directoryName)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
UIControl.SetText(label4, Path.GetFileName(directoryName));
|
|
|
|
progressBar1.Maximum = sender.DirectoryCount;
|
|
progressBar1.Value = sender.BufferLevel;
|
|
});
|
|
}
|
|
|
|
private async Task fileSearcher_OnSearchCompleted(FileSearcher sender, TimeSpan elapsedTime)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
UIControl.SetText(label4, $"Done in {Math.Floor(elapsedTime.TotalMinutes)}m {elapsedTime.Seconds}s");
|
|
UIControl.SetText(label3, ((_foundFiles.Count <= 0) ? "0" : _foundFiles.Count.ToString("#,#", System.Globalization.CultureInfo.CurrentCulture)) + " File" + ((_foundFiles.Count == 1) ? "" : "s") + " Found");
|
|
|
|
progressBar1.Value = sender.BufferLevel;
|
|
progressBar2.Value = sender.FileCount;
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
private void textBox2_OnButtonClick(object sender, EventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var form = new MemoBoxForm(this.SearchPaths);
|
|
if (form.ShowDialog() == DialogResult.OK)
|
|
{
|
|
this.SearchPaths = form.Result;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void button2_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
button2.LabelText = "&Cancelling...";
|
|
_cancellationToken.Cancel();
|
|
|
|
return;
|
|
}
|
|
|
|
this.IsBusy = true;
|
|
|
|
progressBar1.ShowProgressText = true;
|
|
progressBar2.ShowProgressText = true;
|
|
|
|
_foundFiles = new List<string>();
|
|
_cancellationToken = new CancellationTokenSource();
|
|
_currentProcess = null;
|
|
|
|
_fileSearcher.FileSearchPattern = textBox1.Text;
|
|
_fileSearcher.SearchPath = new List<string>();
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
foreach (var item in SearchPaths)
|
|
{
|
|
if (_cancellationToken.IsCancellationRequested)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (System.IO.File.Exists(item))
|
|
{
|
|
_foundFiles.Add(item);
|
|
|
|
continue;
|
|
}
|
|
|
|
if (System.IO.Directory.Exists(item))
|
|
{
|
|
_fileSearcher.SearchPath.Add(item);
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
UIControl.SetText(label3, ((_foundFiles.Count <= 0) ? "0" : _foundFiles.Count.ToString("#,#", System.Globalization.CultureInfo.CurrentCulture)) + " File" + ((_foundFiles.Count == 1) ? "" : "s") + " Found");
|
|
});
|
|
|
|
if (_fileSearcher.SearchPath.Count > 0)
|
|
{
|
|
await _fileSearcher.Search(_cancellationToken.Token);
|
|
}
|
|
|
|
this.IsBusy = false;
|
|
|
|
_cancellationToken = new CancellationTokenSource();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Run next
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void button5_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_foundFiles.Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
//this.IsBusy = true;
|
|
|
|
if (this.CurrentSession == null)
|
|
{
|
|
this.CurrentSession = new AppSession();
|
|
}
|
|
|
|
if (this.CurrentSession.ClosePrevOnNext)
|
|
{
|
|
CloseCurrentProcess(_currentProcess);
|
|
}
|
|
|
|
string filename = null;
|
|
|
|
// retry 8 times
|
|
for (int i = 0; i < this.CurrentSession.RetryOnError; i++)
|
|
{
|
|
filename = _foundFiles[_randy.Next(0, (_foundFiles.Count - 1))];
|
|
if (System.IO.File.Exists(filename))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
filename = null;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(filename))
|
|
{
|
|
_currentProcess = RyzStudio.Diagnostics.Process.Execute(filename);
|
|
}
|
|
|
|
//this.IsBusy = false;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save File List
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private async void button4_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (this.IsBusy)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_foundFiles.Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
saveFileDialog1.Title = "Save File List";
|
|
saveFileDialog1.Filter = "Text files (*.txt)|*.txt";
|
|
saveFileDialog1.DefaultExt = "txt";
|
|
|
|
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
|
|
{
|
|
try
|
|
{
|
|
await System.IO.File.WriteAllTextAsync(saveFileDialog1.FileName, string.Join(Environment.NewLine, _foundFiles.ToArray()));
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
ThMessageBox.Show(this, exc.Message, "Save File List", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Close
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
private void button1_MouseClick(object sender, MouseEventArgs e)
|
|
{
|
|
this.Close();
|
|
}
|
|
|
|
|
|
private void CloseCurrentProcess(Process p)
|
|
{
|
|
if (p == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
p.CloseMainWindow();
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// do nothing
|
|
}
|
|
}
|
|
|
|
private void InvalidateHotKey()
|
|
{
|
|
//#if !DEBUG
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
User32.UnregisterHotKey((IntPtr)Handle, 1);
|
|
});
|
|
//#endif
|
|
|
|
if (this.CurrentSession.NextHotKey != null)
|
|
{
|
|
if (this.CurrentSession.NextHotKey.KeyCode != Keys.None)
|
|
{
|
|
//#if !DEBUG
|
|
UIControl.Invoke(this, (x) =>
|
|
{
|
|
User32.RegisterHotKey((IntPtr)Handle, 1, this.CurrentSession.NextHotKey.ModifierCode, this.CurrentSession.NextHotKey.Key);
|
|
});
|
|
//#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearSession()
|
|
{
|
|
_foundFiles = new List<string>();
|
|
_currentProcess = null;
|
|
|
|
textBox1.Text = "*.*";
|
|
|
|
progressBar1.Clear(0, 0, 0);
|
|
progressBar2.Clear(0, 0, 0);
|
|
|
|
UIControl.SetText(label4, "");
|
|
UIControl.SetText(label3, "");
|
|
}
|
|
|
|
protected async Task LoadSessionFile(string filename)
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
this.CurrentSession = RyzStudio.Text.Json.JsonSerialiser.DeserialiseFile<AppSession>(filename) ?? new AppSession();
|
|
|
|
ClearSession();
|
|
|
|
textBox1.Text = (string.IsNullOrWhiteSpace(this.CurrentSession.SearchFilePattern) ? "*" : this.CurrentSession.SearchFilePattern?.Trim());
|
|
|
|
SearchPaths = this.CurrentSession?.SearchItems ?? new List<string>();
|
|
|
|
// hotkey
|
|
InvalidateHotKey();
|
|
});
|
|
}
|
|
|
|
protected async Task SaveSessionFile(string filename)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(filename))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this.CurrentSession == null)
|
|
{
|
|
this.CurrentSession = new AppSession();
|
|
}
|
|
|
|
await Task.Run(() =>
|
|
{
|
|
this.CurrentSession.SearchFilePattern = textBox1.Text;
|
|
this.CurrentSession.SearchItems = new List<string>();
|
|
|
|
foreach (var item in SearchPaths)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
this.CurrentSession.SearchItems.Add(item.Trim());
|
|
}
|
|
|
|
var result = RyzStudio.Text.Json.JsonSerialiser.SerialiseFile(filename, this.CurrentSession);
|
|
if (result.IsSuccess)
|
|
{
|
|
ThMessageBox.Show(this, "Session saved!", "Save session");
|
|
}
|
|
else
|
|
{
|
|
ThMessageBox.Show(this, result.Message, "Save session", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
} |