I'm trying to copy files from external hard disk to folder in my desktop, in order to do that I have to take ownership of the folders and the files in the external hard disk, I read in previous questions about it how it has to be and my code looks like this:
using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), Privilege.TakeOwnership))
{
directoryInfo = new DirectoryInfo(path);
directorySecurity = directoryInfo.GetAccessControl();
directorySecurity.SetOwner(WindowsIdentity.GetCurrent().User);
Directory.SetAccessControl(path, directorySecurity);
}
When I run this code I get an exception in the line:
directorySecurity = directoryInfo.GetAccessControl();
The exception is:
"unauthorizedAccessException was caught" "Attempted to perform an
unauthorized operation".
Why is that happen? And how can I copy these folders and files?
Related
In my C# forms application, I try to download the data in a directory of my SFTP Server. The data should be stored in a folder which I want to create in "MyDocuments". When the folder is created, I receive an Renci error "failure" because the folder is "read-only".
I tried many ways to create a folder, but I in most ways I used I either got an error, that I don't have the permission to create a folder, or I got an empty file instead of a folder. Right now I got a folder, but unluckily it is read only.
String localPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\MyNewFolder\\";
if (Directory.Exists(localPath))
{
Console.WriteLine("Folder already exists");
}
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
DirectoryInfo directory = new DirectoryInfo(localPath);
DirectorySecurity security = directory.GetAccessControl();
}
I expect the folder not to be read only, so that I can safe data in it using my programm. Anyone knows why my code still creates a read only one?
I believe you have to set the following using the DirectorySecurity object:
DirectorySecurity securityRules = new DirectorySecurity();
securityRules.AddAccessRule(new FileSystemAccessRule(#"Domain\Account", FileSystemRights.FullControl, AccessControlType.Allow));
Then you can create the directory using the following:
DirectoryInfo di = Directory.CreateDirectory(#"directoryToCreatePath", securityRules);
EDITED:
Once you've created the directory using Directory.CreateDirectory(), you can then apply the following to the folder. This will allow the user you've specified to have FullControl of the folder. You can check the permissions for that user via Properties > Security
DirectoryInfo directory = new DirectoryInfo("C:\\CreatedFolder");
DirectorySecurity security = directory.GetAccessControl();
security.AddAccessRule(new FileSystemAccessRule(#"USERNAME",
FileSystemRights.FullControl,
AccessControlType.Allow));
directory.SetAccessControl(security);
I'm trying to download multiple files from an SFTP server and save them to the install path (or actually, ANY path at the moment just to get it working). However, I get an UnauthorizedAccess Exception no matter where I try to save the files.
As far as was aware, there are no special permissions required to save files to the install dir (Hence why I chose this folder).
Thread myThread = new Thread(delegate() {
string host;
string username;
string password;
// Path to folder on SFTP server
string pathRemoteDirectory = "public_html/uploads/17015/";
// Path where the file should be saved once downloaded (locally)
StorageFolder localFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
string pathLocalDirectory = localFolder.Path.ToString();
var methods = new List<AuthenticationMethod>();
methods.Add(new PasswordAuthenticationMethod(username, password));
//TODO - Add SSH Key auth
var con = new ConnectionInfo(host, 233, username, methods.ToArray());
using (SftpClient sftp = new SftpClient(con))
{
try
{
sftp.Connect();
var files = sftp.ListDirectory(pathRemoteDirectory);
// Iterate over them
foreach (SftpFile file in files)
{
Console.WriteLine("Downloading {0}", file.FullName);
using (Stream fileStream = File.OpenWrite(Path.Combine(pathLocalDirectory, file.Name)))
{
sftp.DownloadFile(file.FullName, fileStream);
Debug.WriteLine(fileStream);
}
}
sftp.Disconnect();
}
catch (Exception er)
{
Console.WriteLine("An exception has been caught " + er.ToString());
}
}
});
Connection to the server is all fine, the exception occurs on this line.
using (Stream fileStream = File.OpenWrite(Path.Combine(pathLocalDirectory, file.Name)))
I'm must be missing something obvious here but it's worth noting that I've also tried writing to Special Folders like the Desktop, the users Document folder and also direct to the C:/ drive, all with the same exception. I'm also running with Administrator privileges and I have the correct permissions set in the folders.
It turns out that SFTP was counting '.' and '..' as files and trying to download those, when obviously '.' is the set SFTP folder and '..' is the previous folder. This was causing a permissions exception, not 100% sure why. Simply iterating over the files to make sure they're not named '.' or '..' fixed the issue. Code below.
sftp.Connect();
var files = sftp.ListDirectory(pathRemoteDirectory);
// Iterate over them
foreach (SftpFile file in files)
{
if (!file.IsDirectory && !file.IsSymbolicLink)
{
using (Stream fileStream = File.OpenWrite(Path.Combine(pathLocalDirectory, file.Name)))
{
sftp.DownloadFile(file.FullName, fileStream);
Debug.WriteLine(pathLocalDirectory);
}
}
else if (file.Name != "." && file.Name != "..")
{
Debug.WriteLine("Directory Ignored {0}", file.FullName);
}
else if (file.IsSymbolicLink)
{
Debug.WriteLine("Symbolic link ignored: {0}", file.FullName);
}
}
sftp.Disconnect();
You have multiple problems here. The parent folder ("..") reference you answered is one blocker, but that doesn't address the deeper problem that the InstalledLocation is read-only.
UWP apps do not have direct access to most file system locations. By default they can read and write to their ApplicationData directory and they can read from (but not write to) the InstalledLocation. The failures you saw for Desktop, Documents, and C:\ are all expected.
Other locations (including Desktop, Documents, and C:) may be granted access by the user either explicitly or via the app's declared capabilities. They can be accessed via the file broker through the StorageFile object.
See the UWP File access permissions documentation:
The app's install directory is a read-only location. You can't gain
access to the install directory through the file picker.
For the long term you'll want to download your files somewhere else: probably into one of the ApplicationData folders. These folders are the only ones with no special permission requirements for UWP apps.
So why does this work for you now?
You're running into a debugging quirk where your app is not fully installed but is staged from your VS project directory. This allows the app to write to the staged install directory, but once it is properly deployed into Program Files\WindowsApps writing to the InstalledLocation will fail.
Try Path.GetTempPath();. You should have permission there.
When it says you don't have permission, you don't. 8-)
Also, there's no such thing as "no special permissions". Everything requires some level of permission for access.
Delete file using C# from directory is holding the process for long time. How to kill process once the file is deleted.
Tried with 2 options of deleting the file,
Option 1:
path = #"C:\temp\a.xml";
File.Delete(path);
Option 2:
path = #"C:\temp\";
DirectoryInfo CVfiles = new DirectoryInfo(path);
foreach (FileInfo CVfile in CVfiles.GetFiles())
{
CVfile.Delete();
}
Update
(from clarification in comments)
path = #"C:\temp\a.xml";
DirectoryInfo CVfiles = new DirectoryInfo(path);
foreach (FileInfo CVfile in CVfiles.GetFiles())
{
CVfile.Delete();
}
Thanks,
You could try
C# delete a folder and all files and folders within that folder
Ultimately the deletion will take as much as deletions needs.
How to kill process once the file is deleted.
You can just exit the program.
I am working on an application that requires that some files are copied to a different folder. I use the following:
DirectoryInfo dir = new DirectoryInfo(path);
foreach (FileInfo filesindires in dir.GetFiles())
{
FileSecurity ds = filesindires.GetAccessControl();
ds.AddAccessRule(new FileSystemAccessRule("Authenticated Users",
FileSystemRights.FullControl, AccessControlType.Deny));
filesindires.SetAccessControl(ds);
}
With that method I deny the user from opening the file, but I would like to only prevent copying. How can I prevent that a file is copied while allowing the user to read it?
If you can read it, you can copy it.
I have many images on remote server say images.foo.com/222 & i want to access file names of all files that resides in the folder 222 on images.foo.com/.
i have tried following code but getting error "virtual path is not valid" :
imageserver = http://images.foo.com/222;
DirectoryInfo di = new DirectoryInfo(imageserver); // line giving exception
FileInfo[] rgFiles = di.GetFiles();
string simagename = "";
if (rgFiles.Count() > 0)
{
foreach (FileInfo fi in rgFiles)
{
//collect each filename from here
}
}
Please help
thanks in advance
gbaxi
DirectoryInfo need a UNC path of type "\\fileserver\images"
A http address will not work
You can't access a directory residing on the web with the DirectoryInfo class. Instead, use the WebRequest class to get a list from the URL and get the files from that list.
The problem is that HTTP does not have a clear interface on how a directory listing is being displayed. There are roughly two choices:
Parse the HTML retrieved through a WebRequest, but you won't get things like creation/modification time and user;
Go with a different mechanism to retrieve the file details like FTP or File share.