v1.15 — PowerShell edition + repo restructure
- New powershell/InstaSoftOfficeTool.ps1: single-file WPF GUI version - Same Fluent Design UI, no compilation needed - Runs on any Windows 7+ with PowerShell 5.1 (built-in) - Chrome won't flag .ps1 files as "rarely downloaded" - Auto-elevates to admin - Moved C# source to src/ subfolder - Updated .gitignore for nested bin/obj folders Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,124 +0,0 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace InstaSoftOfficeTool.Pages
|
||||
{
|
||||
public partial class ProductKeyDialog : UserControl
|
||||
{
|
||||
private TaskCompletionSource<string> _tcs;
|
||||
private readonly TextBox[] _keyBoxes;
|
||||
private bool _suppress;
|
||||
|
||||
public ProductKeyDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
_keyBoxes = new[] { DKey1, DKey2, DKey3, DKey4, DKey5 };
|
||||
|
||||
foreach (var box in _keyBoxes)
|
||||
{
|
||||
DataObject.AddPastingHandler(box, OnPaste);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<string> ShowAsync()
|
||||
{
|
||||
foreach (var box in _keyBoxes) box.Text = "";
|
||||
BtnOk.IsEnabled = false;
|
||||
Visibility = Visibility.Visible;
|
||||
DKey1.Focus();
|
||||
_tcs = new TaskCompletionSource<string>();
|
||||
return _tcs.Task;
|
||||
}
|
||||
|
||||
private string GetFullKey()
|
||||
{
|
||||
return string.Join("-", DKey1.Text, DKey2.Text, DKey3.Text, DKey4.Text, DKey5.Text).ToUpper();
|
||||
}
|
||||
|
||||
private bool IsKeyComplete()
|
||||
{
|
||||
foreach (var box in _keyBoxes)
|
||||
{
|
||||
if (box.Text.Length != 5 || !Regex.IsMatch(box.Text, "^[A-Za-z0-9]{5}$"))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void KeyBox_TextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (_suppress) return;
|
||||
var tb = (TextBox)sender;
|
||||
|
||||
var cleaned = Regex.Replace(tb.Text, "[^A-Za-z0-9]", "");
|
||||
if (cleaned != tb.Text)
|
||||
{
|
||||
_suppress = true;
|
||||
tb.Text = cleaned;
|
||||
tb.CaretIndex = cleaned.Length;
|
||||
_suppress = false;
|
||||
}
|
||||
|
||||
if (tb.Text.Length == 5)
|
||||
{
|
||||
for (int i = 0; i < _keyBoxes.Length - 1; i++)
|
||||
{
|
||||
if (_keyBoxes[i] == tb)
|
||||
{
|
||||
_keyBoxes[i + 1].Focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BtnOk.IsEnabled = IsKeyComplete();
|
||||
}
|
||||
|
||||
private void OnPaste(object sender, DataObjectPastingEventArgs e)
|
||||
{
|
||||
if (!e.DataObject.GetDataPresent(typeof(string))) return;
|
||||
var pasted = (string)e.DataObject.GetData(typeof(string));
|
||||
var allAlphaNum = Regex.Replace(pasted, "[^A-Za-z0-9]", "");
|
||||
|
||||
if (allAlphaNum.Length <= 5) return;
|
||||
|
||||
e.CancelCommand();
|
||||
_suppress = true;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
int start = i * 5;
|
||||
if (start < allAlphaNum.Length)
|
||||
{
|
||||
int len = Math.Min(5, allAlphaNum.Length - start);
|
||||
_keyBoxes[i].Text = allAlphaNum.Substring(start, len).ToUpper();
|
||||
}
|
||||
}
|
||||
_suppress = false;
|
||||
_keyBoxes[4].Focus();
|
||||
_keyBoxes[4].CaretIndex = _keyBoxes[4].Text.Length;
|
||||
BtnOk.IsEnabled = IsKeyComplete();
|
||||
}
|
||||
|
||||
private void BtnOk_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Visibility = Visibility.Collapsed;
|
||||
_tcs?.TrySetResult(GetFullKey());
|
||||
}
|
||||
|
||||
private void BtnCancel_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Visibility = Visibility.Collapsed;
|
||||
_tcs?.TrySetResult(null);
|
||||
}
|
||||
|
||||
private void Backdrop_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Visibility = Visibility.Collapsed;
|
||||
_tcs?.TrySetResult(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user