Get the current running application path - c#

I have 3 application (asp.net website, console application, SSIS) and a common class library which is used by all these 3 application. That common library fetch the external configuration file which is located in the the current running directory. For example
ASP.NET - > c:\MySite\appconfig.xml
CONSOLE -> C:\MyConsoleApplication\appconfig.xml
SSIS -> c:\MySSISPakage\appconfig.xml
I used the following code to fetch the current running application path to fetch the appconfig.xml file
string appPath = AppDomain.CurrentDomain.BaseDirectory;
In the web application it is running file and returning the path
c:\MySite.
But in the console application it is return the path
C:\MyConsoleApplication\bin\debug
. I need to fetch the path
C:\MyConsoleApplication
for the console application. Any idea?

You can Find Parent Directory using Directory.GetParent
try like this:
Program is name of any class in your project
string path = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Program)).Location);
Console.WriteLine(Directory.GetParent(Directory.GetParent(path).ToString()).ToString());

Related

Excel files are not being read when executing Selenium C# Scripts on Azure Releases

I have some Selenium C# tests hosted on Azure which they need to look for the pre-built excel file in project tree, stored inside bin folder, to execute some file upload validation scenarios.
When they are executed locally these scenarios pass without any problem, but when it comes to be executed on the Azure they receive the following error.
invalid argument: File not found : D:\a\r1\a_Selenium_Tests\TestApplication\bin\Debug\netcoreapp3.1\Files\SC003_CT014_ActiveEmployees.xlsx
The files do exists in the following path: ...\bin\Debug\netcoreapp3.1\Files...
And the code I use to them is:
string root = Directory.GetCurrentDirectory() + "\\Files\\" + file;
Do you know if there's a missing file configuration or building the filePath in another way?
Thanks for your help :D
Directory.GetCurrentDirection() returns the current working directory, not the folder in which the DLL file resides. The current working directory is a different thing. In your case, the current working directory is probably something like D:\a\r1\. Instead, you need to get the folder in which the test assembly resides:
var binDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
// ^^^^^^^^^
var excelFilePath = Path.Combine(binDirectory, "Files", "SC003_CT014_ActiveEmployees.xlsx");
Note: Replace GetType() with typeof(ClassName) if you are executing your code from a static method, or you would like to specify a path to a different assembly than the one that is currently executing.

C# Console app : Read a file from disk both when ran as standalone and when ran from ASP.NET app

I want to know how to be able to read a text file from both :
when running as a standalone
and
when running from a host ASP.NET app.
I am aware of the Server.MapPath command but it only works on the ASP.NET app and I want the file loading to be done from the console application.
Let's begin with an empty project and create two projects :
First, a Console application :
Then, a ASP.NET MVC application :
Once we have our two projects, let's create a text file :
And put something in there :
Make sure it is included in the bin folder :
Now, we can finally read the file content like this :
Using the following code :
We get the desired output.
Now, as stated in the beginning of this post, I want to be able to access the file from the same project, but called from the ASP.NET app.
Let's add the console app as a project dependency of TestWebApp :
And call it's method like so :
Now I get this error :
I want to know how I would go on and be able to load the file both when running the app by itself (console app) or when running from a host web service (asp.net web server).
Use AppContext.BaseDirectory. This is the directory for which the runtime checks to resolve assemblies. In your context, this is the closest to the output directory.
Now there is a difference between what it returns for the Console App vs Web App. The below common code would address both.
var appContextBase = AppContext.BaseDirectory;
var filePath = appContextBase.IndexOf("bin", StringComparison.OrdinalIgnoreCase) == -1 ? "bin/Files/File.txt" : "Files/File.txt";
var fileContent = File.ReadAllText(appContextBase + filePath);
Console.WriteLine(fileContent);
For Console App, AppContext.BaseDirectory returns something like this - "C:\\Users\\user123\\Documents\\Visual Studio 2017\\Projects\\MySamples\\MySamples\\bin\\Debug\\"
For Web App, it returns something like this - "C:\\Users\\user123\\Documents\\Visual Studio 2017\\Projects\\MySamples\\MyWebApp\\"
That is the reason I have added the ternary operator check on the filePath.

Why can't my WebAPI service call find part of the path to a folder via IIS?

I have .NET Core WebAPI 2.1 services. I created a structure in my deployment folder like below. (I'm using IIS.) I want to access MyVariables.json from all services. But, it gave this error:
Could not find a part of the path 'C:\wwwroot\MyProject\Shared\MyVariables.json'.
But that folder and path do exist. I'm trying by this code from my C# service.
using (StreamReader file =File.OpenText(#"../Shared/MyVariables.json"))
{
}
What can be the reason of this?
My publish folder design
-wwwroot
-MyProject
+Service1
+Service2
+Service3
+Service4
-Shared
MyVariables.json
IIS runs with an identity that is configured in the App pool.
Directory access rights must be given to the identity used to run the App pool.
Start inetmgr.exe to configure IIS,find App Pool identity and then configure access in file explorer.
Reference: https://learn.microsoft.com/en-us/iis/manage/configuring-security/application-pool-identities

C# ClickOnce Deployment Mapping Back to My Desktop Drive

I created a WinForms application that includes code to find the user's desktop and perform 3 tasks:
1. Create a folder
2. Read a .csv file
3. Output some data to a .csv file on the desktop.
I'm using the code below to find the user's desktop
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
I used the ClickOnce deployment to install the program to our network drive. The program installs successfully, but Whenever I have someone attempt to run the program from their terminal, they get an error message that states "The directory name is invalid" and it references my desktop and not the user's.
How should I change my code or the deployment method so it references the user's desktop?
If directory invalid try creating it
Try with this code
string filePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string extension = ".log"; filePath += #"\Error Log\" + extension;
if (!Directory.Exists(filePath)) {
Directory.CreateDirectory(filePath);
}
I made the following change to my code and it worked as needed:
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

Application root path

I've recently been having some issues with correctly discovering application root path in c#. I want my applications to use the correct folder in following instances:
web application in debug (visual studio)
web application in release
deployed web application
console application in debug
console application in release
deployed console application
windows service (really same as console application)
Namely I need this for a logging assembly which is shared across all those types of applications. It's using log4net and it needs to correctly resolve physical path internally - inside logging assembly.
Because log4net requires either a call to BasicConfiguration.Configure to load it from web.config / app.config. Issue with this is it doesn't set up a file watcher so changes are not monitored. Solution is to have a log4net.config file separately.
Now, I don't like placing things inside bin, bin/debug or bin/release folder since it is never included in source control. Instead for things like that I have a Config folder in application root. So that you end up with ~\Application\Config\log4net.config.
In the static logger there are 2 methods:
public static string GetRootPath()
{
var debugPath = string.Empty;
#if (DEBUG)
debugPath = "..\\..\\";
#endif
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, debugPath);
}
public static void Init(string loggerName)
{
LoggerName = loggerName;
XmlConfigurator.Configure(new FileInfo(Path.Combine(GetRootPath(), "Config\\log4net.config")));
}
So you can just call Logger.Init() in Application_Start or inside Main() for console apps. This works great for console applications but not for web applications since AppDomain.CurrentDomain.BaseDirectory points to web application root and not to it's bin folder (which also has no debug or release).
Has anyone got a reliable way to resolve root path for all above requirements? So - what should GetRootPath be doing?
PS: I know I could be checking if (HttpContext.Current != null) then don't merge debug path in but there must be a more elegant way?
You could use the CodeBase property of the Assembly class to determine the path to the executing assembly:
public static string GetRootPath()
{
var debugPath = string.Empty;
#if (DEBUG)
debugPath = "..\\..\\";
#endif
return Path.Combine(Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase).LocalPath), debugPath);
}
Note, for web applications and windows services the file path is in file URI scheme format. So, I use the Uri class to convert the path to standard windows path format.
Hope, this helps.

Categories