|
namespace FindDuplicateFile
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Windows;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class DuplicateFileFinder : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// get or set this flag to indicate searching through Hash or through file length.
/// </summary>
private bool isHashSearch;
public bool IsHashSearch
{
get { return isHashSearch; }
set { isHashSearch = value; OnPropertyChanged("IsHashSearch"); }
}
/// <summary>
/// Background worker object
/// </summary>
private System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker();
/// <summary>
/// Private variable for search criteria.
/// </summary>
private string searchExtension = "*.*";
private string _currentPath = string.Empty;
/// <summary>
/// Initialize a new instance of the DuplicateFileFinder class.
/// </summary>
public DuplicateFileFinder()
{
InitializeComponent();
this.DataContext = this;
this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker_DoWork);
this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted);
this.backgroundWorker.WorkerSupportsCancellation = true;
this.backgroundWorker.WorkerReportsProgress = true;
lastStackPanel.RegisterName("wpfProgressBar", wpfProgressBar);
}
/// <summary>
/// Runs on secondary thread.
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">DoWork event argument</param>
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// call long running process and get result
DirectoryInfo dinfo = new DirectoryInfo(this._currentPath);
if (isHashSearch)
{
// FileLength = "FileImpression";
e.Result = this.GetFiles(dinfo)
.GroupBy(i => i.fileImpression)
.Where(g => g.Count() > 1)
.SelectMany(list => list)
.ToList<FileAttrib>();
}
else
{
e.Result = this.GetFiles(dinfo)
.GroupBy(i => i.fileLength)
.Where(g => g.Count() > 1)
.SelectMany(list => list)
.ToList<FileAttrib>();
// FileLength = "FileLength";
}
// Cancel if cancel button was clicked.
if (this.backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
}
/// <summary>
/// Called when DoWork has completed.
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">RunWorker completed argument</param>
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
try
{
// Back on primary thread, can access ui controls
wpfProgressBarAndText.Visibility = Visibility.Collapsed;
if (e.Cancelled)
{
dataGrid1.ItemsSource = "There is no Data to display";
}
else
{
dataGrid1.ItemsSource = (List<FileAttrib>)e.Result;
}
CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
if (IsHashSearch)
{
PropertyGroupDescription pgd = new PropertyGroupDescription("fileImpression");
cv.GroupDescriptions.Add(pgd);
}
else
{
PropertyGroupDescription pgd = new PropertyGroupDescription("fileLength");
cv.GroupDescriptions.Add(pgd);
}
}
finally
{
this.Calculate.Content = "Start";
fileExtension.Visibility = System.Windows.Visibility.Visible;
}
}
/// <summary>
/// Start/Stop button click event
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">Routed event Argument</param>
private void Button1_Click(object sender, RoutedEventArgs e)
{
System.Windows.MessageBox.Show("This tool will skip all the folders that are not authorized to read.", "Information", MessageBoxButton.OK);
//// set isHashSearch flag from radio button value.
IsHashSearch = rdbHash.IsChecked.Value;
if (Directory.Exists(this._currentPath))
{
if (this.Calculate.Content.Equals("Start"))
{
this.searchExtension = this.fileExtension.Text;
if (string.IsNullOrWhiteSpace(this.searchExtension))
{
this.searchExtension = "*";
}
this.Calculate.Content = "Stop";
this.dataGrid1.AutoGenerateColumns = true;
this.backgroundWorker.RunWorkerAsync();
this.wpfProgressBarAndText.Visibility = Visibility.Visible;
this.fileExtension.Visibility = System.Windows.Visibility.Collapsed;
}
else
{
// Cancel the asynchronous operation.
this.backgroundWorker.CancelAsync();
this.backgroundWorker = new System.ComponentModel.BackgroundWorker();
this.backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.BackgroundWorker_DoWork);
this.backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.BackgroundWorker_RunWorkerCompleted);
this.backgroundWorker.WorkerSupportsCancellation = true;
this.backgroundWorker.WorkerReportsProgress = true;
this.backgroundWorker = new BackgroundWorker();
this.Calculate.Content = "Start";
this.wpfProgressBarAndText.Visibility = Visibility.Collapsed;
this.fileExtension.Visibility = System.Windows.Visibility.Visible;
}
}
else
{
System.Windows.Forms.MessageBox.Show("Please select correct folder");
}
}
/// <summary>
/// Method to get all the files from given folder and subfolders.
/// </summary>
/// <param name="dinfo">DirectoryInfo object for the directory.</param>
/// <returns>Gives list of FileAttrib object with all files</returns>
private List<FileAttrib> GetFiles(DirectoryInfo dinfo)
{
List<FileAttrib> files = new List<FileAttrib>();
try
{
if (this.searchExtension == "*")
{
files.AddRange(dinfo.GetFiles().Select(s => this.ConvertFileInfo(s)));
}
else
{
files.AddRange(dinfo.GetFiles().Where(g => g.Extension.ToLower() == string.Format(".{0}", this.searchExtension.ToLower())).Select(s => this.ConvertFileInfo(s)));
}
foreach (var directory in dinfo.GetDirectories())
{
files.AddRange(this.GetFiles(directory));
}
}
catch (UnauthorizedAccessException)
{
}
return files;
}
/// <summary>
/// Convertor for converting FileInfo object into FileAttrib
/// </summary>
/// <param name="finfo">Original FileInfo object</param>
/// <returns>Generated FileAttrib object</returns>
private FileAttrib ConvertFileInfo(FileInfo finfo)
{
return new FileAttrib
{
fileName = finfo.Name,
filePath = finfo.FullName,
fileImpression = isHashSearch ? this.FileToMD5Hash(finfo.FullName) : null,
fileLength = finfo.Length
};
}
/// <summary>
/// Function to get file hash string from a file location.
/// </summary>
/// <param name="_fileName">File name to get byte array</param>
/// <returns>Byte Array</returns>
private string FileToMD5Hash(string _fileName)
{
var returnString = string.Empty;
try
{
using (var stream = new BufferedStream(File.OpenRead(_fileName), 1200000))
{
SHA256Managed sha = new SHA256Managed();
byte[] checksum = sha.ComputeHash(stream);
returnString = BitConverter.ToString(checksum).Replace("-", string.Empty);
}
}
catch
{ }
return returnString;
}
/// <summary>
/// Delete particular file using Menu Sub-item
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="e">routed event argument</param>
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
try
{
var source = dataGrid1.ItemsSource.Cast<FileAttrib>().ToList();
foreach (var selectedItem in dataGrid1.SelectedItems)
{
var deleteFilePath = source.Where((s, i) => s.filePath == ((FileAttrib)selectedItem).filePath).Select(s => s.filePath).First();
if (File.Exists(deleteFilePath))
{
File.Delete(deleteFilePath);
source.RemoveAt(dataGrid1.SelectedIndex);
}
}
dataGrid1.ItemsSource = source;
CollectionView cv = (CollectionView)CollectionViewSource.GetDefaultView(dataGrid1.ItemsSource);
if (IsHashSearch)
{
PropertyGroupDescription pgd = new PropertyGroupDescription("fileImpression");
cv.GroupDescriptions.Add(pgd);
}
else
{
PropertyGroupDescription pgd = new PropertyGroupDescription("fileLength");
cv.GroupDescriptions.Add(pgd);
}
}
catch (UnauthorizedAccessException)
{
System.Windows.MessageBox.Show("You do not have permission to delete this file.");
}
}
/// <summary>
/// Open contain file location using Menu click event.
/// </summary>
/// <param name="sender">sender object</param>
/// <param name="e">Routed event argument</param>
private void MenuItem_Click_1(object sender, RoutedEventArgs e)
{
var source = dataGrid1.ItemsSource.Cast<FileAttrib>().ToList();
var deleteFilePath = source.Where((s, i) => i == dataGrid1.SelectedIndex).Select(s => s.filePath).First();
ProcessStartInfo fileFolder = new ProcessStartInfo("explorer.exe", "/select,\"" + deleteFilePath + "\"");
fileFolder.UseShellExecute = false;
Process.Start(fileFolder);
}
private void selectPath_Click(object sender, RoutedEventArgs e)
{
FolderBrowserDialog folderDialog = new FolderBrowserDialog();
folderDialog.Description = "Select folder to find similar files.";
folderDialog.SelectedPath = this._currentPath;
folderDialog.ShowNewFolderButton = false;
DialogResult result = folderDialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
this._currentPath = folderDialog.SelectedPath;
this.folderPath.Text = this._currentPath;
}
else
{
System.Windows.Forms.MessageBox.Show("You have not selected or canceled Path selection popup");
}
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.