I have a Winforms application that is supposed to create a subdirectory in the Public Documents folder if the directory does not exist and save a text file to it. However, if the subdirectory does not exist, it actually creates another directory called Public Documents under "C:/Users/Public" rather than just creating a subdirectory under the existing "C:/Users/Public" folder. (In the example below the subdirectory is the variable 'token'.) So I end up with 2 folders called Public Documents:
Here is my code:
if (result == DialogResult.Yes)
{
subPath = #"C:\Users\Public\Public Documents\" + token + #"\Tests\";
}
else if (result == DialogResult.No)
{
subPath = #"C:\Users\Public\Public Documents" + #"\Tests\";
}
TestModel testCall = new TestModel
{
Name = frm.fileName,
MethodName = txtApiMethod.Text,
Parameter = rtxtJson.Text,
SchemaKey = txtSchemaKey.Text
};
bool exists = System.IO.Directory.Exists(subPath);
string fileName = frm.fileName + ".txt";
string json = JsonConvert.SerializeObject(testCall);
string filePath = subPath + fileName;
if (!exists)
{
System.IO.Directory.CreateDirectory(subPath);
}
using (StreamWriter file = File.CreateText(filePath))
{
file.Write(json);
}
Can someone tell me why it is creating a duplicate named directory, and what I can do to have just create a new subdirectory under the existing directory?
Any assistance is greatly appreciated!
C:\Users\Public\Public Documents is a display name. I have a french Windows, and the display name is C:\Users\Public\Documents publics
The real path is C:\Users\Public\Documents
Display :
Real :
To make sure you are using the correct folder path (for some reasons, d: could be used instead, or the path could be totaly different. Never use hardcoded path), you can use System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonDocuments); that links to C:\Users\Public\Documents, such as :
var PublicDocuments = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonDocuments);
if (result == DialogResult.Yes)
{
subPath = PublicDocuments + #"\"+ token + #"\Tests\";
}
else if (result == DialogResult.No)
{
subPath = PublicDocuments + #"\Tests\";
}
See the documentation for more infos about System.Environment.SpecialFolder and System.Environment.GetFolderPath()
Related
I have an app in which the user needs to access certain files in a user set and selected folder.
The folder and files paths need to be easily accessed (short simple path).
I use the Properties Settings to hold the Folder and File paths, but for some reason each time I re-start the program the Folder and File paths are lost.
I have followed and checked the program and all seems to be OK (except something I am missing, apparently).
I attach here the program snippet in two parts: The search for path and the setting in case path / file not found. (removed exception handling to save on lines)
public Main() //part of Main, stripped off exception handling)
{
//..........
dataFolder = Properties.Settings.Default.dataFolder;
if (!Directory.Exists(dataFolder))
{
SetDataFolder();
}
configFile = Properties.Settings.Default.configFile;
if (!File.Exists(configFile))
{
SetConfigFile();
}
dataFile = Properties.Settings.Default.dataFile;
if (!File.Exists(dataFile))
{
SetDataFile();
}
loadParamsFromFile(configFile); //Load the previously saved controls.
public String SetDataFolder()
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
DialogResult folder = dialog.ShowDialog();
if (folder == DialogResult.OK)
{
dataFolder = dialog.SelectedPath;
Directory.CreateDirectory(dataFolder);
dataFolder = Path.GetFullPath(dataFolder);
Properties.Settings.Default.dataFolder = dataFolder;
Properties.Settings.Default.Save();
return dataFolder;
}
else return null;
}
private string SetDataFile()
{
dataFile = $"{dataFolder}\\{textBoxSampleID.Text.Replace("/r", "").Trim()}.txt";
File.Create(dataFile).Close();
Properties.Settings.Default.dataFile = dataFile;
Properties.Settings.Default.Save();
return dataFile;
}
private string SetConfigFile()
{
configFile = $"{dataFolder}\\electroplating.cfg";
File.Create(configFile).Close();
Properties.Settings.Default.configFile = configFile;
Properties.Settings.Default.Save();
return configFile;
}
Check out this question:
How to change application settings (Settings) while app is open?
I would suggest using Path.Combine() for the construction of the file paths.
If it still doesn't work, you could also try using the registry for storing the values.
string dataFilePath = Path.Combine(dataFolder, textBoxSampleID.Text.Replace("/r", "").Trim());
RegistryKey key = Registry.LocalMachine.CreateSubKey(#"SOFTWARE\Company");
if (key != null)
{
key.SetValue("dataFilePath", dataFilePath);
}
You could then use string dataFilePath = (string)key.GetValue("dataFilePath") to get the value out of the registry.
I have a DirectoryNotFoundException on a .txt file if I use the full path it's working but I don't want to use the full path because I want the program work no matter where it is placed (compatibilty with the maximum of computer)
Here's my code
private void SaveClose_Click(object sender, RoutedEventArgs e)
{
if (Windowed.IsChecked == true)
windowed = true;
else
windowed = false;
string textWriteWindowed;
if (windowed == true)
{
textWriteWindowed = "-screen-fullscreen 0" + Environment.NewLine;
}
else
{
textWriteWindowed = "-screen-fullscreen 1" + Environment.NewLine;
}
var selectedResolution = ResolutionBox.SelectedItem.ToString();
var split = selectedResolution.Split('x');
widthChoose = Int32.Parse(split[0]);
heightChoose = Int32.Parse(split[1]);
string textWriteWidth;
textWriteWidth = "-screen-width " + widthChoose + Environment.NewLine;
string textWriteHeight;
textWriteHeight = "-screen-height " + heightChoose + Environment.NewLine;
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
File.AppendAllText(#"\Resources\arguments.txt", textWriteWidth);
File.AppendAllText(#"\Resources\arguments.txt", textWriteHeight);
this.Close();
}
The first argument of File.WriteAllText takes a path as input. Whatever you have mentioned is not the absolute path but it is just the relative path of the file. WriteAllText creates the file but doesn't create the directory by itself. So something like:
File.WriteAllText(#"\arguments.txt", textWriteWindowed);
shall work (and create the file in the respective drive), but
File.WriteAllText(#"\Resources\arguments.txt", textWriteWindowed);
shall not work. Hence, if you want to create a file in the path where the application resides, you can do something like:
string folder=Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
File.WriteAllText(#"\arguments2.txt", "ABC");
If you want to create a directory, then you could do something like:
System.IO.FileInfo file = new System.IO.FileInfo(filePath);
file.Directory.Create();// If the directory already exists, this method does nothing.
System.IO.File.WriteAllText(file.FullName, textWriteWindowed);
Hope this answers your query.
you have to check whether the folder is exist before save the file,
if folder not exist create it using
Directory.CreateDirectory(...)
Directory.Exists(..)
you can use to check folder existence
IF you wanted to get the local path of the file you are executing use this:
var fInfo = new FileInfo(System.Reflection.Assembly.GetCallingAssembly().Location);
From there, you would do the following:
var parentDir = new DirectoryInfo(fInfo.DirectoryName);
var subDir = new DirectoryInfo(parentDir.FullName + "Resource");
if(!subDir.Exists)
subDir.Create();
This would ensure that you always have a folder in the directory of your executable. But just so you know, this is absolutely horrible code and should never ever be implemented in a production like environment. What if some knucklehead sysAdmin decides to place your program/folder in an area that the current user does not have access/writes too? The best place to write to is %APPDATA%, this will ensure the user always has read/write permissions to what you are trying to accomplish.
I don't know how but doing that worked for me :
File.WriteAllText(#"./arguments.txt", textWriteWindowed);
File.AppendAllText(#"./arguments.txt", textWriteWidth);
File.AppendAllText(#"./arguments.txt", textWriteHeight);
I'm trying to save a banner picture and before saving to a folder I'm checking and creating the respective folder as well but it gives me error even though I checked that the folder exists. Here is the code:
HttpPostedFileBase banner = Request.Files["banner"];
if (banner != null && banner.ContentLength > 0) {
var folder = Server.MapPath("~/images/Continents/");
if (!Directory.Exists(folder)) {
Directory.CreateDirectory(folder);
}
banner.SaveAs(Server.MapPath("~/images/Continents/" + image.FileName));
string x = "/images/Continents/" + image.FileName;
continent.BANNER = x;
}
Is there something I'm missing?
To concatenate Paths in Server.MapPath, use Path.Combine() as follow:
banner.SaveAs(Server.MapPath(Path.Combine("~/images/Continents", image.FileName)));
I have a nested if-else statement that is checking the contents of a folder I have that contains other txt files. This method either creates new txt files or denies access if they already exist in the folder.
The trouble I am having is with the checks if the file exists in the folder. Currently no matter what I do, the command will always return "Filename already exists" even if it doesn't exist.
If the file does not exist then the program should go down to the else statement and then create the new file
protected void create(string command, string param1)
{
// creates an empty file w/ default permissions
// if file already exists then error message displayed in console
//checks name of the file, checks if its exists, and if clear, creates the file
if (param1 == "accounts.txt" || param1 == "audit.txt" || param1 == "groups.txt" || param1 == "files.txt")
{
Console.WriteLine("Cannot use this filename");
Console.Read();
return;
}
else if (File.Exists(#"C:\Files\"))
{
Console.WriteLine("Filename already exists");
Console.Read();
return;
}
else
{
string path = Path.Combine(#"C:\Files\", param1);
using (StreamWriter sw = File.AppendText(path))
{
Console.Write("create " + param1 + "");
string path2 = "C:\\Files\\audit.txt";
using (StreamWriter sw2 = File.AppendText(path2))
{
sw2.WriteLine("File " + param1 + " with owner and default permissions created"); //append name of current login from memory
}
Console.ReadLine();
}
}
}
This block here is saying if the File doesn't exist, then write to the console 'File already exists'
else if (!File.Exists(#"C:\Files\"))
{
Console.WriteLine("File already exists");
Console.Read();
return;
}
Also note that you're using File.Exists on a directory, and not actually looking at a specific file.
See also Directory.Exists
MSDN - Directory Exists method
You didn't provide the file name in the code. The string #"C:\Files\") is not a file name, it is a directory.
You can use something like.
internal static bool FileOrDirectoryExists(string name)
{
return (Directory.Exists(name) || File.Exists(name));
}
To call the method, you have to pass the valid file name.
var name = Path.Combine( #"C:\Test","MyFile.txt");
var ifFileExist = FileOrDirectoryExists(name);
System.IO.CreateDirectory() is not available on .NET for Windows Store Apps.
How can I implement this equivalent method? StorageFolder.CreateFolderAsync() creates a subfolder inside the current folder, but in my case I have a path like and need to create all folders that doesn't exist in this path.
The path is inside the app's sandbox in windows.
There's no API with exactly the same behaviour of System.IO.CreateDirectory(), so I implemented it using Windows.Storage classes:
// Any and all directories specified in path are created, unless they already exist or unless
// some part of path is invalid. If the directory already exists, this method does not create a
// new directory.
// The path parameter specifies a directory path, not a file path, and it must in
// the ApplicationData domain.
// Trailing spaces are removed from the end of the path parameter before creating the directory.
public static void CreateDirectory(string path)
{
path = path.Replace('/', '\\').TrimEnd('\\');
StorageFolder folder = null;
foreach(var f in new StorageFolder[] {
ApplicationData.Current.LocalFolder,
ApplicationData.Current.RoamingFolder,
ApplicationData.Current.TemporaryFolder } )
{
string p = ParsePath(path, f);
if (f != null)
{
path = p;
folder = f;
break;
}
}
if(path == null)
throw new NotSupportedException("This method implementation doesn't support " +
"parameters outside paths accessible by ApplicationData.");
string[] folderNames = path.Split('\\');
for (int i = 0; i < folderNames.Length; i++)
{
var task = folder.CreateFolderAsync(folderNames[i], CreationCollisionOption.OpenIfExists).AsTask();
task.Wait();
if (task.Exception != null)
throw task.Exception;
folder = task.Result;
}
}
private static string ParsePath(string path, StorageFolder folder)
{
if (path.Contains(folder.Path))
{
path = path.Substring(path.LastIndexOf(folder.Path) + folder.Path.Length + 1);
return path;
}
return null;
}
To create folders outside your app's sandbox in windows store app, you'll have to add the document library in app-manifest, along with file permissions.
For a much more detailed explanation regarding library and documents, Refer this blog