C# DirectorySecurity SetOwner on subcontainers and objects - c#

I am trying to change ownership of a windows folder and everything inside it. Basially I am trying to check the box that would be there if you did this manually in windows that says "Replace owner on subcontainers and objects". This will need to work over a network share path. I am able to get 1 folder deep but then it just stops there. This does not include the base folder changing either.
foreach (string directory in Directory.GetDirectories(dirPath))
{
var di = new DirectoryInfo(directory);
IdentityReference user = new NTAccount(Login.authUserName.ToString());
DirectorySecurity dSecurity = di.GetAccessControl();
dSecurity.SetOwner(user);
di.SetAccessControl(dSecurity);
}

You can use Directory.GetDirectories with SearchOption.AllDirectories in order to recurse.
But it seems easier to just get the DirectoryInfo di objects directly using DirectoryInfo.GetDirectories, which has the same and more recursive options.
IdentityReference user = new NTAccount(Login.authUserName.ToString());
var root = new DirectoryInfo(dirPath);
foreach (var di in root.GetDirectories("*", SearchOption.TopDirectoryOnly).Prepend(root))
{
var dSecurity = di.GetAccessControl();
dSecurity.SetOwner(user);
di.SetAccessControl(dSecurity);
}

Related

c# wpf read only folder

I am creating a new folder in documents and after that I want to write a file to it. The problem is, is that the folder I create is 'read only'. So I can't add a file to it. I can't fix it.
What I have now:
string target_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "data");
Directory.CreateDirectory(target_path);
var di = new DirectoryInfo(target_path);
di.Attributes &= ~FileAttributes.ReadOnly;
I also made my program startup as administrator but that doesn't make any difference.
Edit
When trying to store a file inside the folder I get the following error:
System.UnauthorizedAccessException: 'Access to the path "xxxx"' is denied.'
try explicitly set permissions.
string target_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "data");
DirectorySecurity securityRules = new DirectorySecurity();
securityRules.AddAccessRule(new FileSystemAccessRule("Users",FileSystemRights.FullControl, AccessControlType.Allow));
DirectoryInfo di = Directory.CreateDirectory(target_path, securityRules);

DirectoryInfo usage in a UWP project

I am currently working to a Windows 10 UWP project and I keep getting the following exception:
Unable to cast object of type 'System.IO.FileSystemInfo[]' to type 'System.Collections.Generic.IEnumerable`1[System.IO.FileInfo]'.
and this is the code which throws it:
DirectoryInfo dirInfo = new DirectoryInfo(path);
FileInfo[] files = dirInfo.GetFiles(path);
path is a valid one, i verified it several times, I do not know why I am getting this exception. Can the DirectoryInfo class still be used in a UWP application or should I use an equivalent one ?
The DirectoryInfo class is applicable for UWP. However, it has a lot of limitations. Such as whether the path is valid. For more detail you could refer to Skip the path: stick to the StorageFile.
It throw Second path fragment must not be a drive or UNC name exception when I passed path parameter. I found the following description.
The search string to match against the names of files. This parameter can contain
a combination of valid literal path and wildcard (* and ?) characters (see Remarks),
but doesn't support regular expressions. The default pattern is "*", which returns
all files.
So I modify the searchPattern like the following, it works well.
string root = Windows.ApplicationModel.Package.Current.InstalledLocation.Path;
string path = root + #"\Assets\Media";
DirectoryInfo dirinfo = new DirectoryInfo(path);
FileInfo[] files = dirinfo.GetFiles("head.*");
I do not know why I am getting this exception. Can the DirectoryInfo class still be used in a UWP application or should I use an equivalent one ?
The best practice to query files in UWP is to use folder picker to select a folder and enumerate all the files with GetFilesAsync method. For example:
var picker = new Windows.Storage.Pickers.FolderPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
picker.FileTypeFilter.Add("*");
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
var folder = await picker.PickSingleFolderAsync();
if(folder != null)
{
StringBuilder outputText = new StringBuilder();
var query = folder.CreateFileQuery();
var files = await query.GetFilesAsync();
foreach (StorageFile file in files)
{
outputText.Append(file.Name + "\n");
}
}

How to dispose media files after accessing its properties?

I need to access at least 100 of media files(video) and checking through their properties. eg. date modified, camera model/maker then if im done with it, i need to dispose/release this media files. is there a media.Dispose() method.
Shell32.Shell shell;
shell = new Shell32.Shell();
Shell32.Folder objFolder;
Shell32.FolderItem folderItem;
string stringFullFileName, model, maker;
foreach (FileInfo files in MyFolder)
{
stringFullFileName=files.FullName.ToString();
objFolder = shell.NameSpace(Path.GetDirectoryName(stringFullFileName));
folderItem = objFolder.ParseName(Path.GetFileName(stringFullFileName));
model = objFolder.GetDetailsOf(folderItem, 30);
maker = objFolder.GetDetailsOf(folderItem, 32);
//Marshal.ReleaseComObject(objFolder); //doesnt dispose
//Marshal.ReleaseComObject(folderItem); //doesnt dispose
File.Move(stringFullFileName, newPath); //It says "The process cant access the file
because it is being used by another process"
}
i need File.Move, not File.Copy.
I have 2 possible solutions for you:
1 - Unless you need to import the Shell assembly for some reason, I don't see why you can't just use a DirectoryInfo / FileInfo objects: i.e.
foreach (var file in new DirectoryInfo(#"C:\VideoFolder").GetFiles())
{
//Get the file information that you need here...
var creationTime = file.CreationTime;
//Move the file
file.MoveTo(#"C:\Trash\");
}
2 - If you have to keep the code as is for some reason, why not just move the file direct (it's already a FileInfo Object)? i.e.
Instead of this line:
File.Move(stringFullFileName, newPath); //It says "The process cant access the file
Have this:
files.Move(newPath);

How to Set File Access Permission for Scanning All Files in C#

I am Trying to write a Functionality where i could get the Complete List of All File Name in all Drives,but I am stuck in a place where its giving me security exception to read all files.
I went through many of the articles in this site and the other, but unable to figure out how to set complete access rights
this post was much useful but i am getting an Exception which was unanswered in that thread
How to grant read access to all files in a folder and subfolders using c#?
Now My code looks like this
[FileIOPermission(SecurityAction.LinkDemand, Read = "C:\\")]
public void GetAllFilesFromPhysicalDrives()
{
List<DriveInfo> allphydrives = GetListofPhysicalDrivesOnly(); //Gets All Physical DrivesCollection
try
{
foreach (DriveInfo dr in allphydrives)
{
DirectoryInfo dir = new DirectoryInfo(dr.Name);
DirectorySecurity dirSecurity = dir.GetAccessControl();
dirSecurity.AddAccessRule(new FileSystemAccessRule(Environment.UserName, FileSystemRights.Read, AccessControlType.Allow));
dir.SetAccessControl(dirSecurity);
FileSystemAccessRule faRule;
FileSystemRights fsrRights;
DirectorySecurity dirsec;
fsrRights = FileSystemRights.FullControl;
faRule = new FileSystemAccessRule(new System.Security.Principal.NTAccount("my-pc\\me"),fsrRights,InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,PropagationFlags.InheritOnly, AccessControlType.Allow);
System.Security.Principal.NTAccount account = new System.Security.Principal.NTAccount("me\\me");
dirsec = Directory.GetAccessControl("C:\\");
dirsec.SetOwner(account);
dirsec.AddAccessRule(faRule);
Directory.SetAccessControl("C:\\", dirsec);
}
}
catch(Exception ex)
{
}
}
so when the code to set the access executes i am getting an "Attempt to Perform UnAuthorized Operation" Exception
I don't want to set Permission for files one by one because its a tedious task so help me which would happen dynamically via code for All folders so that i could iterate and get all file names .(I don't intend to get windows related files or kernal files ,just the user created files is enough)

Recursive Security Settings

I would like to apply a folder's Security Settings to all descendants in C#. Essentially, I would like to do the same thing as 'Replace all existing inheritable permissions on all descendants with inheritable permissions from this object' within 'Advanced Security Settings for [Folder]'.
Are there any elegant ways to approach this?
After some quality time with google and MSDN I came up with the following bit of code. Seems to work just fine.
static void Main(string[] args)
{
DirectoryInfo dInfo = new DirectoryInfo(#"C:\Test\Folder");
DirectorySecurity dSecurity = dInfo.GetAccessControl();
ReplaceAllDescendantPermissionsFromObject(dInfo, dSecurity);
}
static void ReplaceAllDescendantPermissionsFromObject(
DirectoryInfo dInfo, DirectorySecurity dSecurity)
{
// Copy the DirectorySecurity to the current directory
dInfo.SetAccessControl(dSecurity);
foreach (FileInfo fi in dInfo.GetFiles())
{
// Get the file's FileSecurity
var ac = fi.GetAccessControl();
// inherit from the directory
ac.SetAccessRuleProtection(false, false);
// apply change
fi.SetAccessControl(ac);
}
// Recurse into Directories
dInfo.GetDirectories().ToList()
.ForEach(d => ReplaceAllDescendantPermissionsFromObject(d, dSecurity));
}
You may find the DirectorySecurity class to be useful for this.
http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.directorysecurity.aspx
There may be some other valuable tools within the System.Security.AccessControl
namespace

Categories