Adding content files to and accessing content files from a web service - c#

I want to include an XML file in the bin directory of my web application/web service. I've included the bin folder in my project in Visual Studio and added the file. I set its Build Action to "Content" and Copy to Output Directory to "Copy Always". When my code goes to find it, I use
string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!dir.EndsWith(#"\")) dir += #"\";
to get the directory and return it as appPath, where appPath is (unescaped version):
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\vs\0c7655f\d4908928\assembly\dl3\5cf9fd67\fdc52284_ffa7d201\
then I append the file name of my XML file (where string filename = "myXmlFile.xml") to read it:
StreamReader reader = new StreamReader(appPath + filename);
But I get an exception on that line of code, that it could not find my file. I am handling for escaping of the slashes fine, so it is not that. When I checked the physical directory that the path points to, it was not copied to that directory, and that is the cause of the exception. So how do I get my file to get copied there?

How about using HostingEnvironment.ApplicationPhysicalPath
var dir = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, "bin\\filename.xml")
See related question how to get the application path in asp.net?.

Related

how to reference file by path in published c# visual studio build

I have a file path which I access like this
string[] pathDirs = { Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..\\..\\")),
"config", "file.txt" };
string pathToFile = Path.Combine(pathDirs);
When I run the build from within visual studio it gets the config directory from the root directory of the project but when I publish the build and run the program from the published build I get the error
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\<user>\AppData\Local\Apps\2.0\GA3VWRPE.G83\KDK3Q6QC.VP1\sv20..tion_333839f4362dc717_0001.0000_958d209d94853f42\config\file.txt'.
I'm unsure how to access this directory and file in the published build. How would I do this?
To get the path to the executable, you can use Assembly.GetExecutingAssembly().Location, which could be incorporated into your code like:
string filePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location), "..", "..", "config", "file.txt"));
Thanks to #ManiVI for that comment.
Go to Solution Explorer and click Show All Files
Go to file.txt, right-click and select Include In Project
in Properties
Build Action: Content,
Copy To Output Directory: Copy always
Once I followed these steps the published program managed to find file.txt.

File ReadAllText is getting a wrong path (C#)

I have a local project that in the future will be in a pipeline.
Because of this, I need to use a relative path to get and read a json file.
But using the File.ReadAllText I'm obtaining the following answer:
> File.ReadAllText("MyJsonFiletoRead.json", Encoding.Default)
System.IO.FileNotFoundException: Could not find file 'C:\Users\15071\MyJsonFiletoRead.json'
Note that 'C:\Users\15071' is not the project folder, this is my windows user folder.
My struct is here:
C:\Projetcs\MyProjectTest -->> Project folder
C:\Projetcs\MyProjectTest\MyClass.cs -->> The class where I'm calling the ReadAllText
C:\Projetcs\MyProjectTest\MyJsonFiletoRead.json -->> My json file that I'm trying to find
I have tried the following commands to check my PATH, but all answer is wrong:
> Environment.CurrentDirectory
"C:\\Users\\15071"
> Directory.GetCurrentDirectory()
"C:\\Users\\15071"
AppDomain.CurrentDomain.BaseDirectory
"c:\\program files (x86)\\microsoft visual studio\\2019\\community\\common7\\ide\\commonextensions\\microsoft\\managedlanguages\\vbcsharp\\languageservices\\DesktopHost\\"
Has somebody a solution to fix this?
Note: If I use the full path, it works:
File.ReadAllText("C:/Projetcs/MyProjectTest/MyJsonFiletoRead.json", Encoding.Default)
If the file is located at the same folder of your executable file, you just need to pass the file name:
File.ReadAllText("MyJsonFiletoRead.json", Encoding.Default);
If the file is located at a relative path from the folder where your executable file is located, you can get the Assembly Location and combine it with a relative path:
var path = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..\\..\\MyJsonFiletoRead.json");
File.ReadAllText(path, Encoding.Default);
You need to find the current folder and then read the file
var currentFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
File.ReadAllText(currentFolder + "/MyJsonFiletoRead.json")

How to create a folder and file inside of the folder where the app is installed? c#

I want to be able to set default folder and file creating inside of the folder where the app is installed? Because this app will be used on multiple machines so I cannot specify path like C://Users/PcName/etc.. Is there any very simple way of doing it?
What you are trying to do is not advisable; if your application is installed using recommended default methods (following Microsoft guidelines) the app will be in a directory under C:\Program Files (or where the program files folder may be redirected) and the user that runs the app will not have write access to that directory, so the directory creation will fail.
That said, you cannot use the Environment.CurrentDirectory, because it may or may not be the directory where your application's executable files reside, neither CurrentDomain.BaseDirectory, because that is not significative too (documentation says it's the directory where the loader will search for assemblies, but that may or may not be the directory of your application's executable files).
Copying from this other answer, the correct way to find the directory of your assembly is
public static string AssemblyDirectory
{
get
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
return Path.GetDirectoryName(path);
}
}
Once you have the path, you can try to create the directory with System.IO.Directory.CreateDirectory() and a file with System.IO.File.WriteAllText() or its siblings, or any other standard method of creating files.
You may also want to use the newer Assembly.GetExecutingAssembly().Location property, and use Path.GetDirectoryName() on that.
This applies to both web and windows apps:
Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
You can get the path for the executable using this code (most of the time, actually it returns the current working directory)
System.Environment.CurrentDirectory
If you only specify a path that doesn't start with a drive letter then the path will be relative to where the application is running. e.g. The following program will create a folder and file in the application's local folder.
class Program
{
static void Main(string[] args)
{
var installedLocation = Directory.GetParent(Assembly.GetExecutingAssembly().Location);
var di = installedLocation.CreateSubdirectory("MyFolder");
File.WriteAllText(Path.Combine(di.FullName, "File.txt"), "This will be written to the file");
var installedPath = AppDomain.CurrentDomain.BaseDirectory;
var di2 = Directory.CreateDirectory(Path.Combine(installedPath, "MyFolder2"));
File.WriteAllText(Path.Combine(di.FullName, "File2.txt"), "This will be written to the file");
}
}

Windows service accessing invalid directory with StreamReader

I am reading a file that is located in the same directory as my executable using a StreamReader with the following method:
StreamReader reader=new StreamReader(".\\file.txt"); //NOTE: 2nd backslash is escape character in C#
When I do this in the debug environment, it reads the file fine, but when I install the service it tries to read the file in C:\Windows\System32\ as if the working directory is set to that path, but in the services properties there is no working directory option. I'm guessing it's using the working dir of sc.exe.
Is there a way I can get it to resolve to the location of the current executable using relative file paths? Because the service might be placed in different locations based on deployments.
Yes, working directory of a service is %WinDir%\System32.Also GetModuleFileName() will return incorrect result because your service is hosted by another executable (by chance placed in that directory too).
You have to find executing assembly and its location, longer to describe than to do:
string assemblyPath = Assembly.GetExecutingAssembly().Location;
Now just extract directory name and combine with file you want:
string path = Path.Combine(Path.GetDirectoryName(assemblyPath), "file.txt");

Save/Copy a file in a directory from another

using : asp .net mvc 4.0, c# , vs10
strFilePath holds a path of a existing file in a directory. I want to save/copy the file into my application's uploads directory.
how could i do this. I am trying something foolish, and searching the internet and feeling helpless.
string filePath = "foo.txt";
//var path = Path.Combine(Server.MapPath("~/Uploads"), filePath);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Copy(filePath, "~/Uploads");
}
~ symbol is not recognized by File.Copy
Convert virtual path to physical path first and then do the copy.
System.IO.File.Copy(filePath, Server.MapPath("~/Uploads"));
Also, You need permission to the folder where you are copying. You may need to Impersonate if the above does not work.

Categories