20

My C# application writes its full path surrounded by double quotes to a file, with:

streamWriter.WriteLine("\"" + Application.ExecutablePath + "\"");

Normally it works, the written file contains

"D:\Dev\Projects\MyApp\bin\Debug\MyApp.exe"

But, if the executable path of my application contains a #, something weird happens. The output becomes:

"D:\Dev\Projects#/MyApp/bin/Debug/MyApp.exe"

The slashes after the # become forward slashes. This causes issues with the system I am developing.

Why is this happening, and is there a way to prevent it that is more elegant than string.replacing the path before writing?

Joe
  • 41,484
  • 20
  • 104
  • 125
Ryan
  • 257
  • 2
  • 4
  • I can't reproduce this. I have my app running from C:\my#\project\foo.exe and it writes out the Application.ExecutablePath correctly as you have written above. When you debug does Application.ExecutablePath inspect correctly? Are you doing any post-processing on the text you write out that isn't shown here? – Joe Oct 18 '12 at 01:44
  • 2
    I re-tested it in a new project, with just the code to write the file. It still reproduces. The framework it's using is 4.5 if that makes any difference. – Ryan Oct 18 '12 at 09:44
  • Interesting, especially in light of Elian's post below. Wonder what I did differently (though I used the 4.0 framework...) – Joe Oct 18 '12 at 11:23

2 Answers2

9

I just looked into the source code of Application.ExecutablePath, and the implementation is essentially this*:

Assembly asm = Assembly.GetEntryAssembly();
string cb = asm.CodeBase;
var codeBase = new Uri(cb); 

if (codeBase.IsFile) 
    return codeBase.LocalPath + Uri.UnescapeDataString(codeBase.Fragment);
else
    return codeBase.ToString();

The property Assembly.CodeBase will return the location as an URI. Something like:

file:///C:/myfolder/myfile.exe

The # is the fragment marker in a URI; it marks the beginning of the fragment. Apparently, the Uri class alters the given uri when it's parsed and converted back to a string again.

Since Assembly.Location contains a 'normal' file path, I guess your best alternative is:

string executablePath = Assembly().GetEntryAssembly().Location;

*) The implementation is more complex than this, because it also deals with situations where there are multiple appdomains and other special situations. I simplified the code for the most common situation.

Elian Ebbing
  • 18,779
  • 5
  • 48
  • 56
  • Interesting issue.. anyway, I converted to Assembly.Location and it's resolved. Thank you :) – Ryan Oct 18 '12 at 11:13
1

Odd error/bug. Other than using a replace function or extension method to always return the correct format you could try using

System.Reflection.Assembly.GetExecutingAssembly().Location 

instead of ExecutablePath.

Mark Alicz
  • 377
  • 1
  • 4