StackExchange / StackExchange.Precompilation

Roslyn based csc.exe and aspnet_compiler.exe replacement with metaprogramming hooks for ASP.NET MVC projects from the pre-DNX era
MIT License
154 stars 37 forks source link

StackExchange.Precompiler.exe throws reference errors #33

Open itssimple opened 7 years ago

itssimple commented 7 years ago

I'm not normally one for posting huge blocks of code. But the 4.0.0 StackExchange.Precompiler.exe throws this when I try to run it.


ERROR: An unhandled exception occured
System.IO.FileNotFoundException: Could not load file or assembly 'System.Composition.AttributedModel, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Composition.AttributedModel, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
   at System.Reflection.Assembly.Load(Byte[] rawAssembly)
   at StackExchange.Precompilation.CompilationAssemblyResolver.<>c__DisplayClass3_0.<Setup>b__4(String resourceKey) in C:\projects\stackexchange-precompilation\StackExchange.Precompilation.Build\CompilationAssemblyResolver.cs:line 51
   at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
   at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.Tasks.Task.Execute()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

System.IO.FileNotFoundException: Could not load file or assembly 'System.Composition.TypedParts, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Composition.TypedParts, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
   at System.Reflection.Assembly.Load(Byte[] rawAssembly)
   at StackExchange.Precompilation.CompilationAssemblyResolver.<>c__DisplayClass3_0.<Setup>b__4(String resourceKey) in C:\projects\stackexchange-precompilation\StackExchange.Precompilation.Build\CompilationAssemblyResolver.cs:line 51
   at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
   at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.Tasks.Task.Execute()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

System.IO.FileNotFoundException: Could not load file or assembly 'System.Composition.Hosting, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Composition.Hosting, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
   at System.Reflection.Assembly.Load(Byte[] rawAssembly)
   at StackExchange.Precompilation.CompilationAssemblyResolver.<>c__DisplayClass3_0.<Setup>b__4(String resourceKey) in C:\projects\stackexchange-precompilation\StackExchange.Precompilation.Build\CompilationAssemblyResolver.cs:line 51
   at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
   at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.Tasks.Task.Execute()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].

System.IO.FileNotFoundException: Could not load file or assembly 'System.Composition.Runtime, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
File name: 'System.Composition.Runtime, Version=1.0.30.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
   at System.Reflection.RuntimeAssembly.nLoadImage(Byte[] rawAssembly, Byte[] rawSymbolStore, Evidence evidence, StackCrawlMark& stackMark, Boolean fIntrospection, SecurityContextSource securityContextSource)
   at System.Reflection.Assembly.Load(Byte[] rawAssembly)
   at StackExchange.Precompilation.CompilationAssemblyResolver.<>c__DisplayClass3_0.<Setup>b__4(String resourceKey) in C:\projects\stackexchange-precompilation\StackExchange.Precompilation.Build\CompilationAssemblyResolver.cs:line 51
   at System.Linq.Parallel.ForAllOperator`1.ForAllEnumerator`1.MoveNext(TInput& currentElement, Int32& currentKey)
   at System.Linq.Parallel.ForAllSpoolingTask`2.SpoolingWork()
   at System.Linq.Parallel.SpoolingTaskBase.Work()
   at System.Linq.Parallel.QueryTask.BaseWork(Object unused)
   at System.Threading.Tasks.Task.Execute()

WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].```
itssimple commented 7 years ago

I got it to work by adding these DLLs manually to the tools folder:

Microsoft.CodeAnalysis.dll
Microsoft.CodeAnalysis.CSharp.dll
StackExchange.Precompilation.Metaprogramming.dll
System.Collections.Immutable.dll
System.Composition.AttributedModel.dll
System.Composition.Hosting.dll
System.Composition.Runtime.dll
System.Composition.TypedParts.dll
System.IO.FileSystem.dll
System.Reflection.dll
System.Reflection.Metadata.dll
System.Runtime.dll
System.Runtime.Extensions.dll
System.ValueTuple.dll

I found which versions by looking into StackExchange.Precompiler.exe.config

itssimple commented 7 years ago

Doesn't work at AppVeyor though

https://ci.appveyor.com/project/itssimple/mn-l10n/build/1.0.65#L1455

itssimple commented 7 years ago

Fix for AppVeyor

I ran this in the Install Script-section:

nuget install StackExchange.Precompilation.Build -Version 4.0.0

REM Installing dependencies, in case the nuget-install didn't take
nuget install Microsoft.CodeAnalysis.Common -Version 2.2.0
copy Microsoft.CodeAnalysis.Common.2.2.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install Microsoft.CodeAnalysis.CSharp -Version 2.2.0
copy Microsoft.CodeAnalysis.CSharp.2.2.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install StackExchange.Precompilation.Metaprogramming -Version 4.0.0
copy StackExchange.Precompilation.Metaprogramming.4.0.0\lib\net462\* C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Collections.Immutable -Version 1.3.1
copy System.Collections.Immutable.1.3.1\lib\netstandard1.0\System.Collections.Immutable.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Composition.AttributedModel -Version 1.0.31
copy System.Composition.AttributedModel.1.0.31\lib\netstandard1.0\System.Composition.AttributedModel.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Composition.Hosting -Version 1.0.31
copy System.Composition.Hosting.1.0.31\lib\netstandard1.0\System.Composition.Hosting.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Composition.Runtime -Version 1.0.31
copy System.Composition.Runtime.1.0.31\lib\netstandard1.0\System.Composition.Runtime.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Composition.TypedParts -Version 1.0.31
copy System.Composition.TypedParts.1.0.31\lib\netstandard1.0\System.Composition.TypedParts.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.IO.FileSystem -Version 4.3.0
copy System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Reflection -Version 4.3.0
copy System.Reflection.4.3.0\lib\net462\System.Reflection.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Reflection.Metadata -Version 1.4.2
copy System.Reflection.Metadata.1.4.2\lib\netstandard1.1\System.Reflection.Metadata.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Runtime -Version 4.3.0
copy System.Runtime.4.3.0\lib\net462\System.Runtime.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.Runtime.Extensions -Version 4.3.0
copy System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

nuget install System.ValueTuple -Version 4.3.0
copy System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\

And then I modified the config-file to support version 1.0.31 of the System.Composition.* packages

And in Before build-script I run: copy StackExchange.Precompilation.Build.cfg C:\Users\appveyor\.nuget\packages\stackexchange.precompilation.build\4.0.0\tools\StackExchange.Precompiler.exe.config /Y

tompazourek commented 6 years ago

I have the same issue (running 4.1.1 version).

I suspect the main problem is that I have more references to the same assemblies and they aren't resolved correctly -- I'm using .NET Framework, and some projects reference the .NET Framework "System.Runtime" (which is assembly version 4.0.20.0 in .NET 4.7 on path C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7\Facades\System.Runtime.dll), while some libraries that are built for .NET Standard use the NuGet's "System.Runtime" package (e.g. assembly version "4.1.1.0" of package "4.3.0" on path packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll).

The precompiler isn't then able to resolve this correctly. It crashes on an exception like:

29>CSC : warning : Couldn't load reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7\Facades\System.Runtime.dll' - 'Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. An operation is not legal in the current state. (Exception from HRESULT: 0x80131509)'
29>CSC : error : An unhandled exception occured
29>  System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. (TaskId:412)
29>  File name: 'System.Runtime, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. (TaskId:412)
29>  File name: 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' (TaskId:412)
29>   (TaskId:412)
29>   (TaskId:412)

I solved the issue the same way as @itssimple, I added those lines to my Cake build script (right after NuGet package restore):

CopyFile("src/packages/System.Linq.Expressions.4.3.0/lib/net463/System.Linq.Expressions.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Linq.Expressions.dll");
CopyFile("src/packages/System.Reflection.4.3.0/lib/net462/System.Reflection.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Reflection.dll");
CopyFile("src/packages/System.Runtime.4.3.0/lib/net462/System.Runtime.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Runtime.dll");
CopyFile("src/packages/System.Runtime.Extensions.4.3.0/lib/net462/System.Runtime.Extensions.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Runtime.Extensions.dll");
CopyFile("src/packages/System.Runtime.InteropServices.4.3.0/lib/net463/System.Runtime.InteropServices.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Runtime.InteropServices.dll");
CopyFile("src/packages/System.Xml.ReaderWriter.4.3.0/lib/net46/System.Xml.ReaderWriter.dll", "src/packages/StackExchange.Precompilation.Build.4.1.1/tools/System.Xml.ReaderWriter.dll");
m0sa commented 6 years ago

That sounds familiar. I've had this happen in another project, which doesn't use SE Precompilation. Did you try setting DependsOnNETStandard to true?

Can you try building with /property:SEPrecompilerSkip=true? This would cause a build with the stock csc.exe; I wonder if it knows how to handle the different versions?

tompazourek commented 6 years ago

I made some progress since, I've updated to .NET 4.7 (from .NET 4.6.1) and to VS 2017 (and MSBuild 15). Then it seems that most of these assemblies resolve correctly just based on the binding redirects to the .NET 4.7 assembly, not the assembly from NuGet. I've also done some NuGet package reinstallations...

So most of this copying of assemblies was no longer needed. However, there was an exception to this. There was a problem with assemblies that are found in: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net47\ref (notice ref)

There are just 3 assemblies there:

When compiling with the SEPrecompilerSkip property on, the precompilation is skipped and the build is fine (even no warnings about any assembly versions). However, when I execute the precompilation, the precompiler complains that it Cannot load a reference assembly for execution and mentions one of these.

I have tried several things and the only reliable way to get around this issue without causing additional issues during build or runtime, was to copy the three assemblies from: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net47\lib (notice lib) to folder with the precompiler executable. That made it work for me.