winform not creating file in read-only folders - c#

I am trying to create a file in a directory using the code below
if (File.Exists(myDir))
{
return myDir;
}
System.IO.Directory.CreateDirectory(myDir);
File.SetAttributes(myDir, FileAttributes.Normal);
//string name = myDir + "/" + filename;
File.Create(myDir).Dispose();
return myDir;
When I run it on a Mac it works since the directory have write permission, however, I have noticed that on windows 10 all folders are automatically read only, so the access to write in the path is denied.
What would be the solution for me to write a file in this path?
Btw if I use this path which is my MacBook directory (read&write permission) : "//Mac/Home/Movies" it will just work as it should, it will create the subdirectories and the file in it, however if I choose the windows one which is "C:\CSVtest" it would just show "access denied as it is read-only, i can't find a way to bypass this read-only thing, i tried on other windows 10 machines as well and all folders on windows 10 are read-only so it is the same case

//path = #"C:\Temp\Bar\Foo\Test.txt";
Directory.CreateDirectory(Path.GetDirectoryName(path));
Directory.CreateDirectory will create the directories recursively and if the directory already exist it will return without an error.
You then would create the file
File.Create(path).Dispose();

Related

Environment.GetFolderPath(Environment.SpecialFolder) is returning wrong value

I have a UWP project, and wrote this code:
foreach (var foldertype in (Environment.SpecialFolder[])Enum.GetValues(typeof(Environment.SpecialFolder)))
{
//string d = Environment.CurrentDirectory;
var path = Environment.GetFolderPath(foldertype);
var folder = await StorageFolder.GetFolderFromPathAsync(path);
StorageApplicationPermissions.FutureAccessList.Add(folder, folder.Path);
Debug.WriteLine($"Opened the folder: {folder.DisplayName}");
this.MenuFolderItems.Add(new MenuFolderItem(folder));
}
It is supposed to enumerate all the special folders, and get their folder. However, while debugging, this is what happens:
foldertype = Desktop
path = "C:\\Users\\cuent\\AppData\\Local\\Packages\\402b6149-1adf-4994-abc9-504111b3b972_a5s740xv383r0\\LocalState\\Desktop"
folder = [ERROR] System.IO.FileNotFoundException: 'The system cannot find the file specified. (Exception from HRESULT: 0x80070002)'
I do not know what is happening here, it seems to be appending the path to the installed location of the app. How do I fix this?
Expected output of GetFolderPath() is wherever the Desktop is, not the weird path.
UWP apps are different from desktop applications when accessing the file system. UWP apps are running in the sandbox so there are limitations for UWP apps when trying to access the file system. You could check this document: File access permissions. The document lists all the locations that UWP apps have permission to access.
Back to your scenario, what you need first is a broadFileSystemAccess restricted capability. This capability enables your app could use the StorageFolder.GetFolderFromPathAsync() API with a Path parameter. This is mentioned in the last part of the document I posted above.
Then the second issue is the Environment.GetFolderPath API. It looks like the API will return a Path that points to a local folder inside the app's local folder. But there is no such desktop folder inside the app's local folder so you will get the FileNotFoundException. You might need to set the correct path by yourself like C:\Users\your user name\Desktop. After that, your code should be able to work correctly.

WinSCP .NET assembly - How to set folder permissions after creating directory?

I'm building a web site and I want that when a user registers, to create a directory on the SFTP server and put in that directory a new file
I'm using WinSCP .NET assembly, and writing C#.
I noticed that you are able to set permissions only in the method: Session.PutFiles
and not in the method: Session.CreateDirectory
Snd so after I create the directory and put the file in it, I cannot access the file because I don't have permissions - I'm accessing the file with the full URL
How can I access the file?
PS.
When I change the directory permissions manually, I am able to access the file.
Note that this answers your question how to set permissions when creating a directory. But a root cause of your problem is that a default permissions your server sets are wrong. The server should not use default permissions such that you cannot access a directory/file you have just created yourself!
It's currently not possible to directly set permissions, when a creating directory or modify them afterwards with WinSCP .NET assembly.
See https://winscp.net/tracker/1075
You can hack it though as follows:
Create a local empty temporary directory
Upload it using the Session.PutFiles, setting permissions you need in TransferOptions.FilePermissions
string directoryName = "mydir";
string directoryPath = "/home/username/" + directoryName;
string tempPath = Path.Combine(Path.GetTempPath(), directoryName);
Directory.CreateDirectory(tempPath);
try
{
TransferOptions options = new TransferOptions();
options.FilePermissions = new FilePermissions { Octal = "755" };
session.PutFiles(tempPath, directoryPath, false, options).Check();
}
finally
{
Directory.Delete(tempPath);
}
You can even do without creating an empty temporary directory. Just pick any directory, e.g. directory of your account profile folder, and use a file mask to include only this one directory, preventing files in the directory and sub-directories from being uploaded. Also use an explicit name of desired remote directory in the target path to "rename" the uploaded directory to the name you want.

Force create directories for temporary file and path in Windows Phone 8 app?

I have a C# Windows Phone 8 app where I need to create some temporary files. Currently I'm creating the necessary temporary file name and path using the following code:
string tempFilename = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
Uri tempUri = new Uri(tempFilename, UriKind.Absolute);
The problem is, when I go to create the file with the following code:
StorageFile binaryFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
The operation fails with a file not found Exception because the folder path does not exist yet. How do I quickly create all the necessary directories and sub-directories beneath it to support the temporary file path, in a manner that doesn't fail if the directory tree already exists?
Here's a sample temporary file name and path:
C:\Data\Users\DefApps\AppData\{28B80680-CB2F-459B-B6AC-A60A9A729868}\Temp\tmp7C9F.tmp
There is only one way to create directory in isolated storage: IsolatedStorageFile.CreateDirectory, if you are in windows phone

HttpPostedFile.SaveAs access denied

I'm trying to save a file that I upload from my page but I'm getting an access denied error:
public void SaveFile(Item item, HttpPostedFileBase file)
{
var dir = string.Format(#"{0}\NSN\{1}", ConfigurationManager.AppSettings["ContentLocation"].ToString(), item.Id.ToString());
if (!System.IO.Directory.Exists(dir))
System.IO.Directory.CreateDirectory(dir);
Array.ForEach(Directory.GetFiles(dir), File.Delete);
file.SaveAs(dir);
}
I'm running this site from the local host from visual studio so no app pool is involved. I've given the Network Service (and Everyone as a test) full control of the folder and it's subfolders. Strange thing is it creates the folder if it needs to and also deletes any files in an existing folder. Only when I call the SaveAs function do I get the error.
You call file.SaveAs with path to directory instead of path to file
Here, give this a try:
string saveAsPath = Path.Combine(dir, file);
file.SaveAs(saveAsPath);
Replace file.SaveAs(dir) with the above.

File not found when executable launched from another application

In my application, after the user logs in I set a few picturebox/button/etc images and do some scaling on them and whatnot. I use relative paths for example:
#".\Images\SomeImage.png"
It works fine when the application is launched directly, but if you try to run it via another application:
Process process = new Process();
process.StartInfo.FileName = networkPath;
process.Start();
It dies and comes up with a file not found error, because it cannot locate the images. It also does this if I try to launch it via the command prompt. The executable is stored on a network drive. Why won't the relative path work in this situation? I can just go ahead and hard code the full path but that makes me feel dirty... Any thoughts?
This is because the working directory is different - by default when starting a new process the working directory for the new process is set to the working directory of the existing process (which will in turn probably be the directory that existing application is contained within).
Normally your application will be run with the working directory as the directory that the executable is contained in - this is the default when creating a new shortcut for example (you can see this in the shortcut properties under the "Start in" field.
When your application is run from the command prompt or from another application however the working directory is changed and the relative paths are resolved to a completely different directory.
You can either change the calling application to se the WorkingDirectory property of the new process to the value it expects, however the proper way of fixing this it to modify your application so that it uses absolute paths based on the path to the executable. Assembly.GetExecutingAssembly().Location can be used to get the path to the executable being run and so the following code should do the trick:
static string GetAbsolutePathFromRelative(string RelativePath)
{
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string absolutePath = Path.Combine(directory, RelativePath);
// This final call is to stop paths like "C:\Dir\..\OtherDir\file.txt" being returned
return Path.GetFullPath(absolutePath);
}
You need to set the Process.WorkingDirectory property to the correct path.
The path you posted:
#".\Images\SomeImage.png"
Is not a network path (it is not UNC or using a mapped drive).

Categories