-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Generating strongly typed resource files requires non-intuitive addition of properties #4751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Team triage: I'd like to dig in on some of the changes required here. This may turn into an SDK feature to make it easier to get strongly typed resources. |
Yes, please, ideally the csproj should just pick it up automatically via convention over configuration if the resx file name matches the csproj name. |
@rainersigwald Any updates? Building using
I created the following branch with my changes: https://github.com/bergmeister/PSScriptAnalyzer/tree/netcore3_resgen |
Any updates @rainersigwald ? This would be good to be fixed in 3.1 as it will be LTS |
I am trying to move PowerShell Core projects to the generator. |
I could be able compile PowerShell Core with some workarounds. See PowerShell/PowerShell#12355 |
I was successful for a while doing this: <ItemGroup>
<EmbeddedResource Update="TracerMessages.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TracerMessages.Designer.cs</LastGenOutput>
<StronglyTypedFileName>TracerMessages.Designer.cs</StronglyTypedFileName>
<StronglyTypedLanguage>CSharp</StronglyTypedLanguage>
<StronglyTypedNamespace>Autofac.Diagnostics.DotGraph</StronglyTypedNamespace>
<StronglyTypedClassName>TracerMessages</StronglyTypedClassName>
</EmbeddedResource>
</ItemGroup> Note the
The only way to work around it was to remove the checked-in Designer.cs file and switch to the <ItemGroup>
<EmbeddedResource Update="TracerMessages.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TracerMessages.Designer.cs</LastGenOutput>
<StronglyTypedFileName>$(IntermediateOutputPath)/TracerMessages.Designer.cs</StronglyTypedFileName>
<StronglyTypedLanguage>CSharp</StronglyTypedLanguage>
<StronglyTypedNamespace>Autofac.Diagnostics.DotGraph</StronglyTypedNamespace>
<StronglyTypedClassName>TracerMessages</StronglyTypedClassName>
</EmbeddedResource>
</ItemGroup> This issue is the only place I've found any of this documented. It'd be nice if this was more straightforward to work with in a non-Visual-Studio (i.e., VS Code / all-command-line) environment. |
While this solution removes the warning on running Is there no other workaround? |
Try changing |
That will again cause the CSC : warning CS2002: Source file 'Properties/Something.Designer.cs' specified multiple times error again. |
I think this issue should probably be renamed and escalated. There is currently no method to have some developers use VSCode and some developers use Visual Studio on the same codebase and still use "resx" files. They are just simply incompatible. VisualStudio will attempt to overwrite the designer files whenever it feels like it and those updated designer files will always be different than what the ResXFileCodeGenerator produces (it has a version in it that it doesn't normally). The suggested work around in this issue won't work in that case either as VS will always generate the files next to the resx causing this issue. Unfortunately this is a problem spread across three different projects with inconsistent behavior leading me to believe they will never get fixed unless they all just duplicate the behavior of VisualStudio |
There's a nice write-up of this issue by @tillig at https://www.paraesthesia.com/archive/2022/09/30/strongly-typed-resources-with-net-core/. It would be good to see an SDK feature for this to get simple, consistent behavior in Visual Studio and VS Code. |
I'll add to this. Changing the line |
I updated my blog article with the info from @Arthri - thanks! https://www.paraesthesia.com/archive/2022/09/30/strongly-typed-resources-with-net-core/ I wonder if it'd be interesting/helpful to have some sort of "current workaround" complete code example pinned in here somehow. It's really hard to mentally apply all the incremental changes/updates noted here to get to a "complete solution" that works. (Which, I guess, is the whole point of this issue, but scrolling through this issue is almost as hard as the issue itself.) |
Thanks for the updates. I now have a PR open that makes it work, which I am very happy about. However, there is a difference between the update of @rainersigwald and the blog post by @tillig , which is the |
|
I've been leaving LastGenOutput and other boilerplate there for the reason that the VS resx designer will reinsert it anyway on each save, and I don't want to have to undo .csproj changes each time. (Same with the |
FWIW, Arcade has a solution for this (used by MSBuild itself AFAICT) which further points at dotnet/sdk#94 as an existing issue tracking this problem. |
@mhutch, MSBuild itself does not use the Arcade reimplementation (in fact we do not use strongly typed resources at all). I believe the Arcade reimplementation of the MSBuild feature was done because its authors were unaware of the MSBuild feature. |
msbuild/src/Directory.Build.targets Line 113 in 9f03900
|
Ah you're right, we had to do that to consume a source package that requires the Arcade approach. That's a bug in the package IMO. |
Expanded on @tillig's approach and made it a general-purpose drop-in for <Project>
<PropertyGroup>
<!-- For VSCode/Razor compat -->
<CoreCompileDependsOn>PrepareResources;$(CoreCompileDependsOn)</CoreCompileDependsOn>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Update="@(EmbeddedResource)">
<Generator>MSBuild:Compile</Generator>
<StronglyTypedFileName>$(IntermediateOutputPath)\$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.'))%(Filename).g$(DefaultLanguageSourceExtension)</StronglyTypedFileName>
<StronglyTypedLanguage>$(Language)</StronglyTypedLanguage>
<StronglyTypedNamespace Condition="'%(RelativeDir)' == ''">$(RootNamespace)</StronglyTypedNamespace>
<StronglyTypedNamespace Condition="'%(RelativeDir)' != ''">$(RootNamespace).$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.').TrimEnd('.'))</StronglyTypedNamespace>
<StronglyTypedClassName>%(Filename)</StronglyTypedClassName>
</EmbeddedResource>
</ItemGroup>
</Project> |
I believe this generates classes for |
FWIW, this seems to cause a recursive overflow in the inner markup build when |
Can confirm - I've circumvented the recursion by calling But I end up with the CS2002 errors mentioned previously so it likely doesn't actually work 🫠 |
Does removing it work? I suspect WPF already has a similar setting |
Is there any solution to this for WPF projects? |
I managed to get WPF projects building via: <PropertyGroup Condition="'$(UseWPF)' == 'true'">
<!-- Ensure WPF apps generate RESX designer files with namespace not taken from wpftmp file. -->
<RootNamespace Condition="$(RootNamespace.EndsWith('_wpftmp'))">$(_TargetAssemblyProjectName)</RootNamespace>
<!-- Ensure WPF apps invoke the RESX generator -->
<CoreCompileDependsOn>$(CoreCompileDependsOn);SplitResourcesByCulture;CreateManifestResourceNames;CoreResGen</CoreCompileDependsOn>
</PropertyGroup> |
It is really quite tricky to get this right, especially with WPF involved. Are there any intentions to make this work "out-of-the-box"? I've put together a small sample project (with multiple language files and WPF) for reference / reproduction which might help in resolving this issue. |
I have updated the blog post with my current approach that improves on this:
<ItemGroup>
<EmbeddedResource Update="Strings.resx">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup> And here's a sample repo showcasing it: https://github.com/[kzu/Resources.Wpf](https://github.com/kzu/Resources.Wpf) |
Thanks @kzu for sharing! In my project I have a lot of resx files but not so much locales. Thus, your approach can be combined with e.g. <ItemGroup>
<NonLocalizedResx Include="Resources\**\*.resx" Exclude="Resources\**\*.de.resx;Resources\**\*.en.resx"/>
<EmbeddedResource Update="@(NonLocalizedResx)">
<Generator>MSBuild:Compile</Generator>
</EmbeddedResource>
</ItemGroup> (If all resx inside Note: I added this directly to my project's csproj, not the As I use these resources in combination with DisplayAttribute, adding <EmbeddedResource Update="@(EmbeddedResource -> WithMetadataValue('Generator', 'MSBuild:Compile'))" Type="Resx">
<StronglyTypedFileName>$(IntermediateOutputPath)\$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.'))%(Filename).g$(DefaultLanguageSourceExtension)</StronglyTypedFileName>
<StronglyTypedLanguage>$(Language)</StronglyTypedLanguage>
<StronglyTypedNamespace Condition="'%(RelativeDir)' == ''">$(RootNamespace)</StronglyTypedNamespace>
<StronglyTypedNamespace Condition="'%(RelativeDir)' != ''">$(RootNamespace).$([MSBuild]::ValueOrDefault('%(RelativeDir)', '').Replace('\', '.').Replace('/', '.').TrimEnd('.'))</StronglyTypedNamespace>
<StronglyTypedClassName>%(Filename)</StronglyTypedClassName>
<PublicClass>true</PublicClass>
</EmbeddedResource> |
… any IDE. This is admittedly not very intuitive, which is a known issue: dotnet/msbuild#4751. Also regenerate the Resources.Designer.cs files accordingly.
… any IDE. (#22386) This is admittedly not very intuitive, which is a known issue: dotnet/msbuild#4751. Also regenerate the Resources.Designer.cs files accordingly.
Uh oh!
There was an error while loading. Please reload this page.
From #2272 (comment)
cc @rainersigwald
Steps to reproduce
Expected behavior
Build works
Actual behavior
Build fails due to errors resulting from Strings.Designer.cs not being created.
It seems one needs to apply the following non-intuitive changes to the
Engine.csproj
:The
StronglyTypedNamespace
is due to the following in the csproj:<RootNamespace>Microsoft.Windows.PowerShell.ScriptAnalyzer</RootNamespace>
However, having to supply all the other additional parameters seems unintuitive. I'd like to see a minimal solution for a csproj that also works with VS btw.
Environment data
msbuild /version
output:OS info:
Windows 10 1809
.Net Core 3.0-rc1
The text was updated successfully, but these errors were encountered: