Windows 下重置用户访问权限





5.00/5 (1投票)
一个重置 Windows 用户访问权限的命令行程序
引言
自从 Windows Vista 引入用户帐户控制 (UAC) 以来,对某些系统文件夹的访问受到了限制。除非具有管理员权限,否则不允许修改这些文件夹。虽然 UAC 对于安全性至关重要,但在某些情况下,我们希望授予用户对某些文件夹的完全访问权限(例如 C:\ProgramData\[CompanyName]\[AppName],尽管微软不推荐这样做)。这个简单的命令行程序旨在处理这个问题。
详细说明
要重置访问权限,首先,我们需要确保程序始终以管理员身份运行。这可以通过添加应用程序清单文件来实现,并在其中添加 <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
,如评论 UAC Manifest Options 中所述。
接下来,我们需要确保访问权限被文件夹中所有子文件夹和文件正确继承。这是通过 TraverseDirectory
、SetFileInheritance
和 SetDirectoryInheritance
方法完成的。
最后,让我们检查 SetDirectoryAccess
方法。请注意,我们使用 InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
和 PropagationFlags.None
,因为我们希望我们的访问规则不仅应用于此文件夹,还应用于子文件夹和文件。这篇文章解释了我们的访问规则范围与相应标志之间的关系。
?using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
namespace PermitAccess
{
class Program
{
static void Main(string[] args)
{
foreach (var arg in args)
{
var success = ResetDirectory(arg);
var msg = success ?
string.Format("Access permission has been reset for
all subfolders and files in directory {0}", arg) :
string.Format("Unable to reset access permission for directory {0}", arg);
Console.WriteLine(msg);
}
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
public static bool ResetDirectory(string path)
{
bool accessSet = false;
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
TraverseDirectory(path);
accessSet = SetDirectoryAccess(path);
}
catch (IOException ex)
{
Console.WriteLine("An unexpected exception just occurred. Details:");
Console.WriteLine(ex.Message);
return false;
}
return accessSet;
}
private static void TraverseDirectory(string path)
{
// First set inheritance for the dir itself
SetDirectoryInheritance(path);
var files = Directory.GetFiles(path);
foreach (var f in files)
{
// Then set inheritance for each file in this dir
SetFileInheritance(f);
}
var directories = Directory.GetDirectories(path);
foreach (var d in directories)
{
// Recursively call this method
TraverseDirectory(d);
}
}
private static void SetFileInheritance(string path)
{
var fileInfo = new FileInfo(path);
var fileSecurity = fileInfo.GetAccessControl();
fileSecurity.SetAccessRuleProtection(false, true);
fileInfo.SetAccessControl(fileSecurity);
}
private static void SetDirectoryInheritance(string path)
{
var directoryInfo = new DirectoryInfo(path);
var directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetAccessRuleProtection(false, true);
directoryInfo.SetAccessControl(directorySecurity);
}
private static bool SetDirectoryAccess(string path)
{
var directoryInfo = new DirectoryInfo(path);
var directorySecurity = directoryInfo.GetAccessControl();
var securityIdentifier = new SecurityIdentifier
(WellKnownSidType.BuiltinUsersSid,
null);
var rule = new FileSystemAccessRule(
securityIdentifier,
FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit |
InheritanceFlags.ObjectInherit,
PropagationFlags.None,
AccessControlType.Allow);
bool modified;
directorySecurity.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
directoryInfo.SetAccessControl(directorySecurity);
return modified;
}
}
}
Using the Code
要使用此代码,您可以首先构建此项目,并将 PermitAccess.exe 复制到您自己程序的输出文件夹中。在您的程序中,调用
Process uacProcess = new Process();
uacProcess.StartInfo.FileName = "PermitAccess.exe";
uacProcess.StartInfo.Arguments = @"[Directory to reset]";
uacProcess.Start();
请注意,您不需要强制您的程序以管理员身份运行。PermitAccess.exe 本身会要求用户提供管理员权限。
您也可以在 Windows 命令提示符中运行 PermitAccess.exe。导航到 PermitAccess.exe 所在的文件夹,并调用 PermitAccess [要重置的目录]
。
历史
- 版本 1.0。2017 年 7 月 30 日