I\'ve a custom installer program that has worked fine, but it asks the user for admin permission every time it updates an application. I\'m creating a windows service that skip
I recently encountered a problem loading files from a network and wanted to be able to recreate the bug in a test and ran into the same problem.
I came up with the following little class to help out with it as the API for doing this stuff is pretty horrible and full of little pitfalls:
public class PermissionController
{
private readonly string _file;
private readonly FileSecurity _accessControl;
private readonly SecurityIdentifier _id;
private readonly List<FileSystemAccessRule> _permissionsDenied;
public PermissionController(string file)
{
_file = file;
_accessControl = File.GetAccessControl(_file);
_id = WindowsIdentity.GetCurrent().Owner;
_permissionsDenied = new List<FileSystemAccessRule>();
}
public void Allow(params FileSystemRights[] rights)
{
foreach (var right in rights)
AddRule(Rule(right, AccessControlType.Allow));
}
public void Deny(params FileSystemRights[] rights)
{
foreach (var right in rights)
{
var rule = Rule(right, AccessControlType.Deny);
AddRule(rule);
_permissionsDenied.Add(rule);
}
}
private void AddRule(FileSystemAccessRule rule)
{
_accessControl.AddAccessRule(rule);
}
private FileSystemAccessRule Rule(FileSystemRights right, AccessControlType type)
{
return new FileSystemAccessRule(_id, right, type);
}
public void RemoveDeniedPermissions()
{
foreach (var rule in _permissionsDenied)
_accessControl.RemoveAccessRule(rule);
Apply();
}
public void Apply()
{
File.SetAccessControl(_file,_accessControl);
}
}
The calling code looks like:
_permissionController = new PermissionController(_file);
_permissionController.Allow(FileSystemRights.Read, FileSystemRights.Write);
_permissionController.Deny(FileSystemRights.FullControl,
FileSystemRights.Modify,
FileSystemRights.ReadAndExecute);
_permissionController.Apply();
where _file is the fully qualified path.
You need to be careful to call
File.SetAccessControl after adding/removing rules as otherwise there is no effect.
Unless I misunderstood the API you have to add a rule per permission because the FileSystemRights enum does not use flags.
You also need to be a bit careful as Allowing a right that you have denied is not equivalent to removing the rule that denies that right. It seems that denied rights override allowed ones.
You can eyeball the results by looking at the security tab of a file's properties in windows explorer.
I figured it out. I just needed to call,
file.SetAccessControl(access);
after the above. Apparently file.GetAccessControl passes back a copy of the access control and not the one that controls the file permissions for the file, until you call file.SetAccessControl with the modified permissions.
There's another caveat I discovered with another file that the service was creating in c:\ProgramData,