Click here to Skip to main content
15,867,906 members
Articles / Programming Languages / C#

File Attribute Changer

Rate me:
Please Sign up or sign in to vote.
5.00/5 (11 votes)
25 Jul 2011CPOL4 min read 51.1K   2.9K   24   14
An Attribute changer which can change attributes of files and folders
FileAttributeChanger

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.

C#
public partial class FileAttributeChanger : Form
    {
        //Initializing new instance of DataTable
        DataTable dt = new DataTable();
        DataRow dr;
        string filename = "";

        public FileAttributeChanger()
        {
            InitializeComponent();
            //Adding a new column name  to datagridview of type string
            //that will show files or folder names , its type and full path
			 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.

C#
        //AddFiles To DatagridView
        private void btn_AddFiles_Click(object sender, EventArgs e)
        {
			OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = true; //Allow multiselection of files
            ofd.ShowDialog();
            //If many files are selected, then all of them will be added to datagridview
                foreach (string file in ofd.FileNames)
                {
                    dr = dt.NewRow();
                    FileInfo fi = new FileInfo(file);
                    dr[0] = fi.Name;
                    dr[1] = "File";
                    dr[2] = file;//Filename will be shown in the first column of all rows
                    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.

C#
        //AddFiles To DatagridView
        private void btn_addfolder_Click(object sender, EventArgs e)
        {
            //show folder browser dialog
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.ShowNewFolderButton = false;
            fbd.ShowDialog();

            //if folder browser dialog box path is not empty
            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();//set focus to datagridview 
		      //so that you can remove files/folders just by pressing "delete"
                }
            }
        }

...

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 checkboxes 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);

C#
//if current row changes then the file name will be changed
        private void dgv_filescollection_RowEnter
		(object sender, DataGridViewCellEventArgs e)
        {
	   //filename is actually the fullpath of file or folder which is obtained by
	   //checking its currentrow and value of the 3rd cell in the current row.
            //The File name will be used to retrieve its attributes
            filename = dgv_filescollection.Rows[e.RowIndex].Cells[2].Value.ToString();
            string gettype = 
		dgv_filescollection.Rows[e.RowIndex].Cells[1].Value.ToString();
            clearCheckBox(); //checkboxes are unchecked everytime row is changed
            checkattribs(filename,gettype); 	//file or folder path and its type 
					//is passed on to check its attributes
        }

		//clear the checkboxes so that current file or folder will 
		//not show attributes of previous one
		private void clearCheckBox()
        {
            //since the groupbox contains only checkboxes, 
	   //hence their checked status can be removed
            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")
                {
                    //Get Dates of file
                    //Show File creation,modified,lastaccess date in datetimepicker
                    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();
                }

                //The File.GetAttributes method retrieves all the attributes of file
                if (attributes.Contains("Archive") == true)
                {
                    chk_archive.CheckState = CheckState.Checked;
                }
                if (attributes.Contains("Compressed"))
				{
                    chk_compressed.Checked = true;
                }
            .....
....

            //Get Dates of file
            //Show File creation,modified,lastaccess date in datetimepicker
            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.

C#
private void FileAttributeChanger_DragOver(object sender, DragEventArgs e)
        {
            //on dragging a file or folder over form, show drageffects of copy operation
            e.Effect = DragDropEffects.Copy;
            this.AllowDrop = true;
        }

        private void FileAttributeChanger_DragDrop(object sender, DragEventArgs e)
        {
	   //get all filenames and store them in string array
            string[] FileList = (string[])e.Data.GetData(DataFormats.FileDrop, false);
            foreach (string file in FileList)
            {
		  //Add Directories to datagridview
                    if (File.GetAttributes(file).ToString().Contains("Directory"))
                    {
                        DirectoryInfo di = new DirectoryInfo(file);
                        dr = dt.NewRow(); 	//create a new datarow
                        dr[0] = di.Name; 	//get the name of directory
                        dr[1] = "Directory"; 	//Type , in this case Directory
                        dr[2] = di.FullName; 	//get full path to that directory
                        dt.Rows.Add(dr);
                    }

		  //This will add each file to datagridview
                    else
                    {
                        dr = dt.NewRow();
                        FileInfo fi = new FileInfo(file);
                        dr[0] = fi.Name; 	//Get file name
                        dr[1] = "File"; 	//store its type, will be used 
					//to distinguish between directory and files
                        dr[2] = file;	//full path of the 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 .

C#
private void btn_ChangeAttribs_Click(object sender, EventArgs e)
{
string type ="";
            foreach (DataGridViewRow dgvr in dgv_filescollection.Rows)
            {
                try
                {
                    //Get Current file name in the datagridview
                    filename = dgvr.Cells[2].Value.ToString();
                    type = dgvr.Cells[1].Value.ToString();

                    //Set File Attributes To normal so that new attributes can be set
                    //This is required because file attributes cannot be 
		  //changed if it is read-only
                    File.SetAttributes(filename, FileAttributes.Normal);

                    if (type == "File")
                    {

                        //change file dates if date time picker for 
		      //creation date is enabled
                        if (dtp_creationdate.Enabled)
                            File.SetCreationTime(filename, dtp_creationdate.Value);

                        //change modified time if date time picker for 
		      //modified time is enabled
                        if (dtp_modifieddate.Enabled)
                            File.SetLastWriteTime(filename, dtp_modifieddate.Value);

                        //change last accessed date if datetime picker for 
		      //last accessed date is enabled
                        if (dtp_accesseddate.Enabled)
                            File.SetLastAccessTime(filename, dtp_accesseddate.Value);

                        ChangeFileAttributes(filename);//pass filename as parameter 
						//to change its attributes
                    }

                        //if Changes to all is enabled and type is directory then all the
                    //files and folders in the directory will have the same attributes
                    else if (rbtn_changestoall.Checked == true && type == "Directory")
                    {
                        //create an instance of DirectoryInfo to
                        //get information about the directory
                        DirectoryInfo di = new DirectoryInfo(filename);

                        //get all the files in the directory with 
		      //searchoption by searching all subdirectories within
                        foreach (FileInfo files in di.GetFiles
				("*.*", SearchOption.AllDirectories))
                        {
                            File.SetAttributes(files.FullName, FileAttributes.Normal);

                            //change file dates if date time picker for 
			 //creation date is enabled
                            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);

                            //pass the full path of file as a parameter 
			 //to change its attributes
                            ChangeFileAttributes(files.FullName);
                        }

                        //get all the directories in the current directory 
		      //by searching all directories within
                        foreach (DirectoryInfo dinfo in di.GetDirectories
				("*.*", SearchOption.AllDirectories))
                        {
                            File.SetAttributes(dinfo.FullName, FileAttributes.Normal);
                            //change creation date of directory if creation date 
			 //is to be changed
                            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);
                        }

                        //change attribute of the directory 
		      //which was added to datagridview also
                        if (dtp_creationdate.Enabled)
                            Directory.SetCreationTime(di.FullName, dtp_creationdate.Value);

			//similarly change modified date and lastwritetime of directory
				....
				...
                    }

                    //if only the attributes of the directory in the datagridview 
		  //is to be changed
                    //and NOT its subdirectories and files
                    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)
        {
            //File class is also able to change attributes of Directory ;)
            //if Archive is checked, then its attribute will be set to archive
            if (chk_archive.Checked == true && 
		File.GetAttributes(fname).ToString().Contains("Archive") == false)
                File.SetAttributes(fname, File.GetAttributes(fname) | 
		FileAttributes.Archive);	// Archive attribute will be added to 
					//its existing attributes

            //if unchecked, then Archive attribute will be removed
            //To remove attribute a tilde(~) is appended before the FileAttributes enum
            else if (chk_archive.Checked == false && 
		File.GetAttributes(fname).ToString().Contains("Archive"))
                File.SetAttributes(fname, File.GetAttributes(fname) & 
					~FileAttributes.Archive);

            //set or unset attribute of file or folder to be hidden
            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);

		//similar code to change system and readonly attributes
		...
}

After changing attributes, reload the same files and check their current properties:

After Changing Attribute

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
    • Initial release
    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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer HP Microsystems
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionthanks Pin
Hooman_Kh23-Sep-16 23:27
Hooman_Kh23-Sep-16 23:27 
QuestionGood coding :) Pin
Khursheed Fateh17-Aug-16 19:27
Khursheed Fateh17-Aug-16 19:27 
GeneralThanks Pin
Albarhami15-Sep-12 20:56
Albarhami15-Sep-12 20:56 
GeneralRe: Thanks Pin
Praveen Kullu27-Sep-12 19:54
Praveen Kullu27-Sep-12 19:54 
GeneralMy vote of 5 Pin
Albarhami15-Sep-12 20:56
Albarhami15-Sep-12 20:56 
GeneralMy vote of 5 Pin
sudhir ranjan20-Apr-12 0:41
sudhir ranjan20-Apr-12 0:41 
Nice
SuggestionNo need to convert enum to string [modified] Pin
pebrian2721-Jul-11 0:06
pebrian2721-Jul-11 0:06 
AnswerRe: No need to convert enum to string Pin
Praveen Kullu21-Jul-11 0:39
Praveen Kullu21-Jul-11 0:39 
QuestionNice article. Pin
thompsons20-Jul-11 9:33
thompsons20-Jul-11 9:33 
AnswerRe: Nice article. Pin
Praveen Kullu20-Jul-11 15:30
Praveen Kullu20-Jul-11 15:30 
GeneralMy vote of 1 Pin
Skif20-Jul-11 6:23
Skif20-Jul-11 6:23 
GeneralRe: My vote of 1 Pin
Praveen Kullu20-Jul-11 8:17
Praveen Kullu20-Jul-11 8:17 
GeneralRe: My vote of 1 Pin
Skif20-Jul-11 12:00
Skif20-Jul-11 12:00 
GeneralRe: My vote of 1 Pin
Praveen Kullu20-Jul-11 15:15
Praveen Kullu20-Jul-11 15:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.