C++技术网会员解答:
您好,感谢您对C++技术网的支持与信任。
不管是win7还是win10,对于系统目录C:\Windows\System32都是有严格的权限限制的。如果要在系统目录操作文件,就需要做权限处理。
权限分为两种,一种是运行的程序本身应该拥有管理员权限,另一种是系统目录下的文件必须允许当前操作的用户有对应的操作权限。第一种权限可以让你去修改文件权限。所以对于系统目录的操作,你需要使用管理员权限运行。一般来说,系统文件并不是Administrator拥有,所以Administrators用户组下的管理员只是有读取和执行的权限,如下图所示:
所以,尽管你是管理员用户组的用户,你依然不能直接修改、删除、替换系统目录里的文件。不过你是管理员用户,你就可以修改系统目录里的文件的权限,让你这个用户拥有写入权限或者更多权限。如果你只是单次操作,你可以手动在上图界面中点击编辑,就可以勾选需要的权限,然后保存即可。如果你想用程序修改权限,那么就需要费一番功夫了。
用程序修改系统目录里的文件的权限,首先得让程序有管理员权限。所以需要先以管理员权限运行。否则都无法修改文件权限,更别想修改文件或者删除文件了。然后,通过获取文件权限的访问控制列表,然后将当前管理员用户添加到访问控制列表里,然后将这个访问控制列表设置会文件权限,这样就将管理员的需要的访问权限设置到了文件权限。设置文件访问权限成功后,就可以自由操作文件了。不过需要注意的是,系统目录的文件不要轻易操作,以免造成系统不稳定。
在VC中操作文件的权限,我们可以使用下面的API函数:
GetNamedSecurityInfo : 获取文件(夹)安全对象的DACL列表
BuildExplicitAccessWithName : 生成指定用户帐户的访问控制信息(这里指定赋予全部的访问权限)
SetEntriesInAcl : 创建新的ACL对象(合并已有的ACL对象和刚生成的用户帐户访问控制信息)
SetNamedSecurityInfo :设置文件(夹)安全对象的DACL列表
这些函数的声明头文件是:Aclapi.h
需要的库是:Advapi32.lib 或 Advapi32.dll
可以这样快捷导入lib库:
#pragma comment(lib,"Advapi32.lib")
VC修改文件目录的访问权限的代码如下:
BOOL EnableFileAccountPrivilege (PCTSTR pszPath, PCTSTR pszAccount)
{
BOOL bSuccess = TRUE;
PACL pNewDacl = NULL, pOldDacl = NULL;
EXPLICIT_ACCESS ea;
do
{
// 获取文件(夹)安全对象的DACL列表
if (ERROR_SUCCESS != ::GetNamedSecurityInfo ((LPTSTR)pszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDacl, NULL, NULL))
{
bSuccess = FALSE;
break;
}
// 此处不可直接用AddAccessAllowedAce函数,因为已有的DACL长度是固定,必须重新创建一个DACL对象
// 生成指定用户帐户的访问控制信息(这里指定赋予全部的访问权限)
::BuildExplicitAccessWithName (&ea, (LPTSTR)pszAccount,GENERIC_WRITE /*GENERIC_ALL*/, GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT);
// 创建新的ACL对象(合并已有的ACL对象和刚生成的用户帐户访问控制信息)
if (ERROR_SUCCESS != ::SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl))
{
bSuccess = FALSE;
break;
}
// 设置文件(夹)安全对象的DACL列表
int ERR = ::SetNamedSecurityInfo ((LPTSTR)pszPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);
if (ERROR_SUCCESS != ERR)
{
CString str;
str.Format(_T("错误码:%d"),ERR);
MessageBox(0,str,str,0);
bSuccess = FALSE;
}
} while (FALSE);
// 释放资源
if (pNewDacl != NULL)
::LocalFree(pNewDacl);
return bSuccess;
}
SetNamedSecurityInfo函数在设置文件权限的时候,可能会失败,错误码为5,意思是拒绝访问。请自己查询资料深入调查问题的原因,不同的系统的安全限制都不太一样。请自己深入学习Windows系统的安全权限编程知识,这个知识是非常复杂的,并不能一蹴而就。特别是win8、win10,对权限要求越来越高,更容易出现权限操作失败的情况。