using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Collections.Generic;
using Timer = System.Windows.Forms.Timer;
namespace VStudioCleaner_ns
{
/// <summary>
/// Author: Dennis Lang - 2009
/// http://home.comcast.net/~lang.dennis/
///
/// This application is based off of Leonardo Paneque "Solution Cleaner"
/// http://www.teknowmagic.net/
///
/// Scan folder (directory) paths and apply filters to extract 'located' files.
/// </summary>
public class FileScan : System.Windows.Forms.Form
{
private IContainer components;
string path;
ArrayList filterList;
int maxFileList;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label infoLbl;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label totalFilesLabel;
private System.Windows.Forms.Label totalBytesLabel;
private System.Windows.Forms.MenuItem RemoveMenuItem;
private System.Windows.Forms.ProgressBar ProgressMon;
private System.Windows.Forms.Button DelFilesBtn;
private System.Windows.Forms.Button StopBtn;
private ListView filesListview;
private ColumnHeader columnHeader0;
private ColumnHeader columnHeader1;
private ColumnHeader columnHeader2;
private ColumnHeader columnHeader3;
private ColumnHeader columnHeader4;
private ColumnHeader columnHeader5;
private ToolTip toolTip;
private MenuItem menuItem1;
private MenuItem menuItem2;
private Button exportBtn;
private SaveFileDialog exportCsvDialog;
private TableLayoutPanel btnTable;
private Button closeBtn;
private Label label1;
private TextBox selFilterBox;
private MenuItem RemoveInvMenuItem;
private MenuItem deleteNowMenuItem;
private System.Windows.Forms.ContextMenu FileListContextMenu;
public FileScan(string path,ArrayList filterList, int maxFileList)
{
this.path = path;
this.filterList = filterList;
this.maxFileList = maxFileList;
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.filesListview.ListViewItemSorter = new ListViewColumnSorter(ListViewColumnSorter.SortDataType.eAuto);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FileScan));
this.DelFilesBtn = new System.Windows.Forms.Button();
this.FileListContextMenu = new System.Windows.Forms.ContextMenu();
this.RemoveMenuItem = new System.Windows.Forms.MenuItem();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
this.StopBtn = new System.Windows.Forms.Button();
this.ProgressMon = new System.Windows.Forms.ProgressBar();
this.panel1 = new System.Windows.Forms.Panel();
this.infoLbl = new System.Windows.Forms.Label();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.totalFilesLabel = new System.Windows.Forms.Label();
this.totalBytesLabel = new System.Windows.Forms.Label();
this.filesListview = new System.Windows.Forms.ListView();
this.columnHeader0 = new System.Windows.Forms.ColumnHeader();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.exportBtn = new System.Windows.Forms.Button();
this.closeBtn = new System.Windows.Forms.Button();
this.exportCsvDialog = new System.Windows.Forms.SaveFileDialog();
this.btnTable = new System.Windows.Forms.TableLayoutPanel();
this.label1 = new System.Windows.Forms.Label();
this.selFilterBox = new System.Windows.Forms.TextBox();
this.deleteNowMenuItem = new System.Windows.Forms.MenuItem();
this.RemoveInvMenuItem = new System.Windows.Forms.MenuItem();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.btnTable.SuspendLayout();
this.SuspendLayout();
//
// DelFilesBtn
//
this.DelFilesBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.DelFilesBtn.AutoSize = true;
this.DelFilesBtn.BackColor = System.Drawing.SystemColors.Highlight;
this.DelFilesBtn.Enabled = false;
this.DelFilesBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.DelFilesBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.DelFilesBtn.ForeColor = System.Drawing.Color.White;
this.DelFilesBtn.Location = new System.Drawing.Point(3, 4);
this.DelFilesBtn.Name = "DelFilesBtn";
this.DelFilesBtn.RightToLeft = System.Windows.Forms.RightToLeft.No;
this.DelFilesBtn.Size = new System.Drawing.Size(86, 25);
this.DelFilesBtn.TabIndex = 0;
this.DelFilesBtn.Text = "Delete Files";
this.toolTip.SetToolTip(this.DelFilesBtn, "Warning - deletes ALL files in list above. ");
this.DelFilesBtn.UseVisualStyleBackColor = false;
this.DelFilesBtn.Click += new System.EventHandler(this.deleteBtn_Click);
//
// FileListContextMenu
//
this.FileListContextMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.RemoveMenuItem,
this.RemoveInvMenuItem,
this.deleteNowMenuItem,
this.menuItem1,
this.menuItem2});
//
// RemoveMenuItem
//
this.RemoveMenuItem.Index = 0;
this.RemoveMenuItem.Text = "Remove from list";
this.RemoveMenuItem.Click += new System.EventHandler(this.RemoveMenuItem_Click);
//
// menuItem1
//
this.menuItem1.Index = 3;
this.menuItem1.Text = "Launch file explorer";
this.menuItem1.Click += new System.EventHandler(this.LaunchExplorer_Click);
//
// menuItem2
//
this.menuItem2.Index = 4;
this.menuItem2.Text = "Launch cmd";
this.menuItem2.Click += new System.EventHandler(this.LaunchCmd_Click);
//
// StopBtn
//
this.StopBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.StopBtn.AutoSize = true;
this.StopBtn.BackColor = System.Drawing.SystemColors.Highlight;
this.StopBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.StopBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.StopBtn.ForeColor = System.Drawing.Color.White;
this.StopBtn.Location = new System.Drawing.Point(455, 4);
this.StopBtn.Name = "StopBtn";
this.StopBtn.Size = new System.Drawing.Size(75, 25);
this.StopBtn.TabIndex = 2;
this.StopBtn.Text = "Stop";
this.toolTip.SetToolTip(this.StopBtn, "Stop active scan or deletion.\r\n\r\n");
this.StopBtn.UseVisualStyleBackColor = false;
this.StopBtn.Click += new System.EventHandler(this.stopBtn_Click);
//
// ProgressMon
//
this.ProgressMon.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.ProgressMon.Location = new System.Drawing.Point(18, 102);
this.ProgressMon.Maximum = 26;
this.ProgressMon.Name = "ProgressMon";
this.ProgressMon.Size = new System.Drawing.Size(905, 22);
this.ProgressMon.TabIndex = 13;
this.ProgressMon.Visible = false;
//
// panel1
//
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.panel1.BackColor = System.Drawing.Color.White;
this.panel1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("panel1.BackgroundImage")));
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panel1.Controls.Add(this.infoLbl);
this.panel1.Controls.Add(this.pictureBox1);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(948, 72);
this.panel1.TabIndex = 8;
//
// infoLbl
//
this.infoLbl.BackColor = System.Drawing.Color.White;
this.infoLbl.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.infoLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.infoLbl.ForeColor = System.Drawing.Color.Black;
this.infoLbl.Location = new System.Drawing.Point(11, 16);
this.infoLbl.Name = "infoLbl";
this.infoLbl.Size = new System.Drawing.Size(487, 42);
this.infoLbl.TabIndex = 0;
this.infoLbl.Text = "Right click on items to remove before pressing Delete. Delete is permanent so ma" +
"ke sure the file list is correct ! Nothing moved to recycle bin";
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage")));
this.pictureBox1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
this.pictureBox1.Location = new System.Drawing.Point(525, 16);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(76, 50);
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(16, 86);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(78, 13);
this.label3.TabIndex = 9;
this.label3.Text = "Total Files : ";
//
// label4
//
this.label4.AutoSize = true;
this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label4.Location = new System.Drawing.Point(216, 86);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(88, 13);
this.label4.TabIndex = 10;
this.label4.Text = "Total Space : ";
//
// totalFilesLabel
//
this.totalFilesLabel.AutoSize = true;
this.totalFilesLabel.Location = new System.Drawing.Point(92, 86);
this.totalFilesLabel.Name = "totalFilesLabel";
this.totalFilesLabel.Size = new System.Drawing.Size(13, 13);
this.totalFilesLabel.TabIndex = 11;
this.totalFilesLabel.Text = "0";
//
// totalBytesLabel
//
this.totalBytesLabel.AutoSize = true;
this.totalBytesLabel.Location = new System.Drawing.Point(299, 86);
this.totalBytesLabel.Name = "totalBytesLabel";
this.totalBytesLabel.Size = new System.Drawing.Size(13, 13);
this.totalBytesLabel.TabIndex = 12;
this.totalBytesLabel.Text = "0";
//
// filesListview
//
this.filesListview.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.filesListview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.filesListview.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader0,
this.columnHeader1,
this.columnHeader2,
this.columnHeader3,
this.columnHeader4,
this.columnHeader5});
this.filesListview.ContextMenu = this.FileListContextMenu;
this.filesListview.FullRowSelect = true;
this.filesListview.GridLines = true;
this.filesListview.HideSelection = false;
this.filesListview.Location = new System.Drawing.Point(19, 130);
this.filesListview.Name = "filesListview";
this.filesListview.Size = new System.Drawing.Size(904, 389);
this.filesListview.TabIndex = 1;
this.filesListview.UseCompatibleStateImageBehavior = false;
this.filesListview.View = System.Windows.Forms.View.Details;
this.filesListview.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.ColumnClick);
this.filesListview.KeyUp += new System.Windows.Forms.KeyEventHandler(this.filesListview_KeyUp);
//
// columnHeader0
//
this.columnHeader0.Text = "Why";
this.columnHeader0.Width = 70;
//
// columnHeader1
//
this.columnHeader1.Text = "Location";
this.columnHeader1.Width = 400;
//
// columnHeader2
//
this.columnHeader2.Text = "File";
this.columnHeader2.Width = 200;
//
// columnHeader3
//
this.columnHeader3.Text = "Ext";
//
// columnHeader4
//
this.columnHeader4.Text = "Size";
//
// columnHeader5
//
this.columnHeader5.Text = "Status";
//
// exportBtn
//
this.exportBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.exportBtn.AutoSize = true;
this.exportBtn.BackColor = System.Drawing.SystemColors.Highlight;
this.exportBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.exportBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.exportBtn.ForeColor = System.Drawing.Color.White;
this.exportBtn.Location = new System.Drawing.Point(229, 4);
this.exportBtn.Name = "exportBtn";
this.exportBtn.Size = new System.Drawing.Size(121, 25);
this.exportBtn.TabIndex = 14;
this.exportBtn.Text = "Export Files List...";
this.toolTip.SetToolTip(this.exportBtn, "Export file list as CSV");
this.exportBtn.UseVisualStyleBackColor = false;
this.exportBtn.Click += new System.EventHandler(this.exportBtn_Click);
//
// closeBtn
//
this.closeBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.closeBtn.AutoSize = true;
this.closeBtn.BackColor = System.Drawing.SystemColors.Highlight;
this.closeBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.closeBtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.closeBtn.ForeColor = System.Drawing.Color.White;
this.closeBtn.Location = new System.Drawing.Point(681, 4);
this.closeBtn.Name = "closeBtn";
this.closeBtn.Size = new System.Drawing.Size(75, 25);
this.closeBtn.TabIndex = 15;
this.closeBtn.Text = "Close";
this.toolTip.SetToolTip(this.closeBtn, "Close Dialog");
this.closeBtn.UseVisualStyleBackColor = false;
this.closeBtn.Click += new System.EventHandler(this.closeBtn_Click);
//
// exportCsvDialog
//
this.exportCsvDialog.DefaultExt = "csv";
this.exportCsvDialog.Filter = "Csv|*.csv|Text|*.txt|All Files|*.*";
this.exportCsvDialog.Title = "Export File List";
//
// btnTable
//
this.btnTable.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.btnTable.ColumnCount = 4;
this.btnTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.btnTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.btnTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.btnTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.btnTable.Controls.Add(this.closeBtn, 3, 0);
this.btnTable.Controls.Add(this.StopBtn, 2, 0);
this.btnTable.Controls.Add(this.exportBtn, 1, 0);
this.btnTable.Controls.Add(this.DelFilesBtn, 0, 0);
this.btnTable.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize;
this.btnTable.Location = new System.Drawing.Point(19, 525);
this.btnTable.Name = "btnTable";
this.btnTable.RowCount = 1;
this.btnTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.btnTable.Size = new System.Drawing.Size(904, 32);
this.btnTable.TabIndex = 15;
//
// label1
//
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(19, 102);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(86, 20);
this.label1.TabIndex = 16;
this.label1.Text = "Selection Filter:";
//
// selFilterBox
//
this.selFilterBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.selFilterBox.HideSelection = false;
this.selFilterBox.Location = new System.Drawing.Point(123, 103);
this.selFilterBox.Name = "selFilterBox";
this.selFilterBox.Size = new System.Drawing.Size(799, 20);
this.selFilterBox.TabIndex = 17;
this.selFilterBox.TextChanged += new System.EventHandler(this.selFilterBox_TextChanged);
//
// deleteNowMenuItem
//
this.deleteNowMenuItem.Index = 2;
this.deleteNowMenuItem.Text = "Delete from Disk NOW!";
this.deleteNowMenuItem.Click += new System.EventHandler(this.DeleteNowMenuItem_Click);
//
// RemoveInvMenuItem
//
this.RemoveInvMenuItem.Index = 1;
this.RemoveInvMenuItem.Text = "Remove inverse of selected";
this.RemoveInvMenuItem.Click += new System.EventHandler(this.RemoveInvMenuItem_Click);
//
// FileScan
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.Color.Silver;
this.ClientSize = new System.Drawing.Size(948, 566);
this.Controls.Add(this.ProgressMon);
this.Controls.Add(this.selFilterBox);
this.Controls.Add(this.label1);
this.Controls.Add(this.btnTable);
this.Controls.Add(this.filesListview);
this.Controls.Add(this.totalBytesLabel);
this.Controls.Add(this.totalFilesLabel);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.panel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FileScan";
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Located Files";
this.Load += new System.EventHandler(this.LocateFiles);
this.Closing += new System.ComponentModel.CancelEventHandler(this.ClosingEvent);
this.panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.btnTable.ResumeLayout(false);
this.btnTable.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
#region ==== Support methods
/// <summary>
/// Format size into Bytes, Kbytes or Mbytes.
/// </summary>
/// <param name="val"></param>
/// <returns></returns>
public static string FormatSize(long val)
{
const long MByte = 1024 * 1024;
if (val < 1024)
{
return val + " Bytes";
}
else if (val >= 1024 && val < MByte)
{
return val / 1024 + " KBytes";
}
else
{
return Math.Round((double)(val) / MByte, 2) + " MBytes";
}
}
private void ClosingEvent(object sender, System.ComponentModel.CancelEventArgs e)
{
if (working)
e.Cancel = true;
}
#endregion
#region ==== Thread to Locate Files
bool working = false;
bool isScanDone = false;
bool cancel = false;
Queue InfoQueue = new Queue();
Thread thread;
Timer timer;
ArrayList subDirList;
ArrayList extList;
ArrayList patternList;
ArrayList excludeList;
ArrayList neverList;
Dictionary<string, string> key_why = new Dictionary<string, string>();
/// <summary>
/// Scan folders and isolated those matching filters.
/// </summary>
private void LocateFiles(object sender, System.EventArgs e)
{
subDirList = new ArrayList();
extList = new ArrayList();
patternList = new ArrayList();
excludeList = new ArrayList();
neverList = new ArrayList();
ThreadWorking(false);
// Separate filters into four types, exclude, directory, extension or wildcards
//
// Syntax Description Examples
// -xxxxx Exclude pattern -*.exe or -*sdk/
// xxxxx/ Directory name bin/ or Release/
// .xxx File extension .obj or .suo
// xxxx wildcard connect*.xml
//
foreach (ListViewItem item in this.filterList)
{
string action = item.SubItems[1].Text;
string[] sList = action.Split(';');
foreach (string s in sList)
{
if (s.Length == 0)
continue;
if (s[0] == '-')
{
if (item.Text.ToLower() == "never")
{
neverList.Add(s);
}
else
{
excludeList.Add(s);
key_why.Add(s, item.Text);
}
}
else
{
int n = s.Length;
if (n > 0 && s[n - 1] == '\\')
{
string d = s.TrimEnd('\\');
subDirList.Add(d);
key_why.Add(d, item.Text);
}
else
{
if (s[0] == '.')
extList.Add(s);
else
patternList.Add(s);
key_why.Add(s, item.Text);
}
}
}
}
ThreadWorking(true);
ProgressMon.Visible = true;
ProgressMon.Minimum = 0;
ProgressMon.Maximum = 100;
thread = new Thread(new ThreadStart(scanFilesThread));
thread.Start();
timer = new Timer();
timer.Tick+=new EventHandler(fileScanTimer_Tick);
timer.Interval = 1000;
timer.Enabled = true;
}
private void ThreadWorking(bool w)
{
this.working = w;
this.StopBtn.Enabled = w;
this.ProgressMon.Visible = w;
// Disable a bunch of buttons while working.
this.closeBtn.Enabled = !w;
this.DelFilesBtn.Enabled = !w;
this.exportBtn.Enabled = !w;
if (filesListview.Items.Count == 0)
this.filesListview.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
else
{
this.filesListview.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
this.filesListview.Invalidate();
this.filesListview.AutoResizeColumns(ColumnHeaderAutoResizeStyle.None);
foreach (ColumnHeader colHeader in this.filesListview.Columns)
{
if (colHeader.Width < colHeader.Text.Length * 12)
colHeader.Width = colHeader.Text.Length * 12;
}
}
}
private string errorMsg;
private void scanFilesThread()
{
try
{
errorMsg = string.Empty;
cancel = false;
WalkFolder(this.path);
}
catch (ThreadAbortException e)
{
errorMsg = "Operation cancelled by user";
}
catch (Exception e)
{
errorMsg = "Error ocurred while scanning folders: " + e.Message;
}
finally
{
isScanDone = true;
}
working = false;
}
/// <summary>
/// File Find compare supports simple '*' wildcard pattern.
/// Returns true if pattern matches even if raw text has more characters.
/// </summary>
/// <returns>true for partial match</returns>
private bool WildCompare(string wildStr, int wildOff, string rawStr, int rawOff)
{
while (wildOff != wildStr.Length)
{
if (rawOff == rawStr.Length)
return (wildStr[wildOff] == '*');
if (wildStr[wildOff] == '*')
{
if (wildOff + 1 == wildStr.Length)
return true;
do
{
// Find match with char after '*'
while (rawOff < rawStr.Length &&
char.ToLower(rawStr[rawOff]) != char.ToLower(wildStr[wildOff + 1]))
rawOff++;
if (rawOff < rawStr.Length &&
WildCompare(wildStr, wildOff + 1, rawStr, rawOff))
return true;
++rawOff;
} while (rawOff < rawStr.Length);
if (rawOff >= rawStr.Length)
return (wildStr[wildOff + 1] == '*');
}
else
{
if (char.ToLower(rawStr[rawOff]) != char.ToLower(wildStr[wildOff]))
return false;
if (wildStr.Length == wildOff)
return true;
++rawOff;
}
++wildOff;
}
return true;
}
string Why(string key)
{
string why;
key_why.TryGetValue(key, out why);
return why;
}
const string neverStr = "never";
bool Exclude(string file, string why)
{
foreach (string p in excludeList)
{
if ((Why(p) == why || why == neverStr) &&
WildCompare(p, 1, file, 0))
{
return true;
}
}
return false;
}
long TotalBytes = 0;
long TotalFiles = 0;
public void WalkFolder(string folder)
{
if (this.cancel)
return;
string[] folderParts = folder.Split(Path.DirectorySeparatorChar);
int n = folderParts.Length;
string lastDir = folderParts[n - 1];
// Scan directories for match
foreach (string dir in subDirList)
{
if (lastDir == dir && !Exclude(dir, Why(dir)) )
{
AddFileToList(folder, Why(dir)); // actually adding a directory
AddAllFilesInFolder(folder, Why(dir));
return;
}
}
ArrayList fileList = new ArrayList();
try
{
fileList.AddRange(Directory.GetFiles(folder, "*"));
}
catch { };
// Scan files for match
foreach (string file in fileList)
{
string ext = Path.GetExtension(file);
if (extList.Contains(ext) && !Exclude(file, Why(ext)))
{
AddFileToList(file, Why(ext));
continue;
}
foreach (string p in patternList)
{
if (WildCompare(p, 0, file, 0) && !Exclude(file, Why(p)))
{
AddFileToList(file, Why(p));
break;
}
}
}
string[] directories = Directory.GetDirectories(folder);
foreach (string directory in directories)
{
try
{
WalkFolder(directory);
}
catch (Exception e)
{
Console.Write(e);
}
}
}
public ArrayList GetAllFiles(string path)
{
ArrayList result = new ArrayList();
result.AddRange(Directory.GetFiles(path, "*"));
string[] directories = Directory.GetDirectories(path);
foreach (string directory in directories)
{
result.Add(directory);
result.AddRange(GetAllFiles(directory));
}
return result;
}
private void AddAllFilesInFolder(string path, string why)
{
ArrayList allfiles = GetAllFiles(path);
foreach (string s in allfiles)
{
AddFileToList(s, why);
}
}
private void AddFileToList(string file, string why)
{
foreach (string p in neverList)
{
if (WildCompare(p, 1, file, 0))
return;
}
lock(InfoQueue.SyncRoot)
{
FileWhy fw = new FileWhy();
fw.file = file;
fw.why = why;
InfoQueue.Enqueue(fw);
}
}
class FileWhy
{
public string file;
public string why;
};
/// <summary>
/// Copy background files into foreground ListView
/// </summary>
private void fileScanTimer_Tick(object sender, EventArgs e)
{
ProgressMon.Value = (ProgressMon.Value + 1) % 100;
lock(InfoQueue.SyncRoot)
{
this.filesListview.BeginUpdate();
while (InfoQueue.Count > 0)
{
//get the string info
FileWhy fw = InfoQueue.Dequeue() as FileWhy;
//create the listviewitem
ListViewItem item = filesListview.Items.Add(fw.why);
item.Tag = fw.file;
item.SubItems.Add(Path.GetDirectoryName(fw.file));
item.SubItems.Add(Path.GetFileName(fw.file));
item.SubItems.Add(Path.GetExtension(fw.file));
try
{
FileInfo info = new FileInfo(fw.file);
TotalBytes += info.Length;
item.SubItems.Add(info.Length.ToString());
}
catch (Exception e1)
{
try
{
DirectoryInfo info = new DirectoryInfo(fw.file);
if (info.Exists)
{
// Directory item
item.SubItems.Add("dir");
item.BackColor = Color.LightBlue;
}
}
catch
{
// Unknown file object
item.ForeColor = Color.Red;
item.SubItems.Add(e1.Message);
}
}
TotalFiles++;
if (maxFileList > 0 && TotalFiles >= maxFileList)
{
item = filesListview.Items.Add("Limit"); // why
item.ForeColor = Color.Red;
item.Tag = string.Empty;
item.SubItems.Add("File Limit reached, see options menu");
item.SubItems.Add(""); // file
item.SubItems.Add(""); // ext
item.SubItems.Add(""); // size
item.SubItems.Add(""); // status
stopBtn_Click(null, EventArgs.Empty);
break;
}
totalBytesLabel.Text = FormatSize(TotalBytes);
totalFilesLabel.Text = TotalFiles.ToString();
}
this.filesListview.EndUpdate();
}
if (!working)
{
ThreadWorking(working);
timer.Stop();
if (isScanDone)
{
if (errorMsg.Length != 0)
{
bool isError = errorMsg.StartsWith("Error");
MessageBox.Show(errorMsg, isError ? "Error" : "Info",
MessageBoxButtons.OK,
isError ? MessageBoxIcon.Error : MessageBoxIcon.Information);
}
if (TotalFiles > 0)
{
DelFilesBtn.Enabled = true;
}
else
{
isScanDone = false;
MessageBox.Show(this, "There are no files to be deleted on this folder", "Ups!");
this.Close();
}
}
}
}
// Stop action (background thread or foreground deletion)
private void stopBtn_Click(object sender, System.EventArgs e)
{
cancel = true;
// if (thread.IsAlive)
// thread.Abort();
// timer.Enabled = false;
}
#endregion
#region ==== Delete file methods
private void deleteBtn_Click(object sender, System.EventArgs e)
{
string msg = string.Format("You are about to delete {0} files and free up {1} of space, do you want to proceed?",
TotalFiles,FormatSize(TotalBytes));
if (DialogResult.Yes !=
MessageBox.Show(this, msg, "Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
return;
ThreadWorking(true);
cancel = false;
DelFilesBtn.Enabled = false;
ProgressMon.Minimum = 0;
ProgressMon.Maximum = filesListview.Items.Count + 1;
DeleteFiles(false);
ThreadWorking(false);
}
private void DeleteFiles(bool onlySelected)
{
try
{
bool anyDir = false;
// Delete files.
foreach (ListViewItem item in filesListview.Items)
{
if (onlySelected && filesListview.SelectedItems.Contains(item) == false)
continue;
// Allow window event such as pressing cancel button to get processed.
Application.DoEvents();
ProgressMon.Value = (ProgressMon.Value + 1) % ProgressMon.Maximum;
if (cancel)
return;
try
{
if (item.SubItems[4].Text != "dir")
{
File.Delete(item.Tag as string);
RemoveFileFromList(item);
}
else
anyDir = true;
}
catch (Exception e)
{
// Failed to delete file, maybe in use or protected.
item.ForeColor = Color.Red;
item.SubItems.Add(e.Message);
}
}
if (anyDir)
{
// sort by directory name in decending order
ListViewColumnSorter sorter = this.filesListview.ListViewItemSorter as ListViewColumnSorter;
sorter.Order = SortOrder.Descending;
sorter.SortColumn = 1; // directory column
this.filesListview.Sort();
// Delete Directories
foreach (ListViewItem item in filesListview.Items)
{
if (onlySelected && filesListview.SelectedItems.Contains(item) == false)
continue;
// Allow window event such as pressing cancel button to get processed.
Application.DoEvents();
ProgressMon.Value = (ProgressMon.Value + 1) % ProgressMon.Maximum;
if (cancel)
return;
try
{
if (item.SubItems[4].Text == "dir")
{
Directory.Delete(item.Tag as string);
RemoveFileFromList(item);
}
}
catch (Exception e)
{
// Failed to delete file, maybe in use or protected.
item.ForeColor = Color.Red;
item.SubItems.Add(e.Message);
}
}
}
}
finally
{
ThreadWorking(false);
if (cancel || filesListview.Items.Count > 0)
{
DelFilesBtn.Enabled = true;
ProgressMon.Visible = false;
ProgressMon.Minimum = 0;
ProgressMon.Maximum = filesListview.Items.Count + 1;
}
else
{
infoLbl.Text = "Done deleting files";
}
}
}
#region ==== Context popup menu items
private void RemoveFileFromList(ListViewItem item)
{
TotalFiles--;
try
{
if (item.SubItems[4].Text != null)
TotalBytes -= int.Parse(item.SubItems[4].Text);
}
catch { }
totalBytesLabel.Text = FormatSize(TotalBytes);
totalFilesLabel.Text = TotalFiles.ToString();
filesListview.Items.Remove(item);
}
private void RemoveMenuItem_Click(object sender, System.EventArgs e)
{
foreach (ListViewItem item in filesListview.SelectedItems)
{
RemoveFileFromList(item);
}
}
private void RemoveInvMenuItem_Click(object sender, EventArgs e)
{
if (filesListview.SelectedItems.Count != 0)
{
foreach (ListViewItem item in filesListview.Items)
{
if (filesListview.SelectedItems.Contains(item) == false)
{
RemoveFileFromList(item);
}
}
}
}
private void DeleteNowMenuItem_Click(object sender, EventArgs e)
{
DeleteFiles(true);
}
private void LaunchExplorer_Click(object sender, EventArgs e)
{
if (filesListview.SelectedItems.Count != 0)
{
ListViewItem item = filesListview.SelectedItems[0];
string dir = Path.GetDirectoryName(item.Tag as string);
System.Diagnostics.Process.Start("explorer.exe", dir);
}
}
private void LaunchCmd_Click(object sender, EventArgs e)
{
if (filesListview.SelectedItems.Count != 0)
{
ListViewItem item = filesListview.SelectedItems[0];
string dir = Path.GetDirectoryName(item.Tag as string);
System.Diagnostics.Process.Start("cmd.exe", "/k cd \"" + dir + "\"");
}
}
#endregion
private void filesListview_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
RemoveMenuItem_Click(null, null);
else if (e.KeyCode == Keys.A && e.Modifiers == Keys.Control)
{
foreach (ListViewItem item in filesListview.Items)
{
item.Selected = true;
}
}
}
#endregion
/// <summary>
/// Column header click fires sort.
/// </summary>
private void ColumnClick(object sender, ColumnClickEventArgs e)
{
ListView listView = sender as ListView;
ListViewColumnSorter sorter = listView.ListViewItemSorter as ListViewColumnSorter;
// Determine if clicked column is already the column that is being sorted.
if (e.Column == sorter.SortColumn)
{
// Reverse the current sort direction for this column.
if (sorter.Order == SortOrder.Ascending)
sorter.Order = SortOrder.Descending;
else
sorter.Order = SortOrder.Ascending;
}
else
{
// Set the column number that is to be sorted; default to ascending.
sorter.SortColumn = e.Column;
sorter.Order = SortOrder.Ascending;
}
// Perform the sort with these new sort options.
if (listView != null)
listView.Sort();
}
/// <summary>
/// Save ListView contents in as a CSV file.
/// </summary>
private void exportBtn_Click(object sender, EventArgs e)
{
if (filesListview == null || filesListview.Items.Count == 0)
return;
if (this.exportCsvDialog.ShowDialog() == DialogResult.OK)
{
String filePath = this.exportCsvDialog.FileName;
TextWriter writer = new StreamWriter(filePath);
string txtLine = string.Empty;
foreach (ColumnHeader ch in filesListview.Columns)
{
if (txtLine.Length != 0)
txtLine += ",";
txtLine += ch.Text;
}
writer.WriteLine(txtLine);
foreach (ListViewItem item in filesListview.Items)
{
txtLine = string.Empty;
foreach (ListViewItem.ListViewSubItem subItem in item.SubItems)
{
if (txtLine.Length != 0)
txtLine += ",";
txtLine += subItem.Text.Replace(',', ';');
}
writer.WriteLine(txtLine);
}
writer.Close();
infoLbl.Text = "Saved list to file:" + filePath;
}
}
private void closeBtn_Click(object sender, EventArgs e)
{
this.Close();
}
bool isSearching = false;
bool stopSearch = false;
private void selFilterBox_TextChanged(object sender, EventArgs e)
{
string[] searchList = selFilterBox.Text.Split(';');
stopSearch = true;
while (isSearching)
Application.DoEvents();
filesListview.SelectedItems.Clear();
filesListview.BeginUpdate();
isSearching = true;
stopSearch = false;
foreach (string searchFor in searchList)
{
if (stopSearch)
break;
foreach (ListViewItem item in filesListview.Items)
{
if (stopSearch)
break;
bool foundIt = false;
foreach (ListViewItem.ListViewSubItem subItem in item.SubItems)
{
if (subItem.Text.Length != 0 &&
(foundIt = WildCompare(searchFor, 0, subItem.Text, 0)))
{
break;
}
}
if (foundIt)
{
item.Selected = true;
}
}
}
filesListview.EndUpdate();
isSearching = false;
}
}
}