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");