C#.NET - Error Logging and Relative File Paths - c#

I have a class in C# that saves an error message in a log file in case of an exception. Now I want to save the log file in the same folder containing the application's (in my case, a website) files. I tried using Environment.CurrentDirectory however it is not retrieving the path to my website. What can I do please to make use of a relative file path which points inside the website's directory?
Here is the class' code. As you can see, the path is absolute. I want to change it to a relative file path pointing to a folder in my website's directory.

Usually Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) returns the path where the current assembly resides. You could use
string logName = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "MyLogFile.log");
to create the log file name.
Question is really whether logging to the application's folder is permitted by the OS. Also, for Web-applications, the log file would be publically visible and accessible through the web browser.

For a website use:
HttpContext.Current.Server.MapPath("~/");

You might also could try this solution:
string path = AppDomain.CurrentDomain.BaseDirectory + "anotherFolder";
This would put the base dir of the app and a folder inside of the project!

Related

How to get the path of the uploaded file within the AppBundle?

We are using Autodesk Forge's Design Automation API. We have an AppBundle ready and we put an .rfa file into the same folder which contains the .dll file. When the AppBundle is unzipped on the Forge servers, which path can lead to our .rfa file? (how can we access it?) Our goal is to place the attached Family file's contents into the input file which is being uploaded with the API, and the result should be a new file which contains the additions from the file which we uploaded within the AppBundle. The process works when testing with Revit locally, but it doesn't work with the API. In the report we are retrieving it's obviously pointing out that the attached file cannot be found:
Autodesk.Revit.Exceptions.FileNotFoundException: T:\Aces\Jobs\ced628d35ecf4412b68c024e2cec098b\something.rfa
On the code side, we are trying to access the .rfa file via this path:
static string currentDir = Environment.CurrentDirectory;
static string path_input = currentDir+#"\something.rfa";
This seemed as a logical path, but as it turned out, it's not..
Is there a way to access the .rfa file inside the uploaded AppBundle?
I took a look at the Restrictions but reading the file from the AppBundle is not mentioned as restricted or not approachable. Am I missing something?
A .NET assembly knows its own path. You can call System.Reflection.Assembly.GetExecutingAssembly().Location within it to find the current path of the dll. You can then compute the path of the .rfa file relative to the folder of the dll and use it / open it. Thus you should be able to open any file you package along with your addin in your appbundle.
You can simply modify your code to:
static string assemblyLocation = Assembly.GetExecutingAssembly().Location;
static string assemblyDirectory = Path.GetDirectoryName(assemblyLocation);
static string path_input = assemblyDirectory+#"\something.rfa";
One thing to note however, is that you only have readonly access to files in appbundle. If your code relies on modifying these during execution, then you may simply copy the source rfa file to the current working folder and then work with the copied file instead.
Also see more details in blog for similar ideas.
We have a blog post on how you can either pass in the app bundle path in the commandLine parameter or find the path via the location of the add-in dll:
https://forge.autodesk.com/blog/store-template-documents-appbundle

Folder in windows form c#

This is my first windows form application.
I need to work with folders that I have created in my project and I need to access the Data folder where I put .txt files.
I try :
string fileName = #"Data\TextFile1.txt";
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
but i keep receiving this error :
impossible find part of path.
How can I combine the folder's path with file's name so when I release the project all works well?
This is what I do in an asp.net application:
Path.Combine(HttpRuntime.AppDomainAppPath, "Folder/FileName.txt");
Your data files need to be available in output folder along with you application .exe file. to do that:
Open properties of each file in Data folder.
Select Copy Always against Copy to output directory
Then build application
This will copy Data folder along with all files in Bin\Debug folder and will work with your existing code.
If I understand correctly, you are trying to read some file you have added to your solution in Visual Studio.
First, to have those files "deployed", click on them in the Solution Explorer, go to the Properties tool and have a look at the "Copy to Output Directory". Default is "Do not copy". Change that setting to "Copy always" or "Copy if newer". Now your files will be copied to the output directory when you build the solution.
Then, to get the current assembly path at runtime, have a look at:
Getting the path of the current assembly
string path = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath;
from the assembly path, you can get the containing folder's path, then you can use Path.Combine() to get your desired file path.
in C# .NET you can easy use the Environment Properties when working with Forms.
If you want e.g. the Appdata Path do this:
string MyPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\" + MyFileName;
But please get sure that the File/Path Exists!
For this you can use File.Exists -Function:
if(File.Exists(MyPath))
{
//Do Something
}
(For File-Class you need the System.IO namespace!)
EDIT:
Example:
string MyPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\MyConfig.txt";
if(File.Exists(MyPath))
{
MessageBox.Show($"{MyPath} exists!");
}
Hope that helped ;)
I would not create any path inside the application if possible. The NET framework provides the application configuration file for this kind of problems. You should simply add this section to your configuration file (app.config when developing, then application.exe.config after compilation)
<configuration>
<appSettings>
<add key="mydatafolder" value="e:\whateverpathyoulike"></add>
</appSettings>
</configuration>
Then at runtime read that value from your code
string path = ConfigurationManager.AppSettings["mydatafolder"];
path = Path.Combine(path, fileName);
This is easily modifiable both automatically or manually to adapt to any environment you find on the destination computers

Remove Hardcoded Folder Path in WPF

In my project I am referring to a folder:
string path=Path.Combine(#"E:\Per\kamlendra.sharma\Windows\main\software\my.software\my.software.Server\Resources", string.Format("LocalizationDictionary.{0}.xaml", SelectedNewLanguage.culture));
But I don't want to hard code this address:
#"E:\Per\kamlendra.sharma\Windows\main\software\my.software\my.software.Server\Resources"
Can anyone please suggest a better approach?
You can store application data in app.config
The UNC path of the currently executing assembly can be obtained. You can then use this as the basis to access the specific subfolder - this is assuming the folder you are looking for is the a subfolder of where the assembly is located...
System.Reflection.Assembly.GetExecutingAssembly().Location //This actually returns the assembly file name, so you would need to use FileInfo to get the folder location.
A better approach is probably System.Appdomain, which gives you access to the location of the actuall WPF application rather than the assembly.
System.AppDomain.CurrentDomain.BaseDirectory
This is how to configure and use application data files.
WPF Application Resource, Content, and Data Files

Environment PATH variable affecting Relative File Path(s)

I had this console application. Now i have added Environment variable PATH to its setup so that it can be executed from any location through Console. Strangely, the same application is breaking after this change.
Installation directory contains, BIN and CONFIG folder. Exe is placed inside BIN folder.
I have this line of code,
WriteToFile(#"..\Config\Settings.xml")
The path used to write to a file Settings.xml inside Config folder inside the INSTALLATION DIRECTORY. However, now it tries to write to settings.xml inside Config folder at EXECUTION PATH.
So, if i execute my app from console as c:/users/guest/app.exe, it would try to interpret path relative to this location AND NOT relative to installation directory for the application.
Any help, suggestions?
Get the path of the executing assembly then add to it the folder and file name:
string pathOfExecutingAssembly = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string settingsPath = pathOfExecutingAssembly + "\\..\\Config\\Settings.xml"
Why don't you try getting the Executing Application's Path and append it before the path where you want to save
Path starting from \ means: start from the root directory on the current drive. \Config\Settings.xml executed from any C subdirectory gives: C:\Config\Settings.xml.
BTW, do you post exact code? It should be WriteToFile(#"\Config\Settings.xml") or WriteToFile("\Config\Settings.xml")
In any case, you need to decide, whether you want to search configuration file using absolute path, or path relative to current directory/installation directory/executable directory. The code, installation package and execution command should be changed accordingly.

How to get a path from a directory in a C# console application?

Say I have this file structure
Soultion-> Folder1 -> FileIwant.html
So this could be something like C:\Soultion\Folder1\FilterIwant.html
Now I need to read this file into my application. I can't just hardcode it since when I give it to someone else they might put it on F: drive or something.
Or when I create a msi file the path might be completely different. So how can I say maybe take
"Folder1\FilterIwant.html"
and use that to get the folder path regardless of where they put it?
Edit
I tried Path.GetFullPath but I land up in the bin/debug directory. But my file is not in that directory. I think it is a couple directories before. Also if I make a msi file will I have bin/debug directory?
Why is a file which is used as part of your application not in the same folder as the application? It sounds to me like you should set the properties on that file to copy to the output folder when you do a build.
Doing that will make sure your file is in the bin\debug folder.
EDIT:
either that or you should be placing your files in one of the special folders, app data or my documents spring to mind.
When Visual Studio compiles your project, it will be putting the output into the bin\debug directory. Any content files that you want to reference must also be copied to those locations, in order for your app residing in that directory to be able to read that file.
You have two choices:
either you set the Copy to Output Directory property on your FilterIwant.html to Copy if newer; in that case, if the file has changed, it will be copied to the output directory, and you should be able to reference it and load it there
or
you just define a path in your app.config, something like DataPath, and set it to your folder where the file resides. From your app, you then create the full path name for that file as Path.Combine(AppSettings["DataPath"], "FilterIwant.html") - with this approach, you become totally independant of where the file really is and you don't need to move around anything. Also: this gives you the opportunity to create an admin/config utility for your users later on, so that they can pick any directory they like, and your app will find those files there.
In my console app, I started with the debug directory until i found the closest parent folder I wanted.
static void Main(string[] args)
{
Console.WriteLine("Start");
var debugDir = Environment.CurrentDirectory;
DirectoryInfo di = new DirectoryInfo(debugDir);
var searchDir = "";
while (!di.FullName.ToLower().EndsWith("Folder1"))
{
if(di.FullName.ToLower().EndsWith(":")) //if you went too far up as in "D:" then
break;
di = di.Parent;
}
Console.WriteLine(di.FullName);
}
You need the help of System.Io.Path class:
GetFullPath: Returns the absolute path for the specified path string.
Edit:
You might also need the application directory - this is where your application will be installed:
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
Path.GetFullPath
Edit
The bin/Debug path will not be present when you run your installed application (unless you specifically tell the installer to use that subdirectory, of course).
You probably want to pass the full path as a command line argument. You can then get the argument using the args parameter of the Main method. To convert a relative path to an absolute one you can use Path.GetFullPath:
using System;
using System.IO;
public class CommandLine
{
public static void Main(string[] args)
{
// The path is passed as the first argument
string fileName = arg[0];
// get absolute path
fileName = Path.GetFullPath(fileName);
// TODO: do whatever needs to done with the passed file name
}
}

Categories

Resources