How do I get the name of the current executable in C#?
Asked Answered
P

21

423

I want to get the name of the currently running program, that is the executable name of the program. In C/C++ you get it from args[0].

Psittacine answered 5/3, 2009 at 21:0 Comment(1)
Executable is EXE file (Windows Forms, WPF applications) ? A program can be a Desktop App (WinForms, WPF; and WinRT-Windows Phone?), Web Application, Wcf Service Application, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest), or, Silverlight Application.Miscue
S
464
System.AppDomain.CurrentDomain.FriendlyName
Skimmer answered 5/3, 2009 at 21:33 Comment(17)
Beware of accepted answer. We've had issues with using System.AppDomain.CurrentDomain.FriendlyName under Click-Once deployed applications. For us, this is returning "DefaultDomain", and not the original exe name.Paranoiac
@Paranoiac thanks for the heads up! So how did you get around this?Skimmer
We used this in the end: string file = object_of_type_in_application_assembly.GetType().Assembly.Location; string app = System.IO.Path.GetFileNameWithoutExtension( file ); Paranoiac
FriendlyName can be set to anything. Also getting the assembly location may not be enough if you have an exe with several dlls. Furthermore if you use several AppDomain, Assembly.GetCallingAssembly() returns null.Blacktail
@Paranoiac : it would be easier just to say Path.GetFileNameWithoutExtension(GetType().Assembly.Location) - you don't need to specify an object of a type in the current assembly. You can use GetType of this, and then you don't even need to say "this."Timekeeper
friendly name returned by this call gives me C:\Users\root\AppData\Roaming\myapp.vshost.exe vshost.exe part is hardly something that I wanted to get back...Ardel
@Califf: that looks like the VS debugging .exe host name; are you running a debug version, perhaps through visual studio?Skimmer
@Steven I would prefer to use something that returns a consistent name in both Debug and Release modes, for example if is to be used to create a data profile name for the app in user's directory. So far, the Lee Grissom's answer satisfies this requirement. Sorry I somehow missed it last time.Ardel
Not the same ProcessName, FriendlyName, ModuleName and ApplicationName (AppDomain.CurrentDomain, Process, Process.MainModule). ProcessName: vstest.executionengine.x86 ConfigurationFile: C:\TFS\Tests\bin\Debug\Tests.v4.0.dll.config MainModule.FileName: C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 11.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\vstest.executionengine.x86.exe MainModule.ModuleName: vstest.executionengine.x86.exe BaseDirectory: C:\TFS\Tests\bin\Debug ApplicationBase: C:\TFS\Tests\bin\Debug FriendlyName: UnitTestAdapter: Running test ApplicationName:Miscue
This property can return unexpected values. I've used it in unit test and it has "UnitTestAdapter: Running test" value (which is not valid filename)Etruria
@Timekeeper : true, it's just that in the case we used it the code was not in the exe but an associated assembly.Paranoiac
@Gaspode, What is the issue you had with "with using System.AppDomain.CurrentDomain.FriendlyName under Click-Once deployed applications"? Thank you.Truancy
@Frank, "For us, this is returning "DefaultDomain", and not the original exe name." I'm not sure what more you want to know.Paranoiac
This can be useful, but it should not be the accepted answer: It is vastly different from what was asked for - it will coincidentally be the same thing in some situations, but this is something else entirely. If you didn't write the application yourself it could very well return "I like potatoes!" or whatever else your humorous colleague wrote into this property when they built the application!Flume
System.AppDomain.CurrentDomain.FriendlyName.Substring(0,System.AppDomain.CurrentDomain.FriendlyName.IndexOf(".")) - because I need name without extensionSatang
Is it possible to have that information as a constant expression? I'd like to it in a decorator.Hoffman
@Hoffman No. It's not constant. (It has to be evaluated at run time.)Sexpartite
B
331

System.AppDomain.CurrentDomain.FriendlyName - Returns the filename with extension (e.g. MyApp.exe).

System.Diagnostics.Process.GetCurrentProcess().ProcessName - Returns the filename without extension (e.g. MyApp).

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName - Returns the full path and filename (e.g. C:\Examples\Processes\MyApp.exe). You could then pass this into System.IO.Path.GetFileName() or System.IO.Path.GetFileNameWithoutExtension() to achieve the same results as the above.

Backsight answered 25/2, 2011 at 16:56 Comment(7)
AppDomain can be a EXE application, Web application, Unit test application, Addin Visual Studio, and "Silverlight App"(?). Maybe interesting full solution for all cases. For example, for Unit Test VS2012 - ProcessName: vstest.executionengine.x86 MainModule.FileName: C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 11.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\vstest.executionengine.x86.exe MainModule.ModuleName: vstest.executionengine.x86.exe FriendlyName: UnitTestAdapter: Running test ApplicationName:Miscue
A "program" can be a Desktop App (WinForms, WPF; and WinRT-Windows Phone?), Web Application, Wcf Service Application, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest), or, Silverlight Application. For example, how get service Host assembly for a Wcf Service Application hosted in IIS, not IISExpress or WebDevServer ?Miscue
+1 I’m going to go with this answer because it provides all three variations that you might need in a clean and simple way. Using the bare program name without path or extension is very useful for in-program help text (/? switch), because using the extension and path just clutter it unnecessarily.Stretchy
Remember to dispose the result of GetCurrentProcess()Dyane
Process.GetCurrentProcess().ProcessName() returns MyApp.vshost for me.Feverous
Under Mono on Linux, Process.GetCurrentProcess().MainModule.FileName returned /usr/bin/mono-sgen. The GetType().Assembly.Location approach returned the desired executable path for both Linux and Windows.Clementineclementis
With Mono runtime at least "System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName" works but "System.AppDomain.CurrentDomain.FriendlyName" does not FYI.Frau
C
121

This should suffice:

Environment.GetCommandLineArgs()[0];
Corroboree answered 5/3, 2009 at 21:3 Comment(10)
Hmm, this returns (when run from vs.net and using the debug hosting thing), the location and name of the filename.vshost.exe ... that is indeed the file that is executing at this time )Destructive
This the best answer for me because Environment.GetCommandLineArgs() is the exact C# analogue of argv from C/C++.Kuhlman
Agreed! best answer. I have a need to get Environment.GetCommandLineArgs()[1];Allium
Works on Mono/Linux. The returned string is the full path to the exe running without the "mono " part that would be really bothersome if present. As said before this is exact analogue of C/C++ main function argv parameter.Immaterial
To avoid full path: Path.GetFileNameWithoutExtension(Environment.GetCommandLineArgs()[0])Polinski
This won't always supply the full path, as opposed to System.Diagnostics.Process.GetCurrentProcess().MainModule.FileNameIverson
If you copy the executable and run the two copies with different names, this returns only the most recently started executable in the AppDomain. Process.GetCurrentProcess().MainModule.FileName does not have this static problem,Wende
If the exe is started without ".exe" (e.g. from command line), this solution will give the executable name without ".exe".Hidden
This works well when trying to track down WCF services. The process name comes back with iisexpress in my case. But this command gives me the actual WCF service assembly name.Refund
When using .NET 6+ use: Environment.ProcessPath (see: learn.microsoft.com/en-us/dotnet/api/… )Melpomene
T
116

System.Diagnostics.Process.GetCurrentProcess() gets the currently running process. You can use the ProcessName property to figure out the name. Below is a sample console app.

using System;
using System.Diagnostics;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Process.GetCurrentProcess().ProcessName);
        Console.ReadLine();
    }
}
Tailband answered 5/3, 2009 at 21:3 Comment(9)
Better use Process.GetCurrentProcess().MainModule.FileNameInsipid
Process.GetCurrentProcess().MainModule.FileName works perfectly from within an Excel Addin (ExcelDNA)Gui
This approach will fail when used on the Mono runtime; the process name for applications running on Mono will always be some variant of .../bin/mono on *nixes or .../mono.exe on Windows.Defaulter
This should be the accepted answer. Current AppDomain name may have nothing to do with executable process name, especially when multiple app domains are presentHypha
This method can be substantially slower than playing with the Assembly class.Specular
@cdhowie, Could you recover the entire process invocation string such as :"/usr/bin/mono/mono /home/richard/test/foo.exe" ? Thank you.Truancy
@Truancy Perhaps using OS-specific tricks, such as reading /proc/self/cmdline. (var args = File.ReadAllText("/proc/self/cmdline").Split('\0'); args = args.Take(args.Length - 1).ToArray(); would give you an array of such arguments.)Defaulter
@Truancy Environment.CommandLine should be the invocation string. Could be that mono filters itself out from it - or not - I haven't tested it on a linux machine myself so you would have to test it yourself. (I think it does filter away the mono-part since some applications could have behavior that depends on this property - and they probably wont be expecting it to be prefixed by mono "stuff".)Flume
Fails in .NET Core - "dotnet.exe" - (as well as Mono, for the same / similar reason).Chobot
I
21

This is the code which worked for me:

string fullName = Assembly.GetEntryAssembly().Location;
string myName = Path.GetFileNameWithoutExtension(fullName);

All the examples above gave me the processName with vshost or the running dll name.

Icy answered 20/6, 2012 at 13:12 Comment(3)
For those that dont know, or missed it in other answers, the namespace for Assembly is System.Reflection, and the namespace for Path is System.IO.Appellee
GetEntryAssembly will return null if the application entry point is in native code rather than an assembly.Normanormal
Beware this crashes with .net 5 and single file assembliesStanchion
G
19

Try this:

System.Reflection.Assembly.GetExecutingAssembly()

This returns you a System.Reflection.Assembly instance that has all the data you could ever want to know about the current application. I think that the Location property might get what you are after specifically.

Gammon answered 5/3, 2009 at 21:1 Comment(5)
It might be safer to use CodeBase instead of Location in case .NET's shadow copy feature is active. See blogs.msdn.com/suzcook/archive/2003/06/26/…Kor
Beware of GetExecutingAssembly(): if you call this from a library assembly, it returns the name of the library assembly, which is different from the name of the entry assembly (i.e. the original executable). If you use GetEntryAssembly(), it returns the name of the actual executable, but it throws an exception if the process is running under WCF (admittedly a rare situation). For the most robust code, use Process.GetCurrentProcess().ProcessName.Insensate
@Gravitas: Certainly not, any executable that is running "interpreted", e.g. with /usr/bin/mono will have the wrong process name. Also ProcessName won't work with windows services. If you use it in a library, use GetCallingAssembly.Acetum
Worked for me. The property Name of the returned Assembly instance GetName() call is what you need, and does not include the ".exe" part. Also tested on Mono/Linux with expected result. Assembly.GetName().NameImmaterial
Hmm, note that the returned string won't change even if you rename the executable file by hand using the file explorer. While Environment.GetCommandLineArgs()[0] changes along with the actual executable filename (of course). Coincidentally, the second method resulted better for my specific situation as I want the data folder to be named as the actual executable filename.Immaterial
O
12

Why nobody suggested this, its simple.

Path.GetFileName(Application.ExecutablePath)
Oddment answered 24/4, 2014 at 12:52 Comment(4)
Which namespace does Application resides.Beaner
This is useful when inside a Windows Forms app, but not otherwiseDesigning
@Designing You might be interested in Application.ExecutablePath's source code.Samovar
@Designing See my post. This works within Console apps if you add a reference to System.Windows.Forms.Round
S
11

Couple more options:

  • System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
  • Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
Stodder answered 2/1, 2011 at 22:5 Comment(1)
see #617084Schaffer
G
11
System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.Name;

will give you FileName of your app like; "MyApplication.exe"

Generalship answered 9/4, 2013 at 14:6 Comment(0)
E
10

If you need the Program name to set up a firewall rule, use:

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

This will ensure that the name is correct both when debugging in VisualStudio and when running the app directly in windows.

Extemporary answered 29/4, 2016 at 17:25 Comment(2)
For my purposes (creating a logging filename), this is the best answer. If running a hosted process (say, a service, or a web application), System.AppDomain.CurrentDomain.FriendlyName can return an ugly GUID-y name with embedded slashes.Unpen
This does not work for .NET Core 2+, which will report "dotnet.exe" - or perhaps the apphost if setup as such.Chobot
P
9

When uncertain or in doubt, run in circles, scream and shout.

class Ourself
{
    public static string OurFileName() {
        System.Reflection.Assembly _objParentAssembly;

        if (System.Reflection.Assembly.GetEntryAssembly() == null)
            _objParentAssembly = System.Reflection.Assembly.GetCallingAssembly();
        else
            _objParentAssembly = System.Reflection.Assembly.GetEntryAssembly();

        if (_objParentAssembly.CodeBase.StartsWith("http://"))
            throw new System.IO.IOException("Deployed from URL");

        if (System.IO.File.Exists(_objParentAssembly.Location))
            return _objParentAssembly.Location;
        if (System.IO.File.Exists(System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName))
            return System.AppDomain.CurrentDomain.BaseDirectory + System.AppDomain.CurrentDomain.FriendlyName;
        if (System.IO.File.Exists(System.Reflection.Assembly.GetExecutingAssembly().Location))
            return System.Reflection.Assembly.GetExecutingAssembly().Location;

        throw new System.IO.IOException("Assembly not found");
    }
}

I can't claim to have tested each option, but it doesn't do anything stupid like returning the vhost during debugging sessions.

Parrisch answered 8/1, 2012 at 3:19 Comment(2)
+1 for amusement. :-) I would hardly use this code, though, unless I'm writing a really generic library that has no idea about its environment (and then it probably wouldn't be a good idea to maintain whatever global state you were going to use the name for).Diagram
@Parrisch A "program" can be a Desktop App (WinForms, WPF; and WinRT-Windows Phone?), Web Application, Wcf Service Application, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest), or, Silverlight Application. For example, how get service Host assembly for a Wcf Service Application hosted in IIS, not IISExpress or WebDevServer ? Any full code valid for A WinForms, WPF, Web Application, Wcf Service Application, Visual Studio Addin, Outlook-Word Addin, Unit Test in VS (MSTest) applications ?Miscue
M
8
  • System.Reflection.Assembly.GetEntryAssembly().Location returns location of exe name if assembly is not loaded from memory.
  • System.Reflection.Assembly.GetEntryAssembly().CodeBase returns location as URL.
Maori answered 26/1, 2010 at 16:8 Comment(2)
Tested, this works 100%, even if its called from within a C# library.Insensate
GetEntryAssembly() returns null if you're not in the main AppDomain.Blacktail
D
6

If you are publishing a single file application in .NET 6.0 or above, you can use Environment.ProcessPath

Donaghue answered 29/12, 2021 at 18:7 Comment(1)
For current WPF (as of 2023), this delivers the expected EXE name. All the others return the created DLL which is slightly different from what I want (the exe). Thank you.Bramble
A
4

This works if you need only the application name without extension:

Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName);
Arista answered 23/5, 2018 at 8:3 Comment(0)
G
3

You can use Environment.GetCommandLineArgs() to obtain the arguments and Environment.CommandLine to obtain the actual command line as entered.

Also, you can use Assembly.GetEntryAssembly() or Process.GetCurrentProcess().

However, when debugging, you should be careful as this final example may give your debugger's executable name (depending on how you attach the debugger) rather than your executable, as may the other examples.

Gudgeon answered 5/3, 2009 at 21:4 Comment(4)
Beware of GetExecutingAssembly(): if you call this from a library assembly, it returns the name of the library assembly, which is different from the name of the entry assembly (i.e. the original executable). If you use GetEntryAssembly(), it returns the name of the actual executable, but it throws an exception if the process is running under WCF (admittedly a rare situation). For the most robust code, use Process.GetCurrentProcess().ProcessName.Insensate
@Gravitas: good point - wow, it's been a while since I wrote this! :D I'll edit accordinglyGudgeon
Environment.CommandLine gives the absolute path, not the entered command line, at least on Mono/Linux.Doersten
@Mechanicalsnail: Sounds like Mono doesn't quite follow the documentation. Interesting.Gudgeon
A
3

IF you are looking for the full path information of your executable, the reliable way to do it is to use the following:

   var executable = System.Diagnostics.Process.GetCurrentProcess().MainModule
                       .FileName.Replace(".vshost", "");

This eliminates any issues with intermediary dlls, vshost, etc.

Anu answered 14/3, 2013 at 6:1 Comment(4)
I tried your reliable way in Ubuntu Linux 15.10 C++ using realpath followed by STL C++ string replace and it caused Point and Click to fail. Could that have been caused by a bug in mono as our director of software surmised today? Thanks.Truancy
I don't program on Mono, though it might be fun to tryAnu
Gasponde wrote above that "We've had issues with using System.AppDomain.CurrentDomain.FriendlyName under Click-Once deployed applications." Could you make a guess as to what the issues might be with Click-Once deployed applications in .NET? Thanks.Truancy
Returns C:\Program Files\dotnet\dotnet.exe for my Sample program in VS2017.Guillory
D
1

Is this what you want:

Assembly.GetExecutingAssembly ().Location
Destructive answered 5/3, 2009 at 21:3 Comment(2)
Beware of GetExecutingAssembly(): if you call this from a library assembly, it returns the name of the library assembly, which is different from the name of the entry assembly (i.e. the original executable). If you use GetEntryAssembly(), it returns the name of the actual executable, but it throws an exception if the process is running under WCF (admittedly a rare situation). For the most robust code, use Process.GetCurrentProcess().ProcessName.Insensate
An answer should not be a question. Is that what the OP wanted?Guillory
M
1

Super easy, here:

Environment.CurrentDirectory + "\\" + Process.GetCurrentProcess().ProcessName
Monarch answered 3/2, 2017 at 18:13 Comment(2)
For .NET Core Process.GetCurrentProcess().ProcessName returns "dotnet".Knap
The current directory is temporally transient and cannot be relied on to be the location of the assembly/executable.Guillory
C
1

On .Net Core (or Mono), most of the answers won't apply when the binary defining the process is the runtime binary of Mono or .Net Core (dotnet) and not your actual application you're interested in. In that case, use this:

var myName = Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
Cedar answered 31/3, 2017 at 21:53 Comment(1)
GetEntryAssembly() can return null.Chobot
R
0

For windows apps (forms and console) I use this:

Add a reference to System.Windows.Forms in VS then:

using System.Windows.Forms;
namespace whatever
{
    class Program
    {
        static string ApplicationName = Application.ProductName.ToString();
        static void Main(string[] args)
        {
            ........
        }
    }
}

This works correctly for me whether I am running the actual executable or debugging within VS.

Note that it returns the application name without the extension.

John

Round answered 15/7, 2017 at 0:6 Comment(0)
H
-2

To get the path and the name

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

Highborn answered 7/2, 2020 at 21:5 Comment(1)
This duplicates this answer and this answer.Hastings

© 2022 - 2024 — McMap. All rights reserved.