184

I found solutions for Windows Forms with AppDomain but what would be the equivalent for a WPF Application object?

Joey
  • 344,408
  • 85
  • 689
  • 683

9 Answers9

363

One method:

System.AppDomain.CurrentDomain.BaseDirectory

Another way to do it would be:

System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName)
Doug
  • 5,116
  • 10
  • 33
  • 42
Helen
  • 87,344
  • 17
  • 243
  • 314
  • Ah, thanks. Must have overlooked AppDomain somehow. I was looking for it, actually ... – Joey Jun 02 '09 at 12:34
  • Doesn't appear to be available in VS.Net 2010 / WPF 4 – AndyD273 Aug 19 '11 at 19:32
  • @AndyD273: Works for me. Are you missing a `using` directive or an assembly reference? – Helen Aug 28 '11 at 18:45
  • 3
    @Helen: Judging from the upvotes, this is obviously an excellent answer. However, the answer has two ways of getting the app dir. Will they both work equally well? – Christoffer Lette Aug 29 '11 at 15:34
  • @ChristofferLette: Honestly, I don't know .NET/WPF that well to think of a condition when they won't. – Helen Aug 31 '11 at 17:28
  • @Helen: Good question... I've done a bunch of stuff to the project since then, and when I just tried it again, it was showing up. Guess I was either out of it that day or I included some stuff since then that made it available. Either way, my apologies. – AndyD273 Aug 31 '11 at 18:11
  • 24
    I would use the first alternative. It looks simpler, doesn't have a method call and causes less doubt on what the line actually does when reading. – Filip Oct 21 '11 at 03:11
  • 4
    I've used the first method in a WCF service, in a WPF Application and in a Class Library project and worked fine in all. – Apostrofix Nov 25 '15 at 12:21
  • 1
    For NetCore and NetStandard, I would recommend the second one, because AppDomain was added in 2.0 and could not be always set as expected – cdie Oct 05 '17 at 13:22
31

Here is another:

System.Reflection.Assembly.GetExecutingAssembly().Location
Eddie Butt
  • 493
  • 3
  • 4
  • 2
    This one gets the location after _shadow-copying_, as stated [in the docs](http://msdn.microsoft.com/en-us/library/system.reflection.assembly.location.aspx). I'm actually not sure if the suggestions in the accepted answer is affected by shadow-copying. – Christoffer Lette Sep 07 '11 at 08:02
  • 2
    This gave me the sub directory of the DLL I was calling, not the main program directory. – strattonn Jun 16 '14 at 09:14
8

You can also use the first argument of the command line arguments:

String exePath = System.Environment.GetCommandLineArgs()[0]

Dr. Rajesh Rolen
  • 14,029
  • 41
  • 106
  • 178
Flip
  • 81
  • 1
  • 1
  • 1
    However, note that an "evil" application can modify its command line arguments. – Daniel Rose Apr 20 '11 at 14:34
  • @Daniel: Why would it do it to itself? Or do you mean a different application? – Merlyn Morgan-Graham Aug 28 '11 at 18:50
  • 1
    @Merlyn: See http://blogs.msdn.com/b/oldnewthing/archive/2009/11/25/9928372.aspx I'll quote: it is a "conveniently initialized parameter to the process's startup code." So you can deliberately or inadvertently modify that memory location. – Daniel Rose Aug 29 '11 at 07:46
  • 1
    @Daniel: Who can? Another process, or the same process? If you shoot yourself in the foot, it should be easy to track down. I'd call that less evil, and more stupid :) If another process can do it, then that is more interesting. Edit: I don't see anything in that article about modifying a running program's command line - only that the launching process passes it in (not sure it is undesirable for the launching process to change the command line), and that you can query it via WMI. – Merlyn Morgan-Graham Aug 29 '11 at 17:44
  • @MerlynMorgan-Graham a malicious application can modify the memory address, and force your application to run another one of their malicious application instead. This is evil, because let's say their application is a keylogger and they want it to activate as soon as you open up a sepcific application. So in their code they'll capture your application name, run their keylogger in the background, and then run your application. The user will be clueless. The article does explain this, but it doesn't tell you how to do it. Maybe that's what you were looking for? – pqsk Jun 26 '14 at 14:53
  • @pqsk: I understand fully how code injection can lead to an Information Disclosure threat. The point I am making is there is no exploitable code injection vector described in the article or any of the comments here. The worst thing that can be done is a process invoking your process can pass you a string that isn't the name/path of the executable you're running. Once you're running, the argument won't change unless you hack it yourself, and neither windows nor .Net will somehow cause that "memory" to be executed, instead of just being interpreted as a string. Comments here are crying wolf. – Merlyn Morgan-Graham Jul 02 '14 at 18:20
  • @MerlynMorgan-Graham, I know your point was about the article and what Daniel had said, but my point was the actual issue. If you think once the program is running that this is not possible and only the user themselves can do this, then I guess you don't understand very well. Perhaps an understanding of how memory works and how the kernel works would help a little bit. I'm not sure what level you are in, but I guess not in the level to know some of these things. You don't need a BS in CS to understand these things. Honestly just google away...the computer just executes commands 1s & 0s... – pqsk Jul 02 '14 at 21:52
  • @pqsk: You can't alter another process's memory space simply because you have google ;) That's called a security vulnerability. What's the entry point to getting access to that running process's address space? Which API? Show me sample code. Onus is on you, bud. If it requires admin access to inject the code, then it isn't a vulnerability, and people need not be warned. – Merlyn Morgan-Graham Jul 03 '14 at 18:47
  • @MerlynMorgan-Graham, sorry I am a CS student, not a Google search student as some. There is such thing as vulnerabilities (as you ironically stated), although ASLR addresses those. There is no such thing as a system that is 100% secure (even Linux, but we're talking about Windows lol). Granted someone would have to target someone or a group for that to happen. One thing I've learned from school, always assume the user is a malicious user. My point here is that it IS possible and NOT impossible. You should be aware of these things and not to always trust the user. – pqsk Jul 04 '14 at 01:52
7

I used simply string baseDir = Environment.CurrentDirectory; and its work for me.

Good Luck

Edit:

I used to delete this type of mistake but i prefer to edit it because i think the minus point on this answer help people to know about wrong way. :) I understood the above solution is not useful and i changed it to string appBaseDir = System.AppDomain.CurrentDomain.BaseDirectory; Other ways to get it are:

1. string baseDir =   
    System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
 2. String exePath = System.Environment.GetCommandLineArgs()[0];
 3. string appBaseDir =    System.IO.Path.GetDirectoryName
    (System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);

Good Luck

QMaster
  • 3,743
  • 3
  • 43
  • 56
  • 3
    That's the current working directory. It *may* conincide with the application directory but those are separate concepts (and most importantly, the working directory can change, e.g. if you had a common file dialog open). – Joey Dec 12 '12 at 10:11
  • 1
    @joey you are right. I changed it to this: string appBaseDir = System.AppDomain.CurrentDomain.BaseDirectory; Thanks. – QMaster Dec 23 '12 at 06:56
3

Try this. Don't forget using System.Reflection.

string baseDir = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Roshan J
  • 39
  • 2
3
String exePath = System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName;
 string dir = Path.GetDirectoryName(exePath);

Try this!

Arsen Mkrtchyan
  • 49,896
  • 32
  • 148
  • 184
1

I tried this:

    label1.Content = Directory.GetCurrentDirectory();

and get also the directory.

paul
  • 96
  • 2
  • This gets the current working directory, which can be different from the process directory. – Thraka Jun 06 '14 at 19:35
  • I guess I have to evaluate Directory.GetCurrentDirectory(); more. Thank you @Thraka for correction. – paul Aug 11 '14 at 04:10
1

Just thought I'd add an updated answer for those who need it.

I used to use: My.Application.Info.DirectoryPath to get my applications path. It seems NET6 didn't like this. After using one of the examples below, I noticed IntelliSense suggested this: Environment.ProcessPath

Thus, to get the path to the application exe:

Environment.ProcessPath

To get the folder:

Path.GetDirectoryName(Environment.ProcessPath)

Hope this helps.

video.baba
  • 817
  • 2
  • 6
  • 11
  • `My` is part of Visual Basic, so perhaps your C# project just has to reference the relevant VB assembly explicitly. – Joey Apr 04 '22 at 08:44
  • Yes, VB. I don't do C#. – video.baba Apr 04 '22 at 10:55
  • My still exists as when using VB with .NET framework, but with .NET (.NET 5, .NET 6, etc) it is mostly removed. Haven't checked .NET core, .NET standard, etc. Also, gotta love the naming strategy MS had with the entire .NET franchise. OG is .NET framework, while .net is the newest iteration. – Wolf-Kun Feb 22 '23 at 17:26
0

You can also use freely Application.StartupPath from System.Windows.Forms, but you must to add reference for System.Windows.Forms assembly!

crash
  • 9
  • 1
  • 1