C# file creation is not working after setup file is created - c#

I have an app which is creating .json file. User enters required data and then app creates .json file inside bin folder:
File.WriteAllText("dbconfig.json", JsonConvert.SerializeObject(dbconfig, Newtonsoft.Json.Formatting.Indented));
Next time I start app the code reads bin folder using Environment.CurrentDirectory an searches for a .json file:
File.Exists($"{Environment.CurrentDirectory}\\dbconfig.json"
I am using this so that user shouldn't need to enter the same data everytime he starts an app, only once for the first time. While debugging everything is working fine. The problem is that after I've created setup file and install an application, after I enter required data to be saved to .json and press OK the application crashes.
Does anyone have an idea where the problem can be? Maybe something is wrong with file creation? I've never done such thing before so there is great possibility that I'm missing something in my code.

Almost impossible to say without more information like what is the exception? Is the error in the file create or json serialization.
Off the top of my head it could be dependent on where you install application. i.e. is it under a protected folder where you may need elevated privileges.
Looking at your filename looks like you want to store some user data, ideally those files should be stored in the users profile or all users profile. Try something like
// create a folder to store user data under c:\users\username\appdata\local
var appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "myapp");
if (!Directory.Exists(appDataPath))
{
Directory.CreateDirectory(appDataPath);
}
//Write json to file
var jsonFile = Path.Combine(appDataPath, "dbconfig.json");
File.WriteAllText(jsonFile, JsonConvert.SerializeObject(dbconfig, Newtonsoft.Json.Formatting.Indented));
//ToRead
if (File.Exists(jsonFile))
{
var jsonString = File.ReadAllText(jsonFile);
.....
}

Related

How to save XML file on IIS 7 server using ASP.NET

So I have a problem in my ASP.NET MVC application, it doesn't want to save the xml file after I publish it. I have a form which I post to a controller using ajax, and then I use that data to create an xml file which i then want to save.
I use the following code to generate my xml file and save it:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(rawXml);
StreamWriter path = new StreamWriter(Server.MapPath("/"+ fileName + ".xml"));
xmlDoc.Save(path);
If I run my application in debug It writes the file to ~/MySolution/MyProject/MyFile, no problem.
So when I publish the app to the IIS 7 server on my computer and load the app through localhost/MyApp, I expect it to write the file to C:\inetpub\wwwroot\MyApp\MyFile but it doesn't.
I have enabled permissions to the folder inetpub and all the subsequent folders for NETWORK SERVICE. But the AJAX post keeps returning in Error and the file doesn't appear in the folder, so I assume it's not allowing to write the file to the specified path, or the path is incorrect, ether way I don't know how to check what's gone wrong.
How do I make the published app write the xml file to the C:\inetpub\wwwroot\MyApp\MyFile path?
First of all it's not recommended to write any files in the root folder as writing to root folder cause appdomain to recycle after certain number of writes (default is 15) causing session loss. See more details here.
I would suggest you to add a path of your server to web.config and then fetch it in your code.Use something like below in the appsettings section of web.config
<add key="filePath" value="C:\inetpub\wwwroot\MyApp" />
Regarding the permissions please add Users group to your folder and give that group full permission (read/write).
To further find out which specific user (as there are too many use cases) is used by w3wp you can use process monitor as explained below
Capture Process Monitor log while reproducing issue
Filter on Access Denied
No Access Denied, so filter on w3wp.exe
Look for access to 401-3.htm
Review entries before the 401-3.htm to determine what file was accessed last
Check permissions based on successful QuerySecurityFile operation for last file accessed (in this case was asp.dll)

How to create a content file and navigate into it from a console application?

Im working on a "text only" game with console application. I searched for ways to add sound to my application, but all of the solutions needed to include a path to the .wav file location. that would work, but I want to publish my game later on. and the file location matches only my PC, I mean, the user who downloads it can put the content file in a diffrent location than c:/Mygame/Content. what if he has multiple hard-drives? or a Disk on key? the program wont play the sound, because it cant find the sound. any ideas?
Store the WAV file in a location relative to your .exe file and use:
System.Reflection.Assembly.GetExecutingAssembly().Location
to dynamically get the location of your .exe file at runtime and append it to the name of the .WAV file.
I solved it myself with these lines of code:
` string exe_location = System.Reflection.Assembly.GetExecutingAssembly().Location;
exe_location = exe_location.Remove(exe_location.Length - 11);
int last_path_chat = exe_location.Length;
string sound_location = exe_location.Insert(last_path_chat, "DIE_ANTWOORD_-_UGLY_BOY.wav");
SoundPlayer.SoundLocation = sound_location;
SoundPlayer.PlaySync();
You should be able to have your console application reference the .wav format file through a relative path(something like "~/Content", and have it called in reference to the current directory of the application. Once that's done, you could build a simple installer(or just have the .wav file site in the program directory if you'll just be deploying your app via copy) to deploy your app.
I'm at work right now so can't do any quick testing, but if this question is still outstanding when I get home tonight I'll mock something up and post it here.

How can I get the file path for a file I only know the name of? C#

So I'm making a Tic Tac Toe application and have created a Text file linked to the program to hold the following information:
the name
the time took to win
the difficulty
I know the timer is redundant for a quick game like Tic Tac Toe but I'll use it in the future for other programs.
My question is how can I find the full path of the file while only knowing the name of the file?
I want to do this using the program so it can be transferred to any computer and still be able to access the file without the user having to input it.
The code I've tried is:
string file_name = Path.Combine(Environment.CurrentDirectory, "Tic Tac Toe\\HighScores.txt");
But this just looks in the Debug folder, where the file isn't located. The application is entirely a console application.
Try to dedicate the file in a fixed sub directory:
\TicTacToe.exe
\settings\settings.cfg
So the path is dependent of your executable file.
You'll fetch the directory by calling Directory.GetCurrentDirectory()
You can set a desired directory by setting Environment.CurrentDirectory
A common way to handle this case is the one described above.
Another would be to use user specifiy directories like the %appdata% path and create a dedicated directory there.
%appdata%\TicTacToe\settings.cfg
Everytime your application starts it should lookup the folder %appdata%\TicTacToe\
If it is present, your application has been executed with this user.
If not, just create a new one, so we know it's the first run.
You can get the %appdata% path by calling
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Example of what i would have done
private void setUp(){
string filename = "settings.cfg";
string dir = "TicTacToe";
string appdata =Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string fullpath = Path.Combine(Path.Combine(appdata,dir),filename);
//check if file exists, more accurate than just looking for the folder
if(File.Exists(fullpath )){
//read the file and process its content
}else{
Directory.CreateDirectory(Path.Combine(appdata,dir)); // will do nothing if directory exists, but then we have a bug: no file, but directory available
using (FileStream fs = File.Create(fullpath))
{
Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
}
}
Hope it helped.
Perhaps have a configuration file for your application and store the directory name in there.
An old example from MS, but should still be applicable...
How to store and retrieve custom information from an application configuration file by using Visual C#

Denied acces to a file

I have a code which is similar this:
string file;
using (StreamReader r = new StreamReader("xml.xml"))
{
file = r.ReadToEnd();
}
XElement xml = XElement.Parse(file);
using (XmlWriter w = XmlWriter.Create("xml.xml")) //The point of problem!
{
w.WriteStartDocument();
...;
w.WriteEndDocument();
}
When I try run it like a console application is everything all right. But problems start when I want to use it in an ASP.NET application. At the using line it throws UnauthorizedAccessException exception with a description "access to the path is denied". Why?
You need to check which account your application Pool is using to access your server files/folders, for example, make one code to copy one file to application folder, check all security info, copy and paste on this problem folder, normally use this account "IIS_IURRS" give full control to test only...
If IIS/the web server is configured correctly, an account with a very limited set of permissions is used. As your path points to the application directory, it is very likely that the application pool account is not allowed to write to this location.
If you run the code in a console application, your user's permissions are applied and it is more than likely that you are allowed to write to the output folder of the project as Visual Studio writes the build output there under your account.
I would not recommend to change the application pool account or the permissions of the application folder in the file system - it is a very sensible limitation that limits the amount of trouble an attacker can possibly make.
Therefore I'd recommend to either move the file to a folder that the account can write to without changing permissions or define a special one outside of the application folder hierarchy that the account is given permissions to.
Also keep in mind that multiple users might access the file at the same time, so a database might be a better choice to store the data.

Environment.SpecialFolder.ApplicationData returns the wrong folder

I have a strange problem: my .NET 4.0 WPF application is saving data to the ApplicationData folder.
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\myProgram\\";
99.9% of the cases are working great, but on some computers it returns the wrong folder - instead of returning the user folder it returns another folder:
C:\Users\<user>\AppData\Roaming\myProgram\ --correct
C:\Users\s\AppData\Roaming\myProgram\ --wrong
The wrong folder has no write/read permission so my program doesn't work.
It seems the program is running under a different user, but if I check the Task Manager the user is the logged one.
The problem seems to be occurring with domain users with few permissions.
Do you also create a text file to write?
If so save a file such as:
String path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var filePath = Path.Combine(path, "filetowrite.log"); // Handles whether there is a `\` or not.
if (File.Exists(filePath))
{
......................
}
Note also before doing any file operations, one should check if directory exists.

Categories

Resources