I have an xml file in a WCF application that describes dependencies. It is loaded when the service facade constructor runs and works great when testing the app alone. The way our separate web testing application is setup is an endpoint in a different (mvc) project - So the relative paths are different to the xml file that we need to load. The question is what would be the best way to load that file from both projects (so that when you run the first project alone it loads the file, but then when that dll is loaded in the second project it can still find the xml file)?
You could copy it to the output directory. You can do this from Visual Studio by right clicking the file, choosing properties and changing "Copy To Output Directory" to "Copy Always".
At runtime you will be able to find the file in the current directory in both projects.
Try Server.MapPath
example:
Server.MapPath (#"~\App_Data\menudata.xml")
then you can place your file in any location relative to the root directory of your website/webservice.
I tried the "Copy To Output" with no luck - for some reason my root path was not where the output path was (which i previously thought)... So to abstract away any headaches from other developers setting up this project I did this:
var _assembly = System.Reflection.Assembly.GetExecutingAssembly();
XDocument xdoc = XDocument.Load(new StreamReader(_assembly.GetManifestResourceStream("TheNamespace.Api.TheFile.xml")));
Which of course requires the file to be an embedded resource.
Related
the problem that i have with my application is about how to reference some files, when i load and image, etc, i use Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..\\..\\..\\")); and this works fine for debugging and for some files, but doesn't work for some essential files, credentials.txt, config.ini, this files are searched in appdata when i run the published file and i don't know how i should reference them.
I try to generate some initial files so i am sure where they are and that they exists, but for folders that works great with
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
with that i can make the folders where the app is run but you can't generate a file without load the content of the original file, and i don't know how to reference them.
Example:
Project.
Root of the project.
utils/key/credentials.txt
When the published file is executed i want to generate and store credentials.txt like this:
Executable (app.exe stored for example in "my documents")
"my documents"/utils/key/credentials.txt
how i do that? when i run the published application you just have the .exe, the dlls, and the resources are embebbed, so the uri doesn't works.
Assuming you have sufficient permissions, you could create a folder in the output folder of your compiled .exe at runtime using the Directory.CreateDirectory method.
If the utils/key/credentials.txt file is part of your deployment, you should set its Build Action to Content and the Copy to Output Directory property to Copy if newer in Visual Studio. This will add the utils and key folders to the output directory of the .exe, which is typically c:<project-folder\bin\Debug or \Release when you build from Visual Studio.
You can get the absolute path of the output directory like this:
string path = System.IO.Path.GetDirectoryName(
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
Depending on your requirements, you may then append the relative path of the file within your app to the absolute path.
I'm currently using fileinfo to use a xsd file in a xml validator.
I have 3 projects, a GUI, interface, project. A input project and a testproject.
Inside the input project i have a class that creates a FileInfo Object based on a path to a file that is also inside the same object:
new FileInfo(#"Xsd\Version_813\kvppt-8130.xsd")
This gives me trouble when i'm running my tests and my GUI. For example when i start my GUI, sometimes the code works and there is no problem but other times FileInfo will search the Bin/debug folder from the GUI project and the XSD isnt there.
I know that this is intended but is there a way to make this work for the unittest Project and the GUI project.
I have tried the following:
var executingFileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
var path = executingFileInfo.DirectoryName + Path.DirectorySeparatorChar + #"Xsd\Version_813\kvppt-8130.xsd";
Return new FileInfo(path);
But this isn't the solution because it will still pick the startup project.
--- Edit:
After trying some of the suggestions in the comments i found out that my problem is a bit diffrent. I found out that if i press rebuild all before running my application, the files are always copied to their correct folder. It only fails if i just run the application.
Properties of the files are on "Copy always"
...sometimes the code works and there is no problem but other times
FileInfo will search the Bin/debug folder from the GUI project and the
XSD isnt there.
Make sure on the properties of the file (from within Visual Studio) you have "Copy to Output Directory" set to either "copy always" or "copy if newer"
I have a solution containing two projects. One project is just for doing all data stuff and the other one, the startup project, do all the web stuff.
Now I want to get the TasksDataBase.xml from the TaskManagerHelpers class by first getting the projects root directory. But all I get is the TaskManager.Web root directory. (I call the method inside TaskManagerHelpers.cs from a controller inside TaskManager.Web)
How do I get the TaskManager.Data root directory when I'm in a class in the same project?
I've tried with theese methodes and similar ones.
HttpContext.Current.Request.PhysicalApplicationPath;
System.IO.Path.GetFullPath();
AppDomain.CurrentDomain.BaseDirectory;
Thanks in advance!
One possibility is to embed the XML file into the assembly of the class library and then read it as resource in your web application. Remember that when you publish your web application to a web server all that will get into the package will be the files of this web application. There's no physical relation to some projects that might have lived into the Visual Studio solution that this web application was part of.
You may take a look at the GetManifestResourceStream method which will allow you to read the embedded XML from the referenced assembly.
Here's an example:
// you could use any type from the assembly here
var assembly = typeof(TaskManagerHelper).Assembly;
using (var stream = assembly.GetManifestResourceStream("TaskManager.Data.DataBase.TasksDataBase.xml"))
using (var xmlReader = XmlReader.Create(stream))
{
// ... do something with the XML here
}
Bear in mind though that since the file is embedded into the assembly you will not be able to modify it. It is readonly. If you need to modify it then an alternative approach would consist into copying this file to your web application. For example a good place is the App_Data special folder. You could even setup a post compilation step that will copy the XML file in this location.
And then you can reference it easily:
string xmlFile = HostingEnvironment.MapPath("~/App_Data/TasksDataBase.xml");
using (var xmlReader = XmlReader.Create(xmlFile))
{
// ... do something with the XML here
}
In this case since the XML file is now physically part of the web application and lives on the hard drive you could also modify it.
Just because the two projects are located in the same folder tree during development, says nothing about where they'll be located at run time. It's entirely possible that that could be on different machines.
"No," you say. They'll will definitely be on the same machine in the same c:\inetpub tree. That may be true, but that's your policy, not a requirement.
If you are going to establish a hard policy about where they are located, then you can hard-code that into you code.
Right-click the XML file and select properties, then change the Copy to Output Director to one of the other settings than "Do Not Copy". That will place the file into your \bin\ folder alongside the other project output. You can then use AppDomain.CurrentDomain.BaseDirectory as your base path
IF you are running a web project, all the referenced dll files are copied to the bin directory (unless they are in the GAC) and used from there, no matter if you add a reference to another project, Visual Studio first compile it and then copies it to the bin folder of the web project. You can mark your xml file as Content (Compilation Action) and with the copy always option so it always copy it to the bin directory .... the problem is that it sometime look for this files outside of the bin folder but I think that you can handle this.
I wrote a form application in c# using Visual Studio 2008, third party dlls, an xml file and images. The images have been added to the project as resources.
A System.IO.FileNotFoundException is thrown when I attempt to run the published version of the executable on another machine.
If I copy the .exe file to the desktop on the pc, and also copy the dlls and the xml file to the desktop, double clicking on the exe works fine.
In my project, I have the copyLocal set to true for the required dll references. The xml is added to the project and set to copy if newer to output directory. I also checked the publish application files and everything is there.
The line I use to load the xml file is this
config = new XmlDocument();
config.Load("fileName.xml");
I'm assuming the FileNotFound exception is being thrown when you try to load the XML file, right?
Simply looking for "filename.xml" doesn't seem like a fantastic idea to me, especially if this is a key configuration file for your application.
I typically try to move these things into my App.config file then load them either using a fully qualified path or a short path. For example:
App.config
<add key="ExternalConfig" value="D:\\config.xml"/>
.cs file
config = new XmlDocument();
config.Load(ConfigurationManager.AppSettings["ExternalConfig"]);
You could also use a relative path, but keep in mind that you're always relative to the current working directory.
Alternatively, based on the type of data in your configuration, you could try to store this information to you App.config file and do away with a config.xml altogether.
I need to read data from a file in a c# console application.
What works: new StreamReader(#"..\\..\myData.csv");
Problem:
the ..\\..\ work because my exe file is in the bin/Debug directory
When I deploy my project the path doesn't work any longer
Question:
How can I reference myData.csv regardless of the location of the exe file?
I had hoped to find a method that returns the 'root' of my console application
So far I tried the following:
Process.GetCurrentProcess().MainModule.FileName
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location
Path.GetFullPath("bp.csv")
AppDomain.CurrentDomain.BaseDirectory
Directory.GetCurrentDirectory()
All of these expressions lead me to the directory of the exe file not the root.
I just started to read about isolated storage but it would be nice to have something simpler. Any suggestions / recommendations?
The simplest option is probably to add your CSV file to the solution and right-click it in VS and set the build action to "Copy if newer", which will output it together with the .exe (to the Debug or Release folder) when you build.
In the code, you can get the current location of the executing assembly like this:
string folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
And then you can combine the path with the CSV file name:
string filePath = Path.Combine(folder, "myData.csv");
Where your myData.csv will be stored ? You should have an absolute location of this file.
there are couple of options
You can place this file at the same directory where your exe is placed so you will only need to do
new StreamReader("myData.csv");
you can define file location in the App.Conig file and read that location.
you can set a path variable an read the PATH variable.
You should change your code to
new StreamReader("myData.csv");
This will ensure that the data is always read from the same folder the .exe is run from.
After that, you can create a post build step to copy the file to the deployment folder (or a subfolder) so that even in your debug environment the file will be in the correct place. The property "Copy to Output Folder" on the data file will do this as well if you just need the file to be in the output path for a project.
If you need more control, n the post build steps you can use macros like $(ProjectPath) to reference where the project files are located and $(TargetDir) to reference where the output directory will be.