Introduction
Recently, I came across an application called "BulkFileModifier
" from nirsoft which is able to change attributes of files and folders. I wanted to know how it works so I developed one of my own. Also, this is an update to my previous release, which modified attributes of files only. Now the program can modify attributes of folders also. I added the option to scan directories recursively, i.e., now you can modify the attributes of all the files and folders inside the directory at once! I also added the option to drag and drop files directly on the program.
Using the Code
To create this program, I added System.IO namespace
. The namespace contains classes to read information from files and folders.
The Main
form uses datagridview
which will contain the file path.
GroupBox
control contains radiobuttons
to change option of changing attributes of files and folders within.
checkbox
and DateTimePicker
to change file attributes.
public partial class FileAttributeChanger : Form
{
DataTable dt = new DataTable();
DataRow dr;
string filename = "";
public FileAttributeChanger()
{
InitializeComponent();
dt.Columns.Add(new DataColumn("Name", typeof(string)));
dt.Columns.Add(new DataColumn("Type", typeof(string)));
dt.Columns.Add(new DataColumn("Path", typeof(string)));
}
...
Adding Files to the Form
To add files to datagrid
view, you can select one or more than one file. Note that all the files added to datagridview
will have the same attributes after you change its attribute. If you want to remove any file from the view, then just click the row and press the "Delete" button on your keyboard. To remove all files from datagridview
, click the "Clearlist" button.
private void btn_AddFiles_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = true;
ofd.ShowDialog();
foreach (string file in ofd.FileNames)
{
dr = dt.NewRow();
FileInfo fi = new FileInfo(file);
dr[0] = fi.Name;
dr[1] = "File";
dr[2] = file;
dt.Rows.Add(dr);
dgv_filescollection.DataSource = dt;
dgv_filescollection.Focus();
}
}
...
Adding Folders to datagridview
Adding folders to the form is similar to adding files. The difference is that you cannot add multiple folders at the same time.
private void btn_addfolder_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
fbd.ShowNewFolderButton = false;
fbd.ShowDialog();
if (fbd.SelectedPath != "")
{
if (Directory.Exists(fbd.SelectedPath))
{
DirectoryInfo di = new DirectoryInfo(fbd.SelectedPath);
dr = dt.NewRow();
dr[0] = di.Name;
dr[1] = "Directory";
dr[2] = di.FullName;
dt.Rows.Add(dr);
dgv_filescollection.DataSource = dt;
dgv_filescollection.Focus();
}
}
}
...
Get Current File Attributes
When files are added to datagridview
, the dgv_filescollection_RowEnter
event below will get the current file or folder name. The current name (i.e., full path of file is passed as a parameter to a user function checkattributes
. The File.GetAttributes
method will retrieve all the attributes of the file and will be passed as a string
. The Contains(Attribute name)
will check whether the file has Archive
, Readonly
properties or not. If any attribute is present, then the checkbox corresponding to it will be checked. Also with change in selected filename in datagridview
, the checkbox
es will be unchecked. This is necessary otherwise it will show attributes of the previous file or folder also. To see all the attributes of the file at once, add a message box inside the checkattribs
function and type MessageBox.Show(Fileattributes);
private void dgv_filescollection_RowEnter
(object sender, DataGridViewCellEventArgs e)
{
filename = dgv_filescollection.Rows[e.RowIndex].Cells[2].Value.ToString();
string gettype =
dgv_filescollection.Rows[e.RowIndex].Cells[1].Value.ToString();
clearCheckBox();
checkattribs(filename,gettype);
}
private void clearCheckBox()
{
foreach (CheckBox cbx in gbx_attributes.Controls)
{
if (cbx.Checked == true)
{
cbx.Checked = false;
}
}
chk_ChangeCreatedDate.Checked = false;
chk_ChangeModifiedDate.Checked = false;
chk_ChangeAccessedDate.Checked = false;
}
private void checkattribs(string currentfile,string type)
{
try
{
String attributes = "";
if (type == "File")
{
dtp_creationdate.Value = File.GetCreationTime(currentfile);
dtp_modifieddate.Value = File.GetLastWriteTime(currentfile);
dtp_accesseddate.Value = File.GetLastAccessTime(currentfile);
attributes = File.GetAttributes(currentfile).ToString();
}
else if (type == "Directory")
{
DirectoryInfo di = new DirectoryInfo(currentfile);
dtp_creationdate.Value = di.CreationTime;
dtp_modifieddate.Value = di.LastWriteTime;
dtp_accesseddate.Value = di.LastAccessTime;
attributes = di.Attributes.ToString();
}
if (attributes.Contains("Archive") == true)
{
chk_archive.CheckState = CheckState.Checked;
}
if (attributes.Contains("Compressed"))
{
chk_compressed.Checked = true;
}
.....
....
dtp_creationdate.Value = File.GetCreationTime(currentfile);
dtp_modifieddate.Value = File.GetLastWriteTime(currentfile);
dtp_accesseddate.Value = File.GetLastAccessTime(currentfile);
}
...
Dragging and Dropping Files and Folders
To drag and drop files and folders, we need to make use of the dragevents
handler. The form has a DragEnter
event handler. To allow dropping files onto form, we need to set AllowDrop
property to true
. On dragging over file to form, it will show cursor drageffects of copy operation(i.e., mouse pointer with + symbol). To add files and folders that have been dragged over, we use dragdrop
event of the form. If one or many files are selected, then all the files will be stored in a string
array after they have been dropped. The foreach
loop will retrieve all the file and folder names that had been dragged over and then it will be added to datagridview
. More Information about dragdrop can be found at this link.
private void FileAttributeChanger_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
this.AllowDrop = true;
}
private void FileAttributeChanger_DragDrop(object sender, DragEventArgs e)
{
string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
foreach (string file in FileList)
{
if (File.GetAttributes(file).ToString().Contains("Directory"))
{
DirectoryInfo di = new DirectoryInfo(file);
dr = dt.NewRow();
dr[0] = di.Name;
dr[1] = "Directory";
dr[2] = di.FullName;
dt.Rows.Add(dr);
}
else
{
dr = dt.NewRow();
FileInfo fi = new FileInfo(file);
dr[0] = fi.Name;
dr[1] = "File";
dr[2] = file;
dt.Rows.Add(dr);
}
}
dgv_filescollection.DataSource = dt;
dgv_filescollection.Focus();
}
Finally...
Once the files whose attributes are to be changed are added to the Datagridview
, check or uncheck the current attributes of the file. (Note: All the files added to the datagridview
will have the same attributes once the ChangeAttributes
button is pressed). If the file is checked to be set as ReadOnly
or System
, then before doing so, attribute of file will be set to normal
(one that has no attributes set). If you don't want to change the current attribute, leave it checked. To change the attribute of folders, one is presented with the option of changing either the attribute of current folder only or all the folders and files within the folder. If the option of applying changes to folder, subfolders and files is selected, then the folder is scanned recursively. This is made by making use of searchoption enum
. The searchoption
allows searching files or folders in topdirectory
or alldirectories
. Here, since we have checked all subdirectories, it will scan recursively and get information about files and folders using directoryinfo
or fileinfo
class. If only the attributes for the directory are to be set, then click "Apply Changes to Folder only" radiobutton .
private void btn_ChangeAttribs_Click(object sender, EventArgs e)
{
string type ="";
foreach (DataGridViewRow dgvr in dgv_filescollection.Rows)
{
try
{
filename = dgvr.Cells[2].Value.ToString();
type = dgvr.Cells[1].Value.ToString();
File.SetAttributes(filename, FileAttributes.Normal);
if (type == "File")
{
if (dtp_creationdate.Enabled)
File.SetCreationTime(filename, dtp_creationdate.Value);
if (dtp_modifieddate.Enabled)
File.SetLastWriteTime(filename, dtp_modifieddate.Value);
if (dtp_accesseddate.Enabled)
File.SetLastAccessTime(filename, dtp_accesseddate.Value);
ChangeFileAttributes(filename);
}
else if (rbtn_changestoall.Checked == true && type == "Directory")
{
DirectoryInfo di = new DirectoryInfo(filename);
foreach (FileInfo files in di.GetFiles
("*.*", SearchOption.AllDirectories))
{
File.SetAttributes(files.FullName, FileAttributes.Normal);
if (dtp_creationdate.Enabled)
File.SetCreationTime
(files.FullName, dtp_creationdate.Value);
if (dtp_modifieddate.Enabled)
File.SetLastWriteTime
(files.FullName, dtp_modifieddate.Value);
if (dtp_accesseddate.Enabled)
File.SetLastAccessTime(files.FullName,
dtp_accesseddate.Value);
ChangeFileAttributes(files.FullName);
}
foreach (DirectoryInfo dinfo in di.GetDirectories
("*.*", SearchOption.AllDirectories))
{
File.SetAttributes(dinfo.FullName, FileAttributes.Normal);
if (dtp_creationdate.Enabled)
Directory.SetCreationTime
(dinfo.FullName, dtp_creationdate.Value);
if (dtp_modifieddate.Enabled)
Directory.SetLastWriteTime
(dinfo.FullName, dtp_modifieddate.Value);
if (dtp_accesseddate.Enabled)
Directory.SetLastAccessTime
(dinfo.FullName, dtp_accesseddate.Value);
ChangeFileAttributes(dinfo.FullName);
}
if (dtp_creationdate.Enabled)
Directory.SetCreationTime(di.FullName, dtp_creationdate.Value);
....
...
}
else if (rbtn_folderonly.Checked == true && type == "Directory")
{
if (dtp_creationdate.Enabled)
Directory.SetCreationTime(filename, dtp_creationdate.Value);
if (dtp_modifieddate.Enabled)
Directory.SetLastWriteTime(filename, dtp_modifieddate.Value);
....
private void ChangeFileAttributes(string fname)
{
if (chk_archive.Checked == true &&
File.GetAttributes(fname).ToString().Contains("Archive") == false)
File.SetAttributes(fname, File.GetAttributes(fname) |
FileAttributes.Archive);
else if (chk_archive.Checked == false &&
File.GetAttributes(fname).ToString().Contains("Archive"))
File.SetAttributes(fname, File.GetAttributes(fname) &
~FileAttributes.Archive);
if (chk_hidden.Checked == true &&
File.GetAttributes(fname).ToString().Contains("Hidden") == false)
File.SetAttributes(fname,
File.GetAttributes(fname) | FileAttributes.Hidden);
else if (chk_hidden.Checked == false &&
File.GetAttributes(fname).ToString().Contains("Hidden"))
File.SetAttributes(fname, File.GetAttributes(fname) &
~FileAttributes.Hidden);
...
}
After changing attributes, reload the same files and check their current properties:
Conclusion
In my initial release, I had released the project with very minimal features. Thanks to the recommendations of CodeProject users, I have now made it a full fledged project which now changes folder attributes, and allows dragdrop files and folders. Please let me know if you like my project so that I may plan for another release.
History
- 20th July, 2011
25th July, 2011
- Added option to add folders
- Added option to scan folders recursively
- Added
DragDrop
feature - Updated source and article and added demo project