1

In debugging some behavior that relies on knowing the current executing assembly's path, I note that if I execute the following line in a C# VS 2010 project with no adjustments made to the build output path, the Assembly.GetExecutingAssembly is returning a case-correct path.

e.g.,

string location = Assembly.GetExecutingAssembly().Location;

shows "C:\src\MyProject\MyProject\bin\Debug\MyProject.exe"

Now, if I create a separate directory to output the assembly to, such as: C:\src\MyCamelCaseDir\, and update the Build -> Output path to C:\src\mycamelcasedir, the code above produces the string "C:\src\mycamcelcasedir\MyProject.exe".

The distinction being, clearly

"..\\MyCamelCaseDir".equals("..\\mycamelcasedir") 

is false, even if the OS doesn't treat paths as case-sensitive.

I assume that running in debug mode in Visual Studio is the reason for this... but I'm still a little confused - shouldn't GetExecutingAssembly return the directory path the operating system thinks contains the assembly, case and all?

EDIT: I don't think my question was well phrased. The correct answer to my question is the poster who notes that VS is just concatenating the text box in Build Ouput Path plus project name.

The question I was trying to ask was: why doesn't Assembly.GetExecutingAssembly().Location, return the path with case sensitivity the way the operating system is storing it?

I know that Windows is case insensitive in that you can type C:\foo\bar into an explorer window, and that will take you to C:\Foo\Bar (if there is such a directory).

But I would have thought that the location of the executing assembly would be the same in all cases, debug or not.

Gojira
  • 2,941
  • 2
  • 21
  • 30
  • "C:\\src\\MyCamelCaseDir*\\Debug*".equals("C:\\src\\mycamelcasedir*\\Debug*") . – Daniil Mar 24 '13 at 19:56
  • Ok, my example was confusing - edited now. But the issue is not that my directory path is incorrect it is that it is being evaluated to lower case, just because I put the path in the Output path as lower case. – Gojira Mar 24 '13 at 19:58
  • Just use a case insensitive string comparison. – Tony Hopkinson Mar 24 '13 at 19:59
  • Further thought. Delete that directory from the file system, and build again, should be created with the case you expect. Should use a case insensitive string compare though, anything else is asking for it. – Tony Hopkinson Mar 24 '13 at 20:02
  • Tony - thanks, but finding a workaround is not the problem I'm describing. It is - should one be able to count on the Assembly library to represent the path in case-correct manner? – Gojira Mar 24 '13 at 20:04

2 Answers2

3

While the documentation is unrevealing on this point, the path from GetExecutingAssembly().Location appears to be the path the operating system used when loading the assembly (For executables, this seems to be the path handed to Process.Start() or its equivalent, which the OS uses as is, without normalizing its case, etc., to the version recorded in the filesystem.), except for the filename part, which is taken from the actual name of the assembly.

You can see this in action easily by compiling a test command-line app and running it from the command prompt:

using System;
using System.Reflection;

namespace TestLocation
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0}", Assembly.GetExecutingAssembly().Location);
        }
    }
}

Which produces:

C:\Users\avatar>C:\Working\TestLocation\bin\Debug\TestLocation.exe C:\Working\TestLocation\bin\Debug\TestLocation.exe

C:\Users\avatar>c:\working\testlocation\bin\debug\testlocation.exe c:\working\testlocation\bin\debug\TestLocation.exe

If you enter a short name, i.e., just "testlocation", you get the correctly-cased version, but in the second case above, it already has a canonical filename, so just passes it through as-is - hence the name is not cased.

In short: it is very much advisable to not rely on case-preservation in filespecs under Windows, even if the NTFS filesystem does provide it internally, unless you manually look up the case of everything from the filesystem yourself. All you're going to get from most APIs is a filespec that can be used to reach the file, not necessarily its as-recorded-in-the-filesystem filespec.

Cerebrate
  • 1,391
  • 11
  • 26
0

String comparison have no knowledge of what underlying value of the string is. As you've pointed out by default path in Windows are not case sensitive, so you must treat them this way when comparing.

I.e. in your case you should be using

String.Equals("..\\MyCamelCaseDir", "..\\mycamelcasedir", 
    String.Comparison.OrdinalIgnoreCase) 

to compare file path strings. (Or you can normalize paths first - Normalize directory names in C#).

Side note: most likely reason of different casing comes from the fact that your full executable name is constructed by VS with string concatenation of "output path" and "project name".

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179