aelij / IgnoresAccessChecksToGenerator

Generates reference assemblies where all the internal types & members become public, and applies the IgnoresAccessChecksTo attribute
MIT License
167 stars 21 forks source link

Update Mono.Cecil to version 0.11.3 #8

Closed 0xced closed 3 years ago

0xced commented 4 years ago

Updating to Mono.Cecil 0.11.3 also implies updating the target framework of the MSBuild task to .NET Standard 2.0

This fixes the following issue:

IgnoresAccessChecksToGenerator.targets(12, 5): [MSB4018] The "PublicizeInternals" task failed unexpectedly.
System.ArgumentOutOfRangeException: Non-negative number required.
Parameter name: count
   at System.IO.BinaryReader.ReadBytes(Int32 count)
   at Mono.Cecil.PE.ImageReader.ReadDebugHeader()
   at Mono.Cecil.PE.ImageReader.ReadImage()
   at Mono.Cecil.PE.ImageReader.ReadImage(Disposable`1 stream, String file_name)
   at Mono.Cecil.ModuleDefinition.ReadModule(String fileName, ReaderParameters parameters)
   at IgnoresAccessChecksToGenerator.Tasks.PublicizeInternals.CreatePublicAssembly(String source, String target)
   at IgnoresAccessChecksToGenerator.Tasks.PublicizeInternals.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()

This crash can be reproduced by building the following project with dotnet build:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <InternalsAssemblyNames>Oracle.ManagedDataAccess</InternalsAssemblyNames>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="IgnoresAccessChecksToGenerator" Version="0.4.0" />
    <PackageReference Include="Oracle.ManagedDataAccess" Version="19.9.0" />
  </ItemGroup>
</Project>
0xced commented 4 years ago

I tried an MSBuild trick to replace Mono.Cecil.dll 0.10.0-beta6 with version 0.11.3.0 to workaround this issue while still using the IgnoresAccessChecksToGenerator 0.4.0 package but unfortunately it failed.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <InternalsAssemblyNames>Oracle.ManagedDataAccess</InternalsAssemblyNames>
  </PropertyGroup>
    <ItemGroup>
    <PackageReference Include="IgnoresAccessChecksToGenerator" Version="0.4.0" GeneratePathProperty="true" />
    <PackageReference Include="Mono.Cecil" Version="0.11.3" GeneratePathProperty="true" />
    <PackageReference Include="Oracle.ManagedDataAccess" Version="19.9.0" />
  </ItemGroup>
  <Target Name="UpdateMonoCecil" BeforeTargets="IgnoresAccessChecksToGenerator">
    <Copy SourceFiles="$(PkgMono_Cecil)\lib\net40\Mono.Cecil.dll" DestinationFolder="$(PkgIgnoresAccessChecksToGenerator)\tools\net46" SkipUnchangedFiles="true" />
  </Target>
</Project>

Replacing the Mono.Cecil.dll file with the Copy MSBuild task works but since IgnoresAccessChecksToGenerator.Tasks.dll references version 0.10.0.0 the PublicizeInternals task now fails with this error (after enabling fusion logs):

IgnoresAccessChecksToGenerator.targets(12, 5): [MSB4061] The "PublicizeInternals" task could not be instantiated from "C:\Users\cedric\.nuget\packages\ignoresaccesscheckstogenerator\0.4.0\build\..\tools\net46\IgnoresAccessChecksToGenerator.Tasks.dll". 
System.IO.FileNotFoundException: Could not load file or assembly 'Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e' or one of its dependencies. The system cannot find the file specified.
File name: 'Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e'
   at IgnoresAccessChecksToGenerator.Tasks.PublicizeInternals..ctor()
=== Pre-bind state information ===
LOG: DisplayName = Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/
LOG: Initial PrivatePath = NULL
Calling assembly : IgnoresAccessChecksToGenerator.Tasks, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Mono.Cecil, Version=0.10.0.0, Culture=neutral, PublicKeyToken=50cebf1cceb9d05e
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/Mono.Cecil.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/Mono.Cecil/Mono.Cecil.DLL.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/Mono.Cecil.EXE.
LOG: Attempting download of new URL file:///C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/MSBuild/Current/Bin/Mono.Cecil/Mono.Cecil.EXE.
LOG: Attempting download of new URL file:///C:/Users/cedric/.nuget/packages/ignoresaccesscheckstogenerator/0.4.0/tools/net46/Mono.Cecil.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
LOG: Attempting download of new URL file:///C:/Users/cedric/.nuget/packages/ignoresaccesscheckstogenerator/0.4.0/tools/net46/Mono.Cecil/Mono.Cecil.DLL.
LOG: Attempting download of new URL file:///C:/Users/cedric/.nuget/packages/ignoresaccesscheckstogenerator/0.4.0/tools/net46/Mono.Cecil.EXE.
LOG: Attempting download of new URL file:///C:/Users/cedric/.nuget/packages/ignoresaccesscheckstogenerator/0.4.0/tools/net46/Mono.Cecil/Mono.Cecil.EXE.

I can think of two ways to fix this loading of Mono.Cecil error.

  1. Add this binding redirect in the MSBuild config file at C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe.Config:
<dependentAssembly>
  <assemblyIdentity name="Mono.Cecil" publicKeyToken="50cebf1cceb9d05e" culture="neutral" />
  <bindingRedirect oldVersion="0.0.0.0-0.11.3.0" newVersion="0.11.3.0" />
</dependentAssembly>
  1. Edit %USERPROFILE%\.nuget\packages\ignoresaccesscheckstogenerator\0.4.0\tools\net46\IgnoresAccessChecksToGenerator.Tasks.dll and fix the Mono.Cecil reference version to 0.11.3.0, for example with dnSpy.

image

Unfortunately, both fixes are not easily automatable with another MSBuild trick.

0xced commented 3 years ago

Ping @aelij. Any interest in merging this and releasing a new version of IgnoresAccessChecksToGenerator?

aelij commented 3 years ago

Thanks for the fix! And sorry for the delay. Will publish soon.

0xced commented 3 years ago

Thanks for merging, and no need to apologize! Looking forward to the new release. 😇

0xced commented 3 years ago

Hmmm, browsing through the project it looks like I may have forgotten to update netstandard1.3 to netstandard2.0 in the IgnoresAccessChecksToGenerator.targets file too.