dotnet / upgrade-assistant

A tool to assist developers in upgrading .NET Framework applications to .NET 6 and beyond
MIT License
1.11k stars 163 forks source link

Method `'[MSBuild]::SubstringByAsciiChars'` not found. - CLI fails when trying to upgrade .NET Framework project #1589

Closed joelverhagen closed 3 months ago

joelverhagen commented 3 months ago

None was produced. But here are the selected options:

 Selected options
────────────────────────────────────────────────────────────────────
 Analysis settings   code
 Privacy mode        Unrestricted
 Report format       Html
 Report name         UpToNet6
 Selected projects   NuGet.Jobs.Common.csproj (+ 81 more projects)
 Source              Solution
 Target framework    .NET 6.0 (Supported until November, 2024)

 Steps
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 Source / Target framework / Projects / Settings / Config file / Report format / Report name / Privacy / Analysis
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Describe the bug

I would like to try migrating NuGet/NuGet.Jobs repository using upgrade-assistant. I opted to use the CLI since it seems like an easier way to start. I plan on using the tool just to migrate to SDK-based projects first (reverting a net6.0 TFM to net472). But I wasn't able to get that far. The tool failed with an InvalidProjectFileException when running analyze.

To Reproduce

  1. Clone https://github.com/NuGet/NuGet.Jobs
  2. Check out dev
  3. Run upgrade-assistant analyze in the repo root
  4. What do you want to analyze? Application sources (source code, settings and binary dependencies)
  5. What is your preferred target framework? .NET 6.0 (Supported until November, 2024)
  6. Which project do you want to upgrade (found 82)? Select all
  7. What do you want to analyze in the selected projects? Source code and settings
  8. Do you want to provide a config file to customize the analysis? n
  9. In what format should the report be generated? Save as HTML
  10. Enter report name UpToNet6
  11. Select privacy mode Unrestricted
  12. We have gathered all required options and are ready to run analysis. Do you want to continue? y

This runs for a while:

Building solution C:\z\Git\NuGet\NuGet.Jobs\NuGet.Jobs.sln ...

/ Initializing selected projects and their dependencies...

It then shows the exception.

Exceptions (if any)

Microsoft.Build.Exceptions.InvalidProjectFileException: Invalid static method invocation syntax: "[MSBuild]::SubstringByAsciiChars($(MSBuildProjectFile), 0, 8)". Method '[MSBuild]::SubstringByAsciiChars' not
found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). Check that all parameters are defined, are of the correct type, and are
specified in the right order.  C:\Program Files\dotnet\sdk\8.0.400-preview.0.24324.5\Microsoft.Common.CurrentVersion.targets
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject(String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, Object[] args)
   at Microsoft.Build.Shared.ProjectErrorUtilities.VerifyThrowInvalidProject[T1,T2](Boolean condition, String errorSubCategoryResourceName, IElementLocation elementLocation, String resourceName, T1 arg0, T2
arg1)
   at Microsoft.Build.Shared.ProjectErrorUtilities.ThrowInvalidProject[T1,T2](IElementLocation elementLocation, String resourceName, T1 arg0, T2 arg1)
   at Microsoft.Build.Evaluation.Expander`2.Function`1.Execute(Object objectInstance, IPropertyProvider`1 properties, ExpanderOptions options, IElementLocation elementLocation)
   at Microsoft.Build.Evaluation.Expander`2.PropertyExpander`1.ExpandPropertyBody(String propertyBody, Object propertyValue, IPropertyProvider`1 properties, ExpanderOptions options, IElementLocation
elementLocation, UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem)
   at Microsoft.Build.Evaluation.Expander`2.PropertyExpander`1.ExpandPropertiesLeaveTypedAndEscaped(String expression, IPropertyProvider`1 properties, ExpanderOptions options, IElementLocation elementLocation,
UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem)
   at Microsoft.Build.Evaluation.Expander`2.PropertyExpander`1.ExpandPropertiesLeaveEscaped(String expression, IPropertyProvider`1 properties, ExpanderOptions options, IElementLocation elementLocation,
UsedUninitializedProperties usedUninitializedProperties, IFileSystem fileSystem)
   at Microsoft.Build.Evaluation.Expander`2.ExpandIntoStringLeaveEscaped(String expression, ExpanderOptions options, IElementLocation elementLocation)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluatePropertyElement(ProjectPropertyElement propertyElement)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluatePropertyGroupElement(ProjectPropertyGroupElement propertyGroupElement)
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
   at Microsoft.Build.Evaluation.Evaluator`4.EvaluateImportElement(String directoryOfImportingFile, ProjectImportElement importElement)
   at Microsoft.Build.Evaluation.Evaluator`4.PerformDepthFirstPass(ProjectRootElement currentProjectOrImport)
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate()
   at Microsoft.Build.Evaluation.Evaluator`4.Evaluate(IEvaluatorData`4 data, ProjectRootElement root, ProjectLoadSettings loadSettings, Int32 maxNodeCount, PropertyDictionary`1 environmentProperties,
ILoggingService loggingService, IItemFactory`2 itemFactory, IToolsetProvider toolsetProvider, ProjectRootElementCacheBase projectRootElementCache, BuildEventContext buildEventContext, ISdkResolverService
sdkResolverService, Int32 submissionId, EvaluationContext evaluationContext, Boolean interactive)
   at Microsoft.Build.Evaluation.Project.ProjectImpl.Reevaluate(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext)
   at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, ProjectLoadSettings loadSettings, EvaluationContext evaluationContext)
   at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(ILoggingService loggingServiceForEvaluation, EvaluationContext evaluationContext)
   at Microsoft.Build.Evaluation.Project.ProjectImpl.ReevaluateIfNecessary(EvaluationContext evaluationContext)
   at Microsoft.Build.Evaluation.Project.ProjectImpl.Initialize(IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectLoadSettings loadSettings, EvaluationContext
evaluationContext)
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings
loadSettings, EvaluationContext evaluationContext)
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, String subToolsetVersion, ProjectCollection projectCollection, ProjectLoadSettings
loadSettings)
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, ProjectCollection projectCollection, ProjectLoadSettings loadSettings)
   at Microsoft.Build.Evaluation.Project..ctor(String projectFile, IDictionary`2 globalProperties, String toolsVersion, ProjectCollection projectCollection)
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, IDictionary`2 globalProperties, String toolsVersion)
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName, String toolsVersion)
   at Microsoft.Build.Evaluation.ProjectCollection.LoadProject(String fileName)
   at Microsoft.UpgradeAssistant.Services.DefaultMsbuildProjectAccess..ctor(String projectPath, ILogger logger, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\msbuild\Services\Msbuild\DefaultMsbuildProjectAccess.cs:line 28
   at Microsoft.UpgradeAssistant.Cli.Slices.Services.Msbuild.MsbuildService.GetProjectAccessAsync(String projectPath, Boolean isReadOnly, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Slices\Services\Msbuild\MsbuildService.cs:line 34
   at Microsoft.UpgradeAssistant.Cli.Slices.Services.Project.MsbuildProjectBuilder.BuildAsync(ISolution solution, String projectPath, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Slices\Services\Project\MsbuildProjectBuilder.cs:line 36
   at Microsoft.UpgradeAssistant.Cli.Slices.Services.Project.ProjectService.GetProjectAsync(ISolution solution, String projectPath, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Slices\Services\Project\ProjectService.cs:line 446
   at Microsoft.UpgradeAssistant.Cli.Slices.Services.Project.ProjectService.GetProjectByPathAsync(ISolution solution, String projectPath, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Slices\Services\Project\ProjectService.cs:line 270
   at Microsoft.UpgradeAssistant.Analysis.ProjectAnalysis.GetProjectEntryAsync(ProjectSliceNode node, CancellationToken cancellationToken) in D:\a\_work\1\s\src\engine\Analysis\ProjectAnalysis.cs:line 113
   at Microsoft.UpgradeAssistant.Analysis.ProjectAnalysis.LoadAsync(CancellationToken cancellationToken) in D:\a\_work\1\s\src\engine\Analysis\ProjectAnalysis.cs:line 95
   at Microsoft.UpgradeAssistant.Cli.Flow.Steps.Analysis.RunAnalysisFlowStep.<>c__DisplayClass12_0.<<LoadAsync>b__0>d.MoveNext() in D:\a\_work\1\s\src\cli\Flow\Steps\Analysis\RunAnalysisFlowStep.cs:line 102
--- End of stack trace from previous location ---
   at Spectre.Console.Status.<>c__DisplayClass16_0.<<StartAsync>b__0>d.MoveNext() in /_/src/Spectre.Console/Live/Status/Status.cs:line 79
--- End of stack trace from previous location ---
   at Spectre.Console.Status.<>c__DisplayClass17_0`1.<<StartAsync>b__0>d.MoveNext() in /_/src/Spectre.Console/Live/Status/Status.cs:line 120
--- End of stack trace from previous location ---
   at Spectre.Console.Progress.<>c__DisplayClass28_0`1.<<StartAsync>b__0>d.MoveNext() in /_/src/Spectre.Console/Live/Progress/Progress.cs:line 133
--- End of stack trace from previous location ---
   at Spectre.Console.Internal.DefaultExclusivityMode.RunAsync[T](Func`1 func) in /_/src/Spectre.Console/Internal/DefaultExclusivityMode.cs:line 40
   at Spectre.Console.Progress.StartAsync[T](Func`2 action) in /_/src/Spectre.Console/Live/Progress/Progress.cs:line 116
   at Spectre.Console.Status.StartAsync[T](String status, Func`2 func) in /_/src/Spectre.Console/Live/Status/Status.cs:line 117
   at Spectre.Console.Status.StartAsync(String status, Func`2 action) in /_/src/Spectre.Console/Live/Status/Status.cs:line 77
   at Microsoft.UpgradeAssistant.Cli.Flow.Steps.Analysis.RunAnalysisFlowStep.LoadAsync(IAnalysis analysis, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Flow\Steps\Analysis\RunAnalysisFlowStep.cs:line 98
   at Microsoft.UpgradeAssistant.Cli.Flow.Steps.Analysis.RunAnalysisFlowStep.RunAsync(IFlowContext context, CancellationToken cancellationToken) in
D:\a\_work\1\s\src\cli\Flow\Steps\Analysis\RunAnalysisFlowStep.cs:line 81
   at Spectre.Console.Flow.FlowRunner.RunAsync(CancellationToken cancellationToken) in D:\a\_work\1\s\src\spectre.flow\Flow\FlowRunner.cs:line 98

Further technical details

3.1.415 [C:\Program Files\dotnet\sdk]
5.0.403 [C:\Program Files\dotnet\sdk]
6.0.100-preview.7.21379.14 [C:\Program Files\dotnet\sdk]
6.0.300 [C:\Program Files\dotnet\sdk]
7.0.201 [C:\Program Files\dotnet\sdk]
8.0.100-preview.1.23115.2 [C:\Program Files\dotnet\sdk]
8.0.303 [C:\Program Files\dotnet\sdk]
8.0.400-preview.0.24324.5 [C:\Program Files\dotnet\sdk]
0.5.678.21462
joelverhagen commented 3 months ago

It's even faster to reproduce this way:

upgrade-assistant upgrade .\src\NuGet.Jobs.Auxiliary2AzureSearch\NuGet.Jobs.Auxiliary2AzureSearch.csproj --operation Inplace --targetFramework net6.0

Same exception.

joelverhagen commented 3 months ago

I see this is tracked in our internal bug tracker (issue 2129511) and appears to be fixed in the next release.

rilehudd commented 2 months ago

I see this is tracked in our internal bug tracker (issue 2129511) and appears to be fixed in the next release.

What was the bug? Is it a bug in the usage of the MSBuild API? I'm seeing this on another project and would be curious on where the actual problem lies.

joelverhagen commented 2 months ago

I don't know what the bug was. For me it went away when I updated to the latest version of the tool.

mjrist commented 2 months ago

@joelverhagen which dotnet sdk version?

We are seeing the same Invalid static method invocation syntax: "[MSBuild]::SubstringByAsciiChars($(MSBuildProjectFile), 0, 8)". in sdk 8.0.400 and 8.0.401.

joelverhagen commented 2 months ago

I did not change my SDK version to resolve the issue, just the version of the upgrade assistent. I was on version 8.0.303 at the time (see the original issue).

theolivenbaum commented 2 months ago

Same issue here, but in a different place (when using our c# to javascript compiler). Any ideas?

 [fail] [07:44:07] 
##[error]H5(0,0): Error H5003: Invalid static method invocation syntax: "[MSBuild]::SubstringByAsciiChars($(MSBuildProjectFile), 0, 8)". Method '[MSBuild]::SubstringByAsciiChars' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). Check that all parameters are defined, are of the correct type, and are specified in the right order.  /Users/runner/hostedtoolcache/dotnet/sdk/8.0.401/Microsoft.Common.CurrentVersion.targets
H5 : error H5003: Invalid static method invocation syntax: "[MSBuild]::SubstringByAsciiChars($(MSBuildProjectFile), 0, 8)". Method '[MSBuild]::SubstringByAsciiChars' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(`a`, `b`)). Check that all parameters are defined, are of the correct type, and are specified in the right order.  /Users/runner/hostedtoolcache/dotnet/sdk/8.0.401/Microsoft.Common.CurrentVersion.targets [/Users/runner/work/1/s/FrontEnd/Mosaik.FrontEnd.Core/Mosaik.FrontEnd.Core.csproj]
  Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
     at H5.Compiler.CompilationProcessor.Compile(CompilationRequest compilationRequest, UID128 compilationUID, CancellationToken cancellationToken)
     at H5.Compiler.Program.Main(String[] args)
     at H5.Compiler.Program.<Main>(String[] args)
rilehudd commented 2 months ago

I don't know what the bug was. For me it went away when I updated to the latest version of the tool.

Can you check the internal bug tracker issue you reference to find out? It sounds like the API usage changed to work around this issue in the upgrade-assistant rather than the root cause being fixed?

Information on how upgrade-assistant worked around this could be useful so we could make similar changes to fix or work around the issue.

joelverhagen commented 2 months ago

I will defer to the upgrade assistant team for the details. I am only a user of upgrade assistant. The internal bug does not mention the fix made. It looks like the problem was retested on the latest build and it went away. But maybe other conversation happened that I don't know about.

I will pass this conversation on to someone internally who may be able to help.

theolivenbaum commented 2 months ago

@joelverhagen the issue is also happening outside of the upgrade assistant - should I open a new issue on GitHub for that?

joelverhagen commented 2 months ago

@abpiskunov - is this something you could help with?

abpiskunov commented 2 months ago

@theolivenbaum The issue was caused by mismatch in msbuild assembly UA loaded and what targets of the project being upgraded were containing - new .NET targets needed that method, when msbuild assembly loaded already was old and did not have it. For UA you could just update it to newer version. For other tools, please open bugs in their repos.

DataJuggler commented 1 month ago

I get this same error trying to use Code Analysis and MSBuild to read a solution.

mtu305 commented 4 days ago

@abpiskunov "by mismatch in msbuild assembly UA loaded and what targets of the project being upgraded were containing - new .NET targets needed that method" Could you please make it detail?

I meet the same issue when I call the method LoadProject of Microsoft.Build.Evaluation.ProjectCollection. I build the App that use LoadProject to open a csproj file. It throws above exception when I run that app in a machine which upgraded to VS2022 Preview (which support Net9.0)