Monday, 16 September 2013

Possible .NET framework bug in System.dll?

What I think is wrong:

The VBCodeCompiler defined in Microsoft.VisualBasic namespace in System.dll fails to extract error messages due to parentheses being present in file paths.

The story why I think this:

I was messing with CodeDom today, and using C# I tried to make use of the VBCodeProvider, using this source code:


string workingDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "new folder");
var codeProvider = new VBCodeProvider();

var parameters = new CompilerParameters()
{
    OutputAssembly = Path.Combine(workingDir, "temp.exe"),
    GenerateExecutable = true,
    CompilerOptions = "/target:exe",
    IncludeDebugInformation = true,
};

var results = codeProvider.CompileAssemblyFromFile(parameters, Path.Combine(workingDir, "Program.vb"));

Console.WriteLine("CompilerResults.HasErrors = {0}", results.Errors.HasErrors);
Console.WriteLine(new string('-', 20));

foreach (CompilerError result in results.Errors)
    Console.WriteLine("{0}: {1}", result.Line, result.ErrorText);

Console.ReadKey();


The file Program.vb which gets compiled contains the following source
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text

Namespace ConsoleApplication1
    Module Program
   
        Public Sub Main(ByVal args() As String)
            Console.WriteLine("lol")
            Console.ReadKey()
        End Sub
   
    End Module
End Namespace


Now here the program works, it generates a file called temp.exe and it works fine. I tried to add a syntax error in the source by adding some gibberish to the end of:

Console.WriteLine("lol")


So it becomes this:


Console.WriteLine("lol") asdf


And yes, the compiler error appears at the CompilerResults.Errors collection.




Now comes the thing. When I try to change the working directory "New Folder" to "New Folder (2)", which is just a copy of the same folder with the Program.vb and the same syntax error in it, the errors disappear magically:




I checked the compiler output by rewriting my C# code to this:


string workingDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "new folder (2)");
var codeProvider = new VBCodeProvider();

var parameters = new CompilerParameters()
{
    OutputAssembly = Path.Combine(workingDir, "temp.exe"),
    GenerateExecutable = true,
    CompilerOptions = "/target:exe /verbose /utf8output",
    IncludeDebugInformation = true,
};

var results = codeProvider.CompileAssemblyFromFile(parameters, Path.Combine(workingDir, "Program.vb"));

Console.WriteLine("CompilerResults.HasErrors = {0}", results.Errors.HasErrors);
Console.WriteLine(new string('-', 20));

foreach (CompilerError result in results.Errors)
    Console.WriteLine("{0}: {1}", result.Line, result.ErrorText);

Console.WriteLine(new string('-', 20));

Console.WriteLine("Output of vbc.exe:");
Console.WriteLine(new string('-', 20));

foreach (var message in results.Output)
    Console.WriteLine(message);

Console.WriteLine(new string('-', 20));

Console.ReadKey();


Which gives me


Telling me the CompilerResults.HasErrors = false, but the compiler clearly returned a syntax error message.

I found this very weird, so I fired up Reflector and checked out the Microsoft.VisualBasic.VBCodeGenerator (the class that actually compiles the VB source) and compared that with the Microsoft.CSharp.CSharpCodeGenerator, and checked the following method which is present in both classes, and processes output lines to check for errors and warnings.

private void ProcessCompilerOutputLine(CompilerResults results, string line)

ProcessCompilerOutputLine in the VBCodeGenerator class:



And the one in CSharpCodeGenerator:




Notice the difference in the Regex. I tried the regex patterns in Expresso and the pattern used in the VBCodeGenerator didn't work for me. So I believe this is causing the error. In the CSharpCodeProvider this is not the case, because it works just fine. Am I missing something, is my .NET framework broken, or is it really a bug and doesn't VBCodeGenerator support parentheses? in file paths.