11

If I add a new resx file to my properties folder in my new dotnetstandard 2.0 SDK project from VS2017 I see

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <EmbeddedResource Remove="Properties\foo.resx" />
  </ItemGroup>

  <ItemGroup>
    <Compile Update="Properties\MyWords.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>MyWords.resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="Properties\MyWords.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>MyWords.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>


</Project>

However I'd prefer to have this handled the same way normal cs files are handled. The project is empty and the filesystem is searched. What is the globby way to achieve the above so that when I add new files they don't end up explicity declared.

My first attempt is

  <ItemGroup>
    <Compile Update="Properties\**\*.designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>Properties\%(Filename).resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="Properties\**\*.resx">
      <Generator>ResXFileCodeGenerator</Generator>

    </EmbeddedResource>
  </ItemGroup>

but this won't work because

Properties\%(Filename).resx

expands to

Properties\Foo.designer.resx

instead of

Properties\Foo.resx
bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217
  • 2
    To someone reading this now: Resource files are included in the new SDK `csproj`. See here: https://learn.microsoft.com/en-us/dotnet/core/tools/csproj#default-compilation-includes-in-net-core-projects. No need for this :) – jpgrassi Nov 24 '18 at 17:58
  • Do you want to add an answer and I can switch the accepted answer if SO allows me to do that. – bradgonesurfing Nov 26 '18 at 07:16
  • I will add later, but no need to change. At the time it was the answer so :). – jpgrassi Nov 26 '18 at 07:23
  • It may be unfair to the person who provided correct information at that time, but switching the answer to a more up-to-date solution will tremendously help all the people who will find this question. – sam hocevar Apr 30 '21 at 16:42

3 Answers3

14

Kudos to @stijn for the direction, we took this solution a step further as it was missing the EmbeddedResource step we use during our publish to avoid disk IOPS at runtime.

Here is a similar strategy that also works with embedded resources:

RESX + Embedded Resource (MSBUILD 15 Glob-style)

  <ItemGroup>
    <Compile Include="**\*.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>$([System.String]::Copy('%(FileName)').Replace('.Designer', '.resx'))</DependentUpon>
    </Compile>
    <EmbeddedResource Include="**\*.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>$([System.String]::Copy('%(FileName)')).Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>

Notes: The MSBUILD Item Metadata reference is a great resource - e.g. it tells you that %FileName excludes the extension which tripped me up initially. Also this related SO post affirms the necessity of using String.Copy.

SliverNinja - MSFT
  • 31,051
  • 11
  • 110
  • 173
  • 1
    Note, that if you want to follow this (for .NET Core SDKs at least), and want this to be configured via Directory.Build file, you need to put it in Directory.Build.targets instead of Directory.Build.props – zastrowm Apr 06 '20 at 17:58
12

You can use property functions on metadata so erasing the .Designer part with String.Replace should be ok:

<Compile Update="Properties\**\*.designer.cs">
  <DesignTime>True</DesignTime>
  <AutoGen>True</AutoGen>
  <DependentUpon>Properties\$([System.String]::Copy('%(FileName)').Replace('.Designer', '')).resx</DependentUpon>
</Compile>
stijn
  • 34,664
  • 13
  • 111
  • 163
  • I used this answer. But, if you could you please put the full snippet (like I did in my answer), then I can remove my answer. – hIpPy Nov 23 '22 at 18:36
0

With Include, I get below build error:

Microsoft.NET.Sdk.DefaultItems.Shared.targets(190, 5): [NETSDK1022] Duplicate 'Compile' items were included. The .NET SDK includes 'Compile' items from your project directory by default. You can either remove these items from your project file, or set the 'EnableDefaultCompileItems' property to 'false' if you want to explicitly include them in your project file. For more information, see https://aka.ms/sdkimplicititems. The duplicate items were: ...

With Update, it works. So, just putting the full snippet here.

  <ItemGroup>
    <Compile Update="**\*.Designer.cs">
      <AutoGen>True</AutoGen>
      <DesignTime>True</DesignTime>
      <DependentUpon>$([System.String]::Copy('%(FileName)').Replace('.Designer', '.resx'))</DependentUpon>
    </Compile>
    <EmbeddedResource Update="**\*.resx">
      <Generator>PublicResXFileCodeGenerator</Generator>
      <LastGenOutput>$([System.String]::Copy('%(FileName)')).Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>
hIpPy
  • 4,649
  • 6
  • 51
  • 65