2023年12月30日发(作者:)

用Visual C++实现改变指定的文件和文件夹的属性

---- 一、应用的API函数

---- 1、API中的文件函数组提供了文件读写、属性设置的众多API函数,在本

编码中用到的该函数组中的函数有:

HANDLE CreateFile( LPCTSTR, DWORD,

DWORD,LPSECURITY_ATTRIBUTES,

DWORD,DWORD,HANDLE );

---- 该函数产生或者打开一个系统对象,并返回一个用以访问该对象的句柄,

这些对象可以是文件、文件夹、管道等。

HANDLE FindFirstFile

( LPCTSTR, LPWIN32_FIND_DATA );

该函数在指定目录寻找

与指定文件名匹配的文件和文件夹,

并返回一个查询句柄。

BOOL FindNextFile

( HANDLE,

LPWIN32_FIND_DATA );

该函数继续一

个由查询句柄指定的查询过程。

BOOL FindClose( HANDLE );

该函数关闭指定的查询句柄,

结束指定的查询。

DWORD GetFileAttributes

( LPCTSTR );

该函数检取指定的

文件的属性信息。

BOOL SetFileAttributes

( LPCTSTR,DWORD );

该函数设置指定的

文件的属性信息。

---- 2、API中的时间函数组提供了有关时间转换的众多API函数,在本编码中

用到的该函数组中的函数有:

BOOL SystemTimeToFileTime

( CONST SYSTEMTIME *,LPFILETIME );

该函数将系统时间转换成文件时间,

文件时间是一个64位长度的数,

表示从1601年

1月1日起的时间偏移,

以千万分之一秒为单位。

BOOL LocalFileTime

ToFileTime(

CONST FILETIME *,LPFILETIME );

该函数将本时区的

文件时间转换成格林威治

时间的文件时间。

BOOL SetFileTime

( HANDLE,CONST FILETIME

*,CONST FILETIME *,

CONST FILETIME * );

该函数设置文件产

生修改和访问的时间。

---- 二、编码实现

---- 1、首先建立一个基于对话框的工程,在对话框窗体中放置以下控制并通

过类管理向导为这些控制添加适当变量:

文件名编辑框,输入要改变的文件的全路径,文件名中可以有通配符*和?。

变量类型CString,名称m_FILENAME;

修改包括子目录文件的检查框,变量类型BOOL,名称m_DIRECTORY;

修改文件访问时间检查框,变量类型BOOL,名称m_ACCESS;

文件访问时间日编辑框,变量类型BOOL,名称m_ADAY;

文件访问时间月编辑框,变量类型BOOL,名称m_AMONTH;

文件访问时间年编辑框,变量类型BOOL,名称m_AYEAR;

修改文件产生时间检查框,变量类型BOOL,名称m_CREATE;

文件产生时间日编辑框,变量类型BOOL,名称m_CDAY;

文件产生时间时编辑框,变量类型BOOL,名称m_CHOUR;

文件产生时间分编辑框,变量类型BOOL,名称m_CMINUTE;

文件产生时间月编辑框,变量类型BOOL,名称m_CMONTH;

文件产生时间秒编辑框,变量类型BOOL,名称m_CSECOND;

文件产生时间年编辑框,变量类型BOOL,名称m_CYEAR;

修改文件修改时间检查框,变量类型BOOL,名称m_MODIFY;

文件修改时间日编辑框,变量类型BOOL,名称m_MDAY;

文件修改时间时编辑框,变量类型BOOL,名称m_MHOUR;

文件修改时间分编辑框,变量类型BOOL,名称m_MMINUTE;

文件修改时间月编辑框,变量类型BOOL,名称m_MMONTH;

文件修改时间秒编辑框,变量类型BOOL,名称m_MSECOND;

文件修改时间年编辑框,变量类型BOOL,名称m_MYEAR;

修改文件属性检查框,变量类型BOOL,名称m_PROPERTY;

文件隐藏属性检查框,变量类型BOOL,名称m_HIDE;

文件只读属性检查框,变量类型BOOL,名称m_READ;

文件存档属性检查框,变量类型BOOL,名称m_SAVE;

文件系统属性检查框,变量类型BOOL,名称m_SYSTEM;

执行更改的按钮,点击该按钮后执行选定的更改操作。

以上成员变量可在对话类的构造函数中用当前系统时间予以初始化。

---- 2、在对话类中加入以下成员:

char filter[16];

intChangeTheProperty

(LPSTR Filename,BYTEbFlag=0) ;

其中成员变量filter用以存放带通配符的文件名。

成员函数ChangeTheProperty中实

现了带通配符的文件的属性的改变,考虑到要遍历子目录,

该函数采用了递归调用,并请注意参数bFlag,其缺省值为0,

1表示调用发生自子目录。其实现如下:

intCChangePropertyDlg::Change

TheProperty(LPSTR FileName,BYTEbFlag)

{

////存放路径

char pathname[MAX_PATH];

////存放全路径文件名

charallname[MAX_PATH];

////初始化pathname

intnum=strlen(FileName);

for(int i=num-1;i>=0;i--){

if(FileName[i]=='')

break;

}

if(i==-1)

return 0;

strncpy(pathname,FileName,i+1);

pathname[i+1]='0';

////查找并修改所有子目录下符合条件的文件

DWORD stat=0;

WIN32_FIND_DATA fileinfo;

if(bFlag){

charDFileName[MAX_PATH];

strcpy(DFileName,pathname);

strcat(DFileName,"*.*");

HANDLE handle=FindFirstFile

(DFileName, &fileinfo);

if(handle==INVALID_HANDLE_VALUE)

return 0;

do{

if(ame[0]=='.')

continue;

strcpy(allname,pathname);

strcat(allname,ame);

//检取文件属性,可以使用

fileinfo的dwFileAttributes成员

stat=GetFileAttributes(allname);

if(stat==0xffffffff){

MessageBox("警告,获取文件信息时出错!!",

allname, MB_OK|MB_ICONINFORMATION);

continue;

}

//如果查询到的是文件夹

if(stat&FILE_ATTRIBUTE_

DIRECTORY &&m_DIRECTORY){

char temp[MAX_PATH];

sprintf(temp,"%s%s%s",

pathname,

ame,filter);

//递归改变该子目录下的文件

ChangeTheProperty(temp,1);

}

}while(FindNextFile

(handle, &fileinfo));

FindClose(handle);

}

////查找并修改符合条件的文件和文件夹

HANDLE handle=FindFirstFile

( FileName, &fileinfo );

if(handle==INVALID_HANDLE_VALUE)

return 0;

do{

if(ame[0]=='.')

continue;

strcpy(allname,pathname);

strcat(allname,ame);

//检取文件属性

stat=GetFileAttributes(allname);

if(stat==0xffffffff){

MessageBox("警告,

获取文件信息时出 错!!",

allname,MB_OK|MB_

ICONINFORMATION);

continue;

}

//设置文件属性

BOOL tt=SetFileAttributes(allname,0);

if(!tt){

MessageBox("警告,

文件信息出错!!",

allname,MB_OK|MB_

ICONINFORMATION);

continue;

}

HANDLE hd=CreateFile(allname,

GENERIC_WRITE, FILE_SHARE_WRITE,

NULL,OPEN_EXISTING,

FILE_FLAG_BACKUP_SEMANTICS,NULL);

if(hd!=INVALID_HANDLE_VALUE){

SYSTEMTIME st[3];

GetLocalTime(&st[0]);

st[1]=st[0];st[2]=st[0];

FILETIME ft[3];

FILETIME lft[3];

BYTE ff[3];

ff[0]=0;ff[1]=0;ff[2]=0;

//改变文件访问时间

if(m_ACCESS){

ff[0]=1;

st[0].wDay =m_ADAY;st[0].

wMonth=m_AMONTH;

st[0].wYear=m_AYEAR;

BOOL bb=SystemTime

ToFileTime(&st[0],&ft[0]);

bb=LocalFileTime

oFileTime(&ft[0],&lft[0]);

}

//改变文件产生时间

if(m_CREATE){

ff[1]=1;

st[1].wDay=m_CDAY;st[1].

wHour=m_CHOUR;st[1].

wMinute=m_CMINUTE;

st[1].wMonth=m_

CMONTH;st[1].

wSecond=m_CSECOND;

st[1].wYear=m_CYEAR;

BOOL bb=SystemTime

ToFileTime(&st[1],&ft[1]);

bb=LocalFileTime

ToFileTime(&ft[1],&lft[1]);

}

//改变文件修改时间

if(m_MODIFY){

ff[2]=1;

st[2].wDay=m_MDAY;st[2].

wHour=m_MHOUR;st[2].

wMinute=m_MMINUTE;

st[2].wMonth=m_MMONTH

;st[2].

wSecond=m_MSECOND;

st[2].wYear=m_MYEAR;

BOOL bb=System

TimeToFileTime(&st[2],&ft[2]);

bb=LocalFileTime

ToFileTime(&ft[2],&lft[2]);

}

//改变文件时间

BOOL tt=SetFile

Time(hd,ff[1]?&lft[1]:

NULL,ff[0]?&lft[0]:

NULL,ff[2]?&lft[2]:NULL);

if(!tt){

MessageBox("警告,文件信息出错!!",

allname,MB_OK|MB_ICONINFORMATION);

}

CloseHandle(hd);

}

//改变文件属性

if(m_PROPERTY){

if(m_HIDE)

stat|=FILE_

ATTRIBUTE_HIDDEN;

else

stat&=~FILE_

ATTRIBUTE_HIDDEN;

if(m_READ)

stat|=FILE_

ATTRIBUTE_READONLY;

else

stat&=~FILE_

ATTRIBUTE_READONLY;

if(m_SAVE)

stat|=FILE_

ATTRIBUTE_ARCHIVE;

else

stat&=~FILE_

ATTRIBUTE_ARCHIVE;

if(m_SYSTEM)

stat|=FILE_

ATTRIBUTE_SYSTEM;

else

stat&=~FILE_

ATTRIBUTE_SYSTEM;

}

//设置文件属性

tt=SetFileAttributes(allname,stat);

if(!tt){

MessageBox("警告,

文件信息出错!!",allname,

MB_OK|MB_

ICONINFORMATION);

continue;

}

//查找并修改当前目录

下所有符合条件的文件

if(stat&FILE_

ATTRIBUTE_DIRECTORY

&& !bFlag){//m_DIRECTORY

char temp[128];

sprintf(temp,"%s%s%s",

pathname,ame,filter);

//递归改变该子目录下的文件

ChangeTheProperty(temp,1);

continue;

}

}while(FindNextFile( handle, &fileinfo ));

FindClose(handle);

return 1;

}

---- 3、在执行更改的按钮的BN_CLICKED消息处理器中加入以下代码,这段代码

首先解析了输入的文件名全路径,并初始化了filter成员变量:

UpdateData(TRUE);

intnum=m_gth();

for(int i=num-1;i>=0;i--){

if(m_(i)=='')

break;

}

if(i!=-1){

CStringss=m_( num-1-i );

strcpy(filter,fer(15) );

eBuffer();

ChangeTheProperty

( m_fer(128)) ;

m_eBuffer();

}

---- 4、编译连接后,在文件名编辑框中输入要改变的文件的带通配符的全路径,

设置文件的创建修改访问时间以及只读隐藏等属性,点击该按钮后执行选定的更

改操作。

---- 三、本编码在NT4.0平台,用VC++6.0编译,效果良好,符合预期。