ltrzesniewski / InlineIL.Fody

Inject arbitrary IL code at compile time.
MIT License
240 stars 17 forks source link

InlineIL.Fody and .NET Core 3.1 #19

Closed hypeartist closed 4 years ago

hypeartist commented 4 years ago

Is it possible to use InlineIL.Fody in .NET Core 3.1 (or higher)? I get some weird error regarding System.ValueTuple not being found.

Error       Fody/InlineIL: Unexpected error occured while processing method T HookManager.Program::Read(System.Void*) at instruction IL_001b: call System.Void InlineIL.IL/Emit::Ldobj(InlineIL.TypeRef): System.IO.FileNotFoundException: Could not load file or assembly 'System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
File name: 'System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.ValueTuple, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.
File name: 'System.ValueTuple, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'

   at InlineIL.Fody.Model.TypeRefBuilder.AddModifiers(TypeReference type)
   at InlineIL.Fody.Processing.ArgumentConsumer.ConsumeArgTypeRef(Instruction typeRefInstruction)
   at InlineIL.Fody.Processing.MethodWeaver.<ProcessIlEmitMethodCall>g__CreateInstructionToEmit|22_0(<>c__DisplayClass22_0& )
   at InlineIL.Fody.Processing.MethodWeaver.ProcessIlEmitMethodCall(Instruction emitCallInstruction, Instruction& nextInstruction)
   at InlineIL.Fody.Processing.MethodWeaver.ProcessMethodCalls()

    HookManager D:\Repos\ConsoleApp2\HookManager\Program.cs 173 
ltrzesniewski commented 4 years ago

Yes, it's definitely possible, I'm using it just fine in netcoreapp3.1 projects.

This looks like an issue with the loaded assemblies in MSBuild itself. InlineIL uses a ValueTuple in TypeRefBuilder.AddModifiers, but it expects a different version of the library than the one which is loaded. Some other assembly used by MSBuild (probably another custom task) must have loaded a previous version of System.ValueTuple, which causes the error you see.

Could you provide a repro project so that I can take a look? Also, are you building with msbuild or dotnet build, and what version do you have? I suppose I could remove usages of System.ValueTuple from InlineIL but I'd rather not, since it's convenient.

hypeartist commented 4 years ago

Could you provide a repro project so that I can take a look?

Sure: Test

ltrzesniewski commented 4 years ago

Thanks. I built it on 2 different machines using both dotnet build and MSBuild, and it built fine.

I noticed you have set <LangVersion>preview</LangVersion>, are you using a preview dotnet SDK?

I've seen a tweet from @simoncropp saying he has issues with ValueTuple after installing a VS preview, so I guess this is related.

Maybe I should remove ValueTuple usages from InlineIL anyway because of this mess.

hypeartist commented 4 years ago

are you using a preview dotnet SDK?

Yes, I use Visual Studio 19 Preview which comes bundled with its .NET Core 3.1 Preview. I am also targeting .NET 5.0 Preview.

Maybe I should remove ValueTuple usages from InlineIL anyway because of this mess.

Oh! That would be just great of you!

hypeartist commented 4 years ago

I have downloaded and installed the latest .NET Core 3.1 LTS (3.1.105) and add global.json to the project folder:

{
  "sdk": {
    "version": "3.1.105"
  }
}

But it didn't help much. Still getting the very same error.

ltrzesniewski commented 4 years ago

Wait, I don't think 3.1.105 is a correct version number. The latest is 3.1.301 (see what dotnet --info tells you).

You may also try adding -nr:false to the dotnet build command, to see if it helps as a workaround.

hypeartist commented 4 years ago

Wait, I don't think 3.1.105 is a correct version number. The latest is 3.1.301.

Hmm... https://dotnet.microsoft.com/download/dotnet-core/thank-you/sdk-3.1.105-windows-x64-installer

You may also try adding -nr:false to the dotnet build command, to see if it helps as a workaround.

Well, -nr:false have worked fine on CLI. But how can I use it inside VS?

ltrzesniewski commented 4 years ago

Oh, OK sorry I haven't noticed that version, it's apparently for an older VS version.

I don't think you can easily set -nr:false from VS itself, but you can try to run VS with the MSBUILDDISABLENODEREUSE=1 environment variable.

hypeartist commented 4 years ago

but you can try to run VS with the MSBUILDDISABLENODEREUSE=1 environment variable.

From here:

This features (for various reasons) is not supported in the .NET Core version of MSBuild

But I did give it a try anyway and it really doesn't work

ltrzesniewski commented 4 years ago

Ok, well I guess you'll have to wait for me to release an updated InlineIL version then 😕

I'll try to do that later today.

ltrzesniewski commented 4 years ago

I released v1.4.2 which removes the dependency on System.ValueTuple, it turns out there was a single usage.

It should be available on NuGet in a few minutes.

hypeartist commented 4 years ago

Works like a charm now! Thank you so much for such great responsiveness!

SimonCropp commented 4 years ago

Sorry. i should have scanned other repos for this.

ltrzesniewski commented 4 years ago

No worries, your tweet helped enough 😉

FYI, I wrote a unit test which checks if a value tuple is used anywhere in an assembly, in case you may be interested. Value tuples aren't exactly easy to spot with a text search...

SimonCropp commented 4 years ago

@ltrzesniewski perhaps a catch in fody core that checks the exception message and says "just dont use them"?

ltrzesniewski commented 4 years ago

I don't think that's worth the trouble. I hope that if a user sees an "unexpected error" message he'll submit an issue like @hypeartist has done here.

I mainly added the unit test to avoid the problem reappearing in the future.

SimonCropp commented 4 years ago

fair enough :)