Skip to content

Rationalize Microsoft.Build.Framework string resources and add ThrowIf* polyfills for exceptions#13276

Merged
JanProvaznik merged 7 commits intodotnet:mainfrom
DustinCampbell:framework-string-resources
Feb 24, 2026
Merged

Rationalize Microsoft.Build.Framework string resources and add ThrowIf* polyfills for exceptions#13276
JanProvaznik merged 7 commits intodotnet:mainfrom
DustinCampbell:framework-string-resources

Conversation

@DustinCampbell
Copy link
Member

Summary

  • Modernize the string resources in Microsoft.Build.Framework and bring them in line with other dotnet repos. (01d840a)
  • Add various Microsoft.Build.Framework.resources.dlls to the Localization package, VSSetup and VSSetup.Arm64. (16c3145 and b89d070)
  • Add polyfills on non-.NET for ThrowIf* static methods on various exception types. (4b362f9)
  • Update AbsolutePath to use ArgumentNullException.ThrowIfNull(...) and ArgumentException.ThrowIfNullOrEmpty(...). (c0f748b)

Eventually, I intend to use the ThrowIf* polyfills throughout the MSBuild code base, which will allow several functions to be removed from ErrorUtilities. However, while wholly mechanical, that change will be pretty large, and I didn't want to pollute this pull request with all of that.

Copilot AI review requested due to automatic review settings February 20, 2026 23:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request modernizes the string resource management in Microsoft.Build.Framework to align with patterns used in other .NET repositories. It migrates from a custom FrameworkResources class with Strings.resx to an auto-generated SR class with SR.resx, adds localized resource DLLs to packaging configurations, and introduces polyfills for exception helper methods (ThrowIf*) that are available in modern .NET but not in .NET Framework.

Changes:

  • Replaced custom FrameworkResources.GetString() pattern with auto-generated SR class using MSBuild's GenerateResxSource feature
  • Added Microsoft.Build.Framework.resources.dll files for all 13 supported locales to VSSetup, VSSetup.Arm64, and Localization packages
  • Introduced polyfill extension methods for ArgumentNullException, ArgumentException, ArgumentOutOfRangeException, and ObjectDisposedException with ThrowIf* helpers for non-.NET targets

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Package/MSBuild.VSSetup/files.swr Added Framework resource DLLs for x86 and x64 builds across all 13 locales
src/Package/MSBuild.VSSetup.Arm64/files.arm64.swr Added Framework resource DLLs for ARM64 builds across all 13 locales
src/Package/Localization/Microsoft.Build.Localization.nuspec Added Framework resource DLLs to NuGet package for all 13 locales
src/MSBuildTaskHost/MSBuildTaskHost.csproj Changed wildcard polyfill inclusion to explicit file list to exclude ArgumentExceptionExtensions
src/Framework/Resources/xlf/.xlf (deleted Strings.) Removed old Strings.xlf localization files
src/Framework/Resources/xlf/.xlf (added SR.) Added new SR.xlf localization files with additional resource strings for polyfills
src/Framework/Resources/SR.resx Replaced Strings.resx with SR.resx containing new and existing resource strings
src/Framework/Resources/AssemblyResources.cs Deleted custom FrameworkResources class in favor of auto-generated SR
src/Framework/Polyfills/ArgumentExceptionExtensions.cs Added polyfill extension methods using experimental C# extension syntax
src/Framework/PathHelpers/AbsolutePath.cs Updated to use ArgumentException.ThrowIfNullOrEmpty and SR.PathMustBeRooted
src/Framework/Microsoft.Build.Framework.csproj Enabled GenerateResxSource for SR.resx and added using directive for Resources namespace
src/Framework.UnitTests/AbsolutePath_Tests.cs Split test methods and updated assertions for new exception messages

- Rename Strings.resx and Strings.*.xlf files to SR.resx and SR.*.xlf
- Set <GenerateResxSource> property to true
- Set <GenerateResxSourceEmitFormatMethods> property to true
- Update <EmbeddedResource> to set <GenerateSource> to true
- Add <Using Include="$(RootNamespace).Resources"/> to make it easier to access "SR" throughout Microsoft.Build.Framework
- Change calls to FrameworkResources.GetString(...) to access the generated SR class.
- Remove FrameworkResources (AssemblyResources.cs)
Add the following static extension methods to polyfill ThrowIf* static methods on non-.NET:

- ArgumentNullException.ThrowIfNull(object?, string?)
- ArgumentNullException.ThrowIfNull(void*, string?)
- ArgumentException.ThrowIfNullOrEmpty(string?, string?)
- ArgumentException.ThrowIfNullOrWhiteSpace(string?, string?)
- ArgumentOutOfRangeException.ThrowIfZero(int, string?)
- ArgumentOutOfRangeException.ThrowIfNegative(int, string?)
- ArgumentOutOfRangeException.ThrowIfNegativeOrZero(int, string?)
- ArgumentOutOfRangeException.ThrowIfEqual(T, T, string?)
- ArgumentOutOfRangeException.ThrowIfNotEqual(T, T, string?)
- ArgumentOutOfRangeException.ThrowIfGreaterThan(T, T, string?)
- ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(T, T, string?)
- ArgumentOutOfRangeException.ThrowIfLessThan(T, T, string?)
- ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(T, T, string?)
- ObjectDisposedException.ThrowIf(bool, object)
- ObjectDisposedException.ThrowIf(bool, Type)

In addition, MSBuildTaskHost.csproj has been tweaked to only include
the files in the Polyfills directory that it uses.
Use ArgumentException.ThrowIfNullOrEmpty in AbsolutePath and remove unneeded string resource, "PathMustNotBeNullOrEmpty" in favor of more general exception string.
@DustinCampbell DustinCampbell force-pushed the framework-string-resources branch from e7ce14c to 1ca1e44 Compare February 21, 2026 00:46
Copy link
Member

@JanProvaznik JanProvaznik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great, improves maintainability and fixes the localization for VS. I'm running an experimental insertion to get ahead of the possible dll count regression, so we can decide on timing of merge/if we should do something about that first

@DustinCampbell
Copy link
Member Author

this is great, improves maintainability and fixes the localization for VS. I'm running an experimental insertion to get ahead of the possible dll count regression, so we can decide on timing of merge/if we should do something about that first

@JanProvaznik: Are there internal instructions for how to do test VS insertions with the MSBuild repo or a pipeline you could point me to? I'm happy to do these on my own to reduce cost on your end. Feel free to ping me over Teams if there's information.

@rainersigwald
Copy link
Member

@DustinCampbell https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/50222/Experimental-SDK-insertion-in-VS

@rainersigwald
Copy link
Member

No wait, that's the wrong scenario, shouldn't have tried to do this while talking to you 🙃

https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/44077/Infra?anchor=experimental-insertion

@JanProvaznik
Copy link
Member

JanProvaznik commented Feb 24, 2026

no Rainer, that link is for sdk insertion coming from VMR (and the second one assumes the person knows what they're doing 😄 )
for MSBuild I don't think there is a doc and I can create it now:

@DustinCampbell
https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/51067/how-to-experimentally-insert-MSBuild-to-VS

note for nonmicrosoft contributors:
it requires permissions, so I am not posting the full guide publicly and we'll do it ourselves in contributions that look promising and need it

@JanProvaznik JanProvaznik merged commit 6fdc193 into dotnet:main Feb 24, 2026
10 checks passed
JanProvaznik pushed a commit to JanProvaznik/msbuild that referenced this pull request Feb 25, 2026
…f* polyfills for exceptions (dotnet#13276)

### Summary

- Modernize the string resources in `Microsoft.Build.Framework` and
bring them in line with other dotnet repos.
(01d840a)
- Add various `Microsoft.Build.Framework.resources.dlls` to the
`Localization` package, `VSSetup` and `VSSetup.Arm64`.
(16c3145 and
b89d070)
- Add polyfills on non-.NET for `ThrowIf*` static methods on various
exception types. (4b362f9)
- Update `AbsolutePath` to use `ArgumentNullException.ThrowIfNull(...)`
and `ArgumentException.ThrowIfNullOrEmpty(...)`.
(c0f748b)

Eventually, I intend to use the `ThrowIf*` polyfills throughout the
MSBuild code base, which will allow several functions to be removed from
`ErrorUtilities`. However, while wholly mechanical, that change will be
pretty large, and I didn't want to pollute this pull request with all of
that.
@DustinCampbell DustinCampbell deleted the framework-string-resources branch February 25, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants