Introduction
I recently downloaded a project of 23 files which all had the readonly attribute set. Not wanting to change all 23 files manually I came up with this simple utility.
Background
CFileFind
has a few members to test for
IsDirectory()
,
IsDots()
etc. I needed to Set or Reset the file attribute which can only be done using
System::IO
Using the Code
The project has to be compiled with Common Language Runtime Support (/clr option). /clr can't be used with /MD or /MT, they have to be cleared from the project properties page.
The default starting directory is C:\Temp
copy your files there. Or enter a new starting directory.
The following code shows the System usage:
#using <mscorlib.dll>
using namespace System;
using namespace System::IO;
using namespace System::Text;
The following code shows the routine that recursively counts the files:
void CurrentAttribute(String^ Path)
{
CFileFind finder;
String^ filename;
String^ fullpath;
CString szSearch(Path); if (szSearch.Right(1) != _T ("\\"))
szSearch += _T ("\\");
szSearch += _T ("*.*");
BOOL bWorking = finder.FindFile(szSearch);
while (bWorking)
{
bWorking = finder.FindNextFile();
Sleep(1); if(finder.IsDirectory())
{
filename = gcnew String(finder.GetFilePath()); if(!finder.IsDots())
CurrentAttribute(filename);
}
fullpath = gcnew String(finder.GetFilePath()); if((!finder.IsDots()) && (!finder.IsDirectory()))
{
if((File::GetAttributes(fullpath) & FileAttributes::ReadOnly) == FileAttributes::ReadOnly)
{
num++;
}
total++;
}
}
}
The following code shows how the ReadOnly Attribute is Set or Reset:
void Recursive(String^ path, bool bSetAttr)
{
CFileFind finder;
String^ fullpath;
String^ filename;
CString szSearch(path); if (szSearch.Right(1) != _T ("\\"))
szSearch += _T ("\\");
szSearch += _T ("*.*");
BOOL bWorking = finder.FindFile(szSearch);
while (bWorking)
{
bWorking = finder.FindNextFile();
Sleep(2); if(finder.IsDirectory())
{
filename = gcnew String(finder.GetFilePath()); if(!finder.IsDots())
Recursive(filename, bSetAttr);
}
fullpath = gcnew String(finder.GetFilePath()); if((!finder.IsDots()) && (!finder.IsDirectory()))
{
if(bSetAttr)
{
if((File::GetAttributes(fullpath) & FileAttributes::ReadOnly) != FileAttributes::ReadOnly)
{
File::SetAttributes(fullpath, static_cast<FileAttributes>(File::GetAttributes(fullpath) |
FileAttributes::ReadOnly));
Console::WriteLine("The file {0} is now Read Only", fullpath);
}
}
else
{
if((File::GetAttributes(fullpath) & FileAttributes::ReadOnly) == FileAttributes::ReadOnly)
{
File::SetAttributes(fullpath, static_cast<FileAttributes>(File::GetAttributes(fullpath) ^
FileAttributes::ReadOnly));
Console::WriteLine("The file {0} is no longer Read Only", fullpath);
}
}
}
}
}
Points of Interest
The code shows how to convert from
String^
to
CString
and how to convert from
CString
to
String^
History
Version 1.0, October 11, 2011.