Auto-loading file on program startup - c#

Ok, so here's a bit of code. I'm having an issue where I want to save to a pre-defined location, and I want to have a pre-defined name for a file. Neither FileStream nor StreamWriter allows you to set both of those paramters as far as I can tell, based on what I've seen on MSDN.
FileStream fs = new FileStream("PermaServerList", FileMode.Create, FileAccess.Write);
StreamWriter hiddensw = new StreamWriter(#"Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments", false);
So, if you look at that, how would I get it to save a file called "PermaServerList" to the location "My Documents", regardless of the version of Windows they're using? I don't want to hard code in a location, I want it to always be whatever My Documents is in their particular version.
Alternatively, the idea behind this is that every time the program starts, I want it to load the list they last saved automatically. Is there a -simple- way to do this? Right now, the idea is that I'll just save to their chosen location, and then make a second copy in my pre-defined location and just load that on program startup. Ideas?

Yes, you're simply trying to store and read user data, which can be easily dealt with using app.config settings file.

string fileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "PermaServerList.txt");
using (StreamWriter writer = new StreamWriter(fileName)) {
writer.WriteLine("wooo");
}
That's how you'd write to the file, for example. The SpecialFolfer enum will get you the location of the "My Documents" directory every time, regardless of what version of Windows they're using, or whether the folder is mapped to a network location, etc.
I'm not sure what you mean by "load the file when the program starts"; I assume your issue is that you need the directory location, beyond that it's just a question of opening it as a stream and working with it.

Related

How Read File Path From a .dat file then open the program When Pressing The Launch Button?

I have a problem Where I cant make my program automatically read the given file path inside the .dat and be ready to launch the program when pressing launch file without opening openFileDialog and choosing the program every time.
the code im using here is for the user to enter the file path for the first time then create a file path .dat file and it works with now issues.
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string path = Path.Combine(desktop, "LS\\Fail-SafePath.dat");
openFileDialog.InitialDirectory = filePath;
openFileDialog.Filter = " PlayGTAV (*.exe)|PlayGTAV.exe";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
var fileStream = openFileDialog.OpenFile();
using (StreamReader reader = new StreamReader(fileStream))
{
fileContent = reader.ReadToEnd();
}
using (StreamWriter sw = File.CreateText(path))
{
sw.WriteLine(filePath);
}
After that that i have a start button for it
private void panel21_MouseClick(object sender, MouseEventArgs e)
{
Process.Start(filePath);
}
This works well when the user does it for the first time but now I want it to read that .dat file path automatically without having to ask the user for the file path every single time which I don't know how to do and need help with please.
I was thinking to do it like that: When Pressing the Launch button (After the first time) The Program Checks if the Fail-SafePath.dat Exists if Yes it reads the lines from it and starts the program from the given path without opening OpenFileDialog.
I'm Using Visual Studio, Windows Form.
If it's a file that the application will always need, then something like you mentioned:
I was thinking to do it like that: When Pressing the Launch button (After the first time) The Program Checks if the Fail-SafePath.dat Exists if Yes it reads the lines from it and starts the program from the given path without opening OpenFileDialog.
Could work easily enough. You could have your application look for it in the default location, and if not there, have your user select it.
Another solution could be using something like Application Settings or User Settings, which are values persisted between executions of .NET projects.
Depending on your full application design, you could also have the file path and other settings stored in some database or other data storage. There are a lot of ways to accomplish this.
EDIT: To elaborate further on the Application Settings
The application settings are very easy to read and write to.
You just need to create the ones you want, before trying to use them.
They can be created by:
Open Visual Studio.
In Solution Explorer, expand the Properties node of your project.
Double-click the .settings file in which you want to add a new setting. The default name for this file is Settings.settings.
In the Settings designer, set the Name, Value, Type, and Scope for your setting. Each row represents a single setting.
To read from your settings:
this.FilePath= Properties.Settings.Default.FilePath;
To write to and save the setting:
Properties.Settings.Default.FilePath= Path.GetFullPath("importantFilePath");
Properties.Settings.Default.Save();

How to obtain the full file path when using InputFile in Blazor Server?

I need to be able to extract the full file name, including the path when the user selects a file using my InputFile element.
So, as an example, using this
<InputFile OnChange="FileSelected" />
I can see the filename in the event handler like so
void FileSelected(InputFileChangeEventArgs eventArgs)
{
//eventArgs.File.Name has just the name of the file, e.g. ABC.csv but I need the full path like c:\userfolder\ABC.csv
but after various googling attempts, I haven't been able to figure out how to get the full file name.
The purpose here is to present the user with a file dialog box where they could pick a file and then I could load a few other files that are needed using the full file path.
Thanks
then I could load a few other files that are needed using the full file path
Nope.
The server cannot read from the client’s file system. Any files that need to be sent to the server, the client needs to send them.
Even the client-side code is very restricted by the browser’s sandboxed environment. The user needs to supply the file in order to grant permission. See: https://developer.mozilla.org/en-US/docs/Web/API/File
You’ll likely need to re-think the use case. Because browsers specifically don’t allow what you want to do.
try this....
public void OnChangeUpload(UploadChangeEventArgs args)
{
foreach (var file in args.Files)
{
var path = Path.GetFullPath("wwwroot\\Images\\") + file.FileInfo.Name;
FileStream filestream = new FileStream(path, FileMode.Create, FileAccess.Write);
file.Stream.WriteTo(filestream);
filestream.Close();
file.Stream.Close();
pathUrl = path;
}
}

Deploy an application's xml file with installer or create it on the fly if it does not exist

I am having an xml file like:
<CurrentProject>
// Elements like
// last opened project file to reopen it when app starts
// and more global project independend settings
</CurrentProject>
Now I asked myself wether I should deliver this xml file with above empty elements with the installer for my app or should I create this file on the fly on application start if it does not exist else read the values from it.
Consider also that the user could delete this file and that should my application not prevent from working anymore.
What is better and why?
UPDATE:
What I did felt ok for me so I post my code here :) It just creates the xml + structure on the fly with some security checks...
public ProjectService(IProjectDataProvider provider)
{
_provider = provider;
string applicationPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
_projectPath = Path.Combine(applicationPath,#"TBM\Settings.XML");
if (!File.Exists(_projectPath))
{
string dirPath = Path.Combine(applicationPath, #"TBM");
if (!Directory.Exists(dirPath))
Directory.CreateDirectory(dirPath);
using (var stream = File.Create(_projectPath))
{
XElement projectElement = new XElement("Project");
projectElement.Add(new XElement("DatabasePath"));
projectElement.Save(stream, SaveOptions.DisableFormatting);
}
}
}
In a similar scenario, I recently went for creating the initial file on the fly. The main reason I chose this was the fact that I wasn't depending on this file being there and being valid. As this was a file that's often read from/written to, there's a chance that it could get corrupted (e.g. if the power is lost while the file is being written).
In my code I attempted to open this file for reading and then read the data. If anywhere during these steps I encountered an error, I simply recreated the file with default values and displayed a corresponding message to the user.

Unbelievable strange file creation time problem

I have a very strange problem indeed! I wonder if the problem is in the framework, OS or maybe it's just me, misunderstanding things...
I have a file, which might be created a long time ago, I use the file, and then I want to archive it, by changing it's name. Then I want to create a new file, with the same name as the old file had, before it was renamed. Easy enough!
The problem that really puzzles me, is that the newly created file gets wrong "created"-timestamp! That's a problem since it's that timestamp that I want to use for determing when to archive and create a new file.
I've created a very small sample that shows the problem. For the sample to work, there must be a file 1.txt in the Files folder. Also, the file attribute must also be set back in time (with one of the tools available, I use Nomad.NET).
static void Main(string[] args)
{
// Create a directory, if doesnt exist.
string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\Files";
Directory.CreateDirectory(path);
// Create/attach to the 1.txt file
string filename = path + "\\1.txt";
StreamWriter sw = File.AppendText(filename);
sw.WriteLine("testing");
sw.Flush();
sw.Close();
// Rename it...
File.Move(filename, path + "\\2.txt");
// Create a new 1.txt
sw = File.AppendText(filename);
FileInfo fi = new FileInfo(filename);
// Observe, the old files creation date!!
Console.WriteLine(String.Format("Date: {0}", fi.CreationTime.Date));
Console.ReadKey();
}
This is the result of an arcane "feature" going way back to the old days of Windows. The core details are here:
Windows NT Contains File System Tunneling Capabilities (Archive)
Basically, this is on purpose. But it's configurable, and an anachronism in most of today's software.
I think you can create a new filename first, then rename old->old.1, then new->old, and it'll "work". I don't remember honestly what we did when we ran into this last a few years back.
I recently ran into the same problem described in the question. In our case, if our log file is older than a week, we delete it and start a new one. However, it's been keeping the same date created since 2008.
One answer here describes renaming the old file and then creating a new one, hopefully picking up the proper Creation Date. However, that was unsuccessful for us, it kept the old date still.
What we used was the File.SetCreationTime method, and as its name suggests, it easily let us control the creation date of the file, allowing us to set it to DateTime.Now. The rest of our logic worked correctly afterwards.
File.SetCreationTime("file", DateTime.Now);

Completely overwriting a file with Velocity / NVelocity

I am trying to use NVelocity templates in a .Net application: using a template to output results to a file. It all seems to work fine except for the fact that the output is never fully overwritten. If my file is 100 characters long and the template only renders 20 characters, the last 80 characters are never altered!
Code sample:
FileStream fileStream = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write);
using (StreamWriter streamWriter = new StreamWriter(fileStream))
{
velocityEngine.MergeTemplate(templateName, Encoding.Default.WebName, velocityContext, streamWriter);
}
So if my template outputs AAAA and the file already contains BBBBBBBB then at the end, the file contains AAAABBBB at the end of the op.
Any clue how I can get it to fully overwrite the file? - e.g. in the above example the final output should be AAAA. Not too sure whether this is just pure stream-related stuff - but I haven't had this problem before with filestreams.
Happy to write a reset method, or just output to a memorystream and overwrite the file, but I would like to get it working like this if possible!
**EDIT:'' got it working by calling
fileStream.SetLength(0);
when I open the file. But would appreciate knowing if there was a better way!
I think the solution is to change the FileMode.OpenOrCreate to simply FileMode.Create in the first line
From the MSDN Article on System.IO.FileMode..
FileMode.Create
Specifies that the operating system should create a new file. If the file already exists, it will be overwritten.
FileMode.OpenOrCreate
Specifies that the operating system should open a file if it exists; otherwise, a new file should be created.
If you don't know, at open time, that you may be truncating the file, you can use the SetLength method on the Stream to truncate it.
http://msdn.microsoft.com/en-us/library/system.io.stream.setlength.aspx
For this to work, the Stream must be writable and seekable.

Categories