MSDN says your assembly's file name should be assembly's simple name, plus .dll/.exe. The reason is those are what we probe. Remember the probing rule?

But your-app.exe can be an exception. The exe may have an assembly name of “MyAsm”. But the file name can be anything.

The reason it works is because there is a special logic in runtime for the exe. CLR Loader will register the exe as a KNOWN assembly in fusion's binding context. Later when you try to bind to the assembly using the assembly name, we will return the exe to you.

But only in the default domain!

Here is an example:
Save the following code as Hello.cs, compile it, rename it to Hello1.exe, run Hello1.exe. You will see Hello1.exe's path is printed.

using System;
using System.Reflection;

class Test
{
    public static void Main()
    {
        Assembly asm1 = Assembly.Load("Hello, Version=0.0.0.0, Culture=Neutral, PublicKeyToken=NULL");
        Console.WriteLine(asm1.Location);
    }
}

Now let's change the code a little bit and do the same thing.

using System;
using System.Reflection;

class Test
{
    public static void Main()
    {
        Assembly asm1 = Assembly.Load("Hello, Version=0.0.0.0, Culture=Neutral, PublicKeyToken=NULL");
        Console.WriteLine(asm1.Location);
        AppDomain ad = AppDomain.CreateDomain("Second");
        Assembly asm2 = ad.Load("Hello, Version=0.0.0.0, Culture=Neutral, PublicKeyToken=NULL");
        Console.WriteLine(asm2.Location);
    }
}

You will see an exception throw in ad.Load().

The load is explicit in my example. But it could be implicit in many cases. Like if you use a type defined in your-app.exe in the second domain, Assembly.Load will be called.

DO NOT change the name of your-app.exe.