Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a glob for resx files for new SDK csproj file

Tags:

.net

msbuild

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
like image 899
bradgonesurfing Avatar asked Oct 05 '17 11:10

bradgonesurfing


People also ask

How do I add a file to resources Resx?

Double click (select) Resource. resx. Select Add Resource > Add Existing File. Select the 'icon.

How do I add a resource to Visual Studio?

In Visual Studio, open a SharePoint solution. In Solution Explorer, choose a SharePoint project node, and then, on the menu bar, choose Project > Add New Item. In the Add New Item dialog box, choose the Global Resources File template, and then choose the Add button.


2 Answers

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.

like image 85
SliverNinja - MSFT Avatar answered Oct 06 '22 05:10

SliverNinja - MSFT


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>
like image 37
stijn Avatar answered Oct 06 '22 05:10

stijn