I had help of AI generated information regarding this issue and I hope information below is useful.
Summary
VBCSCompilerLogger crashes with MissingMethodException when used with MSBuild installations that ship a different version of Microsoft.CodeAnalysis than what the logger was compiled against. The CommandLineArguments.Errors property access is not wrapped in the tryAccessCommandLineArgument helper, unlike other version-sensitive property accesses in the same file.
Environment
BuildXL: 0.1.0-devBuild (built from source, C:\tools\BuildXL-src\Out\Bin\Debug\win-x64\bxl.exe)
MSBuild: 17.x (Visual Studio 2022 BuildTools / Professional)
MsBuild resolver with msBuildRuntime: "FullFramework", useManagedSharedCompilation: true
Windows build nodes
Error (Option A — standard VBCSCompilerLogger.dll from Out\Bin\Debug\win-x64\tools\vbcslogger\net472)
MSBUILD : error MSB4017: The build stopped unexpectedly because of an unexpected logger failure.
Microsoft.Build.Exceptions.InternalLoggerException: The build stopped unexpectedly because of an unexpected logger failure.
---> System.MissingMethodException: Method not found:
'System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.CommandLineArguments.get_Errors()'.
at VBCSCompilerLogger.VBCSCompilerLogger.EventSourceOnMessageRaised(Object sender, BuildMessageEventArgs e)
Error (Option B — VBCSCompilerLoggerOldCodeAnalysis.dll from Out\Objects...\testRun\Logger, renamed to VBCSCompilerLogger.dll)
MSBUILD : error MSB1028: The logger failed unexpectedly.
System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
or one of its dependencies. The system cannot find the file specified.
at VBCSCompilerLogger.VBCSCompilerLogger..ctor()
Root Cause
In VBCSCompilerLogger.cs, the EventSourceOnMessageRaised method accesses parsedCommandLine.Errors directly:
IEnumerable badSwitchErrors = parsedCommandLine.Errors
.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList();
This property was added in a newer version of Microsoft.CodeAnalysis. Unlike other version-sensitive accesses in the same method (e.g., AnalyzerReferences, EmbeddedFiles, AdditionalFiles, AnalyzerConfigPaths, ErrorLogOptions, etc.), the .Errors property is not wrapped in the tryAccessCommandLineArgument helper that gracefully handles MissingMethodException:
static T? tryAccessCommandLineArgument(Func accessCommandLineArgument)
{
try { return accessCommandLineArgument(); }
catch (MissingMethodException) { return default; }
}
Proposed Fix
Wrap the parsedCommandLine.Errors access in tryAccessCommandLineArgument:
ImmutableArray errors = tryAccessCommandLineArgument(() => parsedCommandLine.Errors);
IEnumerable badSwitchErrors = errors != default
? errors.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList()
: Enumerable.Empty();
his is consistent with how all other version-sensitive CommandLineArguments properties are accessed in the same method.
Workaround
Set useManagedSharedCompilation: false in the resolver configuration. This disables the VBCSCompilerLogger entirely but results in slightly slower C# builds (no shared Roslyn compiler service).
Thanks a lot
I had help of AI generated information regarding this issue and I hope information below is useful.
Summary
VBCSCompilerLogger crashes with MissingMethodException when used with MSBuild installations that ship a different version of Microsoft.CodeAnalysis than what the logger was compiled against. The CommandLineArguments.Errors property access is not wrapped in the tryAccessCommandLineArgument helper, unlike other version-sensitive property accesses in the same file.
Environment
BuildXL: 0.1.0-devBuild (built from source, C:\tools\BuildXL-src\Out\Bin\Debug\win-x64\bxl.exe)
MSBuild: 17.x (Visual Studio 2022 BuildTools / Professional)
MsBuild resolver with msBuildRuntime: "FullFramework", useManagedSharedCompilation: true
Windows build nodes
Error (Option A — standard VBCSCompilerLogger.dll from Out\Bin\Debug\win-x64\tools\vbcslogger\net472)
MSBUILD : error MSB4017: The build stopped unexpectedly because of an unexpected logger failure.
Microsoft.Build.Exceptions.InternalLoggerException: The build stopped unexpectedly because of an unexpected logger failure.
---> System.MissingMethodException: Method not found:
'System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.Diagnostic>
Microsoft.CodeAnalysis.CommandLineArguments.get_Errors()'.
at VBCSCompilerLogger.VBCSCompilerLogger.EventSourceOnMessageRaised(Object sender, BuildMessageEventArgs e)
Error (Option B — VBCSCompilerLoggerOldCodeAnalysis.dll from Out\Objects...\testRun\Logger, renamed to VBCSCompilerLogger.dll)
MSBUILD : error MSB1028: The logger failed unexpectedly.
System.IO.FileNotFoundException: Could not load file or assembly
'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
or one of its dependencies. The system cannot find the file specified.
at VBCSCompilerLogger.VBCSCompilerLogger..ctor()
Root Cause
In VBCSCompilerLogger.cs, the EventSourceOnMessageRaised method accesses parsedCommandLine.Errors directly:
IEnumerable badSwitchErrors = parsedCommandLine.Errors
.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList();
This property was added in a newer version of Microsoft.CodeAnalysis. Unlike other version-sensitive accesses in the same method (e.g., AnalyzerReferences, EmbeddedFiles, AdditionalFiles, AnalyzerConfigPaths, ErrorLogOptions, etc.), the .Errors property is not wrapped in the tryAccessCommandLineArgument helper that gracefully handles MissingMethodException:
static T? tryAccessCommandLineArgument(Func accessCommandLineArgument)
{
try { return accessCommandLineArgument(); }
catch (MissingMethodException) { return default; }
}
Proposed Fix
Wrap the parsedCommandLine.Errors access in tryAccessCommandLineArgument:
ImmutableArray errors = tryAccessCommandLineArgument(() => parsedCommandLine.Errors);
IEnumerable badSwitchErrors = errors != default
? errors.Where(diagnostic => diagnostic.Id.Contains("2007")).ToList()
: Enumerable.Empty();
his is consistent with how all other version-sensitive CommandLineArguments properties are accessed in the same method.
Workaround
Set useManagedSharedCompilation: false in the resolver configuration. This disables the VBCSCompilerLogger entirely but results in slightly slower C# builds (no shared Roslyn compiler service).
Thanks a lot