159 lines
6.3 KiB
PowerShell
159 lines
6.3 KiB
PowerShell
#requires -version 5.1
|
|
<#
|
|
.SYNOPSIS
|
|
A PowerShell script with a GUI to merge and deduplicate the contents of hash files.
|
|
.DESCRIPTION
|
|
This script provides a user-friendly graphical interface to:
|
|
1. Select multiple text-based hash files.
|
|
2. Read all lines from the selected files.
|
|
3. Remove all duplicate lines efficiently.
|
|
4. Save the merged, unique list of hashes to a new file specified by the user.
|
|
.AUTHOR
|
|
Gemini
|
|
#>
|
|
|
|
# Load necessary .NET assemblies for the GUI
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
Add-Type -AssemblyName System.Drawing
|
|
|
|
# Suppress errors for a cleaner user experience in the console
|
|
$ErrorActionPreference = 'SilentlyContinue'
|
|
|
|
# --- GUI FORM SETUP ---
|
|
$form = New-Object System.Windows.Forms.Form
|
|
$form.Text = 'Hash File Merger & Deduplicator'
|
|
$form.Size = New-Object System.Drawing.Size(600, 450)
|
|
$form.StartPosition = 'CenterScreen'
|
|
$form.FormBorderStyle = 'FixedSingle'
|
|
$form.MaximizeBox = $false
|
|
$form.Icon = [System.Drawing.SystemIcons]::Application
|
|
|
|
# --- GUI CONTROLS ---
|
|
|
|
# 1. "Select Files" Button
|
|
$selectButton = New-Object System.Windows.Forms.Button
|
|
$selectButton.Text = '1. Select Hash Files...'
|
|
$selectButton.Location = New-Object System.Drawing.Point(20, 20)
|
|
$selectButton.Size = New-Object System.Drawing.Size(550, 40)
|
|
$selectButton.Font = New-Object System.Drawing.Font('Segoe UI', 10, [System.Drawing.FontStyle]::Bold)
|
|
|
|
# 2. ListBox to display selected files
|
|
$fileListBox = New-Object System.Windows.Forms.ListBox
|
|
$fileListBox.Location = New-Object System.Drawing.Point(20, 70)
|
|
$fileListBox.Size = New-Object System.Drawing.Size(550, 200)
|
|
$fileListBox.HorizontalScrollbar = $true
|
|
|
|
# 3. "Merge and Save" Button
|
|
$mergeButton = New-Object System.Windows.Forms.Button
|
|
$mergeButton.Text = '2. Merge and Save As...'
|
|
$mergeButton.Location = New-Object System.Drawing.Point(20, 280)
|
|
$mergeButton.Size = New-Object System.Drawing.Size(550, 40)
|
|
$mergeButton.Enabled = $false # Disabled until files are selected
|
|
$mergeButton.Font = New-Object System.Drawing.Font('Segoe UI', 10, [System.Drawing.FontStyle]::Bold)
|
|
|
|
# 4. Status Label for feedback
|
|
$statusLabel = New-Object System.Windows.Forms.Label
|
|
$statusLabel.Text = 'Please select one or more hash files to begin.'
|
|
$statusLabel.Location = New-Object System.Drawing.Point(20, 330)
|
|
$statusLabel.Size = New-Object System.Drawing.Size(550, 25)
|
|
$statusLabel.Font = New-Object System.Drawing.Font('Segoe UI', 9)
|
|
|
|
# 5. Final Result Label
|
|
$resultLabel = New-Object System.Windows.Forms.Label
|
|
$resultLabel.Text = ''
|
|
$resultLabel.Location = New-Object System.Drawing.Point(20, 355)
|
|
$resultLabel.Size = New-Object System.Drawing.Size(550, 25)
|
|
$resultLabel.Font = New-Object System.Drawing.Font('Segoe UI', 9, [System.Drawing.FontStyle]::Bold)
|
|
|
|
|
|
# --- EVENT HANDLERS (Button Click Actions) ---
|
|
|
|
# Action for the "Select Files" button
|
|
$selectButton.Add_Click({
|
|
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
|
|
$openFileDialog.Title = "Select Hash Files"
|
|
$openFileDialog.Filter = "Text Files (*.txt, *.dic)|*.txt;*.dic|All Files (*.*)|*.*"
|
|
$openFileDialog.Multiselect = $true
|
|
|
|
if ($openFileDialog.ShowDialog() -eq 'OK') {
|
|
# Clear previous list and add new files
|
|
$fileListBox.Items.Clear()
|
|
$openFileDialog.FileNames | ForEach-Object { $fileListBox.Items.Add($_) }
|
|
|
|
# Update status and enable the merge button
|
|
$statusLabel.Text = "$($fileListBox.Items.Count) file(s) selected."
|
|
$resultLabel.Text = ""
|
|
$mergeButton.Enabled = $true
|
|
}
|
|
})
|
|
|
|
# Action for the "Merge and Save" button
|
|
$mergeButton.Add_Click({
|
|
# Disable buttons during processing
|
|
$mergeButton.Enabled = $false
|
|
$selectButton.Enabled = $false
|
|
$form.Cursor = [System.Windows.Forms.Cursors]::WaitCursor
|
|
|
|
try {
|
|
$statusLabel.Text = "Processing... Reading files and calculating hashes."
|
|
$form.Refresh() # Force the UI to update
|
|
|
|
# Using a HashSet for high-performance deduplication, especially with large files
|
|
$uniqueHashes = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
|
|
$totalLines = 0
|
|
|
|
# Read each file and add its lines to the HashSet
|
|
foreach ($filePath in $fileListBox.Items) {
|
|
$lines = [System.IO.File]::ReadAllLines($filePath)
|
|
$totalLines += $lines.Count
|
|
foreach ($line in $lines) {
|
|
# Only add non-empty lines
|
|
if (-not [string]::IsNullOrWhiteSpace($line)) {
|
|
$uniqueHashes.Add($line) | Out-Null
|
|
}
|
|
}
|
|
}
|
|
|
|
$statusLabel.Text = "Read $totalLines total lines. Found $($uniqueHashes.Count) unique lines."
|
|
$resultLabel.Text = "Please choose where to save the merged file."
|
|
$form.Refresh()
|
|
|
|
# Prompt user for save location
|
|
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
|
|
$saveFileDialog.Title = "Save Merged Hash File"
|
|
$saveFileDialog.Filter = "Text File (*.txt)|*.txt"
|
|
$saveFileDialog.FileName = "merged_hashes.txt"
|
|
|
|
if ($saveFileDialog.ShowDialog() -eq 'OK') {
|
|
# Write the unique hashes to the new file
|
|
[System.IO.File]::WriteAllLines($saveFileDialog.FileName, $uniqueHashes)
|
|
$resultLabel.Text = "Success! Saved $($uniqueHashes.Count) unique hashes to $($saveFileDialog.SafeFileName)."
|
|
$statusLabel.Text = "Process complete. Select more files or close the window."
|
|
} else {
|
|
$resultLabel.Text = "Save operation was cancelled."
|
|
}
|
|
}
|
|
catch {
|
|
[System.Windows.Forms.MessageBox]::Show("An error occurred: $($_.Exception.Message)", "Error", "OK", "Error")
|
|
$resultLabel.Text = "An error occurred during processing."
|
|
}
|
|
finally {
|
|
# Re-enable buttons and restore cursor
|
|
$mergeButton.Enabled = $true
|
|
$selectButton.Enabled = $true
|
|
$form.Cursor = [System.Windows.Forms.Cursors]::Default
|
|
}
|
|
})
|
|
|
|
|
|
# --- ADD CONTROLS TO FORM and SHOW ---
|
|
|
|
$form.Controls.Add($selectButton)
|
|
$form.Controls.Add($fileListBox)
|
|
$form.Controls.Add($mergeButton)
|
|
$form.Controls.Add($statusLabel)
|
|
$form.Controls.Add($resultLabel)
|
|
|
|
# Display the form to the user
|
|
[void]$form.ShowDialog()
|
|
|