Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I find the current executable filename? [duplicate]

Tags:

c#

.net

Possible Duplicate:
How do I get the name of the current executable in C#?

An executable file loads an external library.
Is there a way for the library to know the calling executable file?

(I would have sworn I saw the answer to this elsewhere, but I can't seem to find it anymore)

like image 207
Boris Callens Avatar asked Jun 11 '09 09:06

Boris Callens


3 Answers

EDIT:

As of .NET 6, the recommended approach (CA1839) is to use System.Environment.ProcessPath


Original answer:

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
like image 192
Thomas Levesque Avatar answered Nov 06 '22 23:11

Thomas Levesque


If you want the executable:

System.Reflection.Assembly.GetEntryAssembly().Location

If you want the assembly that's consuming your library (which could be the same assembly as above, if your code is called directly from a class within your executable):

System.Reflection.Assembly.GetCallingAssembly().Location

If you'd like just the filename and not the path, use:

Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location)
like image 37
Matt Brindley Avatar answered Nov 07 '22 01:11

Matt Brindley


In addition to the answers above.

I wrote following test.exe as console application

static void Main(string[] args) {
  Console.WriteLine(
    System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
  Console.WriteLine(
    System.Reflection.Assembly.GetEntryAssembly().Location);
  Console.WriteLine(
    System.Reflection.Assembly.GetExecutingAssembly().Location);
  Console.WriteLine(
    System.Reflection.Assembly.GetCallingAssembly().Location);
}

Then I compiled the project and renamed its output to the test2.exe file. The output lines were correct and the same.

But, if I start it in the Visual Studio, the result is:

d:\test2.vhost.exe

d:\test2.exe

d:\test2.exe

C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll

The ReSharper plug-in to the Visual Studio has underlined the

System.Diagnostics.Process.GetCurrentProcess().MainModule

as possible System.NullReferenceException. If you look into documentation of the MainModule you will find that this property can throw also NotSupportedException, PlatformNotSupportedException and InvalidOperationException.

The GetEntryAssembly method is also not 100% "safe". MSDN:

The GetEntryAssembly method can return null when a managed assembly has been loaded from an unmanaged application. For example, if an unmanaged application creates an instance of a COM component written in C#, a call to the GetEntryAssembly method from the C# component returns null, because the entry point for the process was unmanaged code rather than a managed assembly.

For my solutions, I prefer the Assembly.GetEntryAssembly().Location.

More interest is if need to solve the problem for the virtualization. For example, we have a project, where we use a Xenocode Postbuild to link the .net code into one executable. This executable must be renamed. So all the methods above didn't work, because they only gets the information for the original assembly or inner process.

The only solution I found is

var location = System.Reflection.Assembly.GetEntryAssembly().Location;
var directory = System.IO.Path.GetDirectoryName(location);
var file = System.IO.Path.Combine(directory, 
  System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe");
like image 42
Alexander Zwitbaum Avatar answered Nov 07 '22 00:11

Alexander Zwitbaum