dspace-group/dscom

Error: Could not load file or assembly 'PresentationFramework' on tlbexport (regression in 1.6.0)

Closed this issue · 5 comments

When using dscom to export a library referencing WPF or another unavailable library, exceptions are thrown. We don't really want to "fix" those reference problems, just to have tlbexport ignore them.

Related to #120, #204 and fixed in #205 for v1.4.0.

Behavior in v1.4.0 and v1.5.0:

✅ Build succeeds, TLB is successfully produced with log output

1>Calling dscom.exe to export type library
1>dscom : warning TX00000000: Type library exporter encountered an error while processing 'AssemblyName'. Error: Could not load file or assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
1>Done building project "AssemblyName.csproj".

Behavior in v1.6.0 and higher:

❌No TLB is produced, build fails with log output

1>Calling dscom.exe to export type library
1>dscom : warning TX00000000: Type library exporter encountered an error while processing 'AssemblyName'. Error: Could not load file or assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
1>Failed to export type library. Could not load file or assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
1>C:\Users\user\.nuget\packages\dspace.runtime.interopservices.buildtasks\1.6.0\build\dSPACE.Runtime.InteropServices.BuildTasks.Tools.targets(64,5): error MSB3073: The command "C:\Users\user\.nuget\packages\dspace.runtime.interopservices.buildtasks\1.6.0\build\..\tools\x64\dscom.exe       tlbexport    C:\dev\source\repos\OopWpf\AssemblyName\bin\Debug\net462\AssemblyName.dll  --out "C:\dev\source\repos\OopWpf\AssemblyName\bin\Debug\net462\\AssemblyName.tlb"" exited with code 1.
1>Done building project "AssemblyName.csproj" -- FAILED.

Issue occurs on net462 and net7.0. Other frameworks not tested.

Diff between 1.5 to 1.6: https://github.com/dspace-group/dscom/compare/v1.5.0..v1.6.0

Hi Mitch,

I'm very sorry that we somehow broke the bugfix. I'll try to take a closer look at it and investigate what exactly changed.
At a first glance I don't see a change in the relevant code sections. But maybe something changed in the dependencies or the .NET 8 migration broke it.

I've never tried it out on net7.0 because that's not a LTS version of .NET but I'll try to do some debugging and find the reason.

Hi @mgaffigan

From the error messages, you seem to run into the problem of loading the Assembly twice. Once it's caught by the warning and a second time where it goes back to the client and results in the exit code of 1 and the second error message. That's very strange because there is only one instance of assembly.GetTypes() in our code.

I'm having problems reproducing the issue with .NET 6 or .NET 8. I can't try it out with .NET 7 or .NET Framework 4.6.2 because I don't have that on my work computer and it has reached End-Of-Life.

Could you try out exporting with a .NET 6 or 8?
Does the problem also occur on your side when you are trying to export the dSPACE.Runtime.InteropServices.DemoAssembly5.dll ? That assembly also references the PresentationFramework and you introduced it to verify the original bug fix.

No worries and thank you for the quick response @SOsterbrink. Testing with .NET 8 yields the same error. I was able to reproduce with assembly5 with edits. (Or the real use case is open source.) Seems like it is unrelated to the previous issue. Stack of the exception is:

System.IO.FileNotFoundException: Could not load file or assembly 'PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'PresentationFramework, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at System.RuntimeTypeHandle.GetDeclaringType(RuntimeType type)
   at System.RuntimeType.RuntimeTypeCache.GetEnclosingType()
   at System.RuntimeType.RuntimeTypeCache.GetNameSpace()
   at System.RuntimeType.get_Namespace()
   at dSPACE.Runtime.InteropServices.Writer.LibraryWriter.CollectAllTypes() in C:\\dev\\gitroot\\dscom\\src\\dscom\\writer\\LibraryWriter.cs:line 100
   at dSPACE.Runtime.InteropServices.Writer.LibraryWriter.Create() in C:\\dev\\gitroot\\dscom\\src\\dscom\\writer\\LibraryWriter.cs:line 72
   at dSPACE.Runtime.InteropServices.TypeLibConverter.ConvertAssemblyToTypeLib(Assembly assembly, TypeLibConverterSettings settings, ITypeLibExporterNotifySink notifySink) in C:\\dev\
\gitroot\\dscom\\src\\dscom\\TypeLibConverter.cs:line 59
   at dSPACE.Runtime.InteropServices.ConsoleApp.<>c.<ConfigureTLBExportHandler>b__4_0(TypeLibConverterOptions options) in C:\\dev\\gitroot\\dscom\\src\\dscom.client\\Program.cs:line 167

Which would make the breaking commit 12df665 since Type.Namespace may throw if it is not able to be loaded.

That's interesting information. I wasn't aware, that Type.Namespace will try to reload the original file to determine the namespace.
I'll try out some bugfixes for this and get back to you later today.