dotnet / project-system

The .NET Project System for Visual Studio
MIT License
967 stars 386 forks source link

Consider adding more EmbeddedResource metadata to the sdk #5707

Open davidwengier opened 4 years ago

davidwengier commented 4 years ago

Once #2873 is fixed we can potentially include more metadata into the default glob in the SDK for EmbeddedResource to simplify the project file with respect to resource files (*.resx).

For example, consider if the SDK was expanded to the following:

  <ItemGroup>
    <EmbeddedResource Update="**\*.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>%(Filename).Designer.cs</LastGenOutput>
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
    </EmbeddedResource>

    <Compile Update="**\*.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>$([System.IO.Path]::ChangeExtension($([System.IO.Path]::GetFileNameWithoutExtension(%(Identity))), '.resx'))</DependentUpon>
    </Compile>
  </ItemGroup>

This would mean that the act of adding a .resx file to a project would result in no changes to the project file. Any pre-existing (standard) configuration in project files could be removed if users want to clean up their project files. Automatic or manual running of the custom tool for a .resx file also wouldn't modify the project.

The problem with the above is the assumption that *.Designer.cs is solely for .resx files, which doesn't hold true for Windows Forms apps, and possibly others. We could go half-way and just include the EmbeddedResource item above, which would result in some cleanup of the file, but not all.

We should investigate if there are ways to make the whole thing possible. One option to investigate is if we can change the filename for the generated designer files for .resx files to make them more uniquely identifiable, like Resource1.resx.designer.cs, though doing that in a backwards compatible way would present a challenge. Other possibilities should be considered.

cremor commented 4 years ago

Good idea. Two notes to improve it:

jnm2 commented 3 years ago

Can this issue cover .settings and their related Designer.cs files as well? It seems almost exactly the same as the .resx situation.

<None Update="Properties\Settings.settings" Generator="SettingsSingleFileGenerator" LastGenOutput="Settings.Designer.cs" />
<Compile Update="Properties\Settings.Designer.cs" DependentUpon="Settings.settings" DesignTimeSharedInput="True" AutoGen="True" />
RussKie commented 2 years ago

In Windows Forms we had few reports (e.g., https://github.com/dotnet/winforms/issues/6849) where customers had resources with non-standard names, and that caused the designer to fail image

The following workaround appears the help in establishing the dependency correctly:

  <ItemGroup>
    <_EmbeddedResources Include="**\*.resx">
      <_HasLocaleName>$([System.String]::Copy('%(Filename)').IndexOf('.'))</_HasLocaleName>
    </_EmbeddedResources>

    <_EmbeddedResourceWithLocaleNames Include="@(_EmbeddedResources)"
                                      Exclude="@(_EmbeddedResources->HasMetadata('_HasLocaleName')->WithMetadataValue('_HasLocaleName','-1'))" />

    <EmbeddedResource Update="@(_EmbeddedResourceWithLocaleNames)">
      <DependentUpon>$([System.String]::Copy('%(Identity)').SubString(0, $([System.String]::Copy('%(Identity)').IndexOf('.')))).cs</DependentUpon>
    </EmbeddedResource>
  </ItemGroup>

image