[Regression] Designer fails to load with multi target frameworks.
Environment
17.11.5
.NET version
.Net8 and .Net9
Did this work in a previous version of Visual Studio and/or previous .NET release?
Yes in .Net 7 and .Net 6.
Issue description
Designer fail to load with:
<TargetFrameworks>net8.0-windows;net7.0-windows</TargetFrameworks>
But load normally with:
<TargetFrameworks>net8.0-windows</TargetFrameworks><TargetFrameworks>net7.0-windows;net8.0-windows</TargetFrameworks>
Detailed analysis in this comment.
Steps to reproduce
- Build repro app.
- Try to open
Form1.csform in designer - will see an error.
Modify DesignerFail.csproj to - <TargetFrameworks>net8.0-windows</TargetFrameworks> or <TargetFrameworks>net7.0-windows;net8.0-windows</TargetFrameworks> and restart VS.
Try to open Form1.cs form in designer - the designer will open normally.
Diagnostics
[11:54:29.015405] fail: [DesignerFail]: Failed to launch design tools server process process
System.TypeLoadException: Could not load type 'System.Runtime.CompilerServices.NullableContextAttribute' from assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
at System.ModuleHandle.ResolveType(QCallModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
at System.ModuleHandle.ResolveTypeHandle(Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(MetadataToken caCtorToken, MetadataImport& scope, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1& derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctorWithParameters, Boolean& isVarArg)
at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeType type, RuntimeType caType, Boolean inherit)
at System.Attribute.GetCustomAttributes(MemberInfo element, Boolean inherit)
at System.Composition.TypedParts.Util.DirectAttributeContext.GetCustomAttributes(Type reflectedType, MemberInfo member)
at System.Composition.Convention.AttributedModelProviderExtensions.GetDeclaredAttribute[TAttribute](AttributedModelProvider convention, Type reflectedType, MemberInfo member)
at System.Composition.TypedParts.Discovery.TypeInspector.InspectTypeForPart(TypeInfo type, DiscoveredPart& part)
at System.Composition.TypedParts.TypedPartExportDescriptorProvider..ctor(IEnumerable`1 types, AttributedModelProvider attributeContext)
at System.Composition.Hosting.ContainerConfiguration.CreateContainer()
at Microsoft.DotNet.DesignTools.Server.ServerProtocolContext.BuildCompositionHost(IEnumerable`1 designTimeAssemblies, DesignToolsServer designToolsServer, IEnumerable`1 exportDescriptorProviders, ILoggerFactory loggerFactory, ILogger logger)
at Microsoft.DotNet.DesignTools.Server.ServerProtocolContext.Create(ITypeIdentityResolutionService typeIdentityResolution, ILiveObjectService liveObjectService, DesignToolsServer designToolsServer, IEnumerable`1 designTimeAssemblies, IEnumerable`1 exportDescriptorProviders, ILoggerFactory loggerFactory)
at Microsoft.DotNet.DesignTools.Server.DesignToolsServer.StartUpAsync(Boolean testMode, CancellationToken cancellationToken)
at Microsoft.DotNet.DesignTools.Server.DesignToolsServer.StartListeningAsync(Stream stream, TraceListener traceListener)
at Microsoft.DotNet.DesignTools.Server.Program.<>c__DisplayClass2_0.<<Main>b__1>d.MoveNext()
For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
[11:54:29.017408] fail: Microsoft.DotNet.DesignTools.Client.ServerException: Failed to launch the design tools server process.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Threading.TplExtensions.<WithTimeout>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.DotNet.DesignTools.Client.Host.ServerProcess.<LaunchAsync>d__29.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.DotNet.DesignTools.Client.Host.ServerHostFactory.<CreateHostAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.DotNet.DesignTools.Client.DesignToolsClientLoader.<CreateClientAsync>d__29.MoveNext()
For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
[11:54:29.044435] warn: Cannot update selection in server process as Session is not connected.
[11:54:29.373475] fail: BasicDesignerLoader.DependentLoadComplete - _loadDependencyCount is 0.
For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
It doesn't repro on my side, after reloading the project, then everything work well
@LeafShi1 this is not my repro app on the screen.
Designer fail to load only with:
<TargetFrameworks>net8.0-windows;net7.0-windows</TargetFrameworks>
<TargetFrameworks>net9.0-windows;net7.0-windows</TargetFrameworks>
And this issue related to the version of the package WinForms.DataVisualization, if update the version to 1.7.0, the Designer can be loaded normally.
This problem has occurred since version 1.9.2, @kirsan31 you can consider using 1.9.1 in your project
@LeafShi1
And this issue related to the version of the package
WinForms.DataVisualizationThis problem has occurred since version 1.9.2
Nice catch - thank you! 🙏
I am a maintainer of WinForms.DataVisualization. Main change in 1.9.2 was adding net8.0-windows tfm to package, other changes are small fixes not related to designer. But just in case I checked 1.9.2 without net8.0-windows support - no problem.
We have:
- If package support only
net7.0-windowsandnet6.0-windows- all work fine on client with all configurations. - If package support
net7.0-windowsandnet6.0-windowsandnet8.0-windows(ornet7.0-windowsandnet8.0-windows): 2.1 If client uses single tfmnet8.0-windows- all work fine. Sonet8.0-windowssupport in package works correctly. 2.2 If client uses multiple tfms but main (first) not .Net8 - all work fine. 2.3 The problem only if client uses multiple tfms and main (first) is .Net8.
So the bug appears only if package support multiple tfms including net8.0-windows and client uses multiple tfms with main (first) is net8.0-windows.
More of it I've created a small repro project as possible (updated it at 1 post) - simple new empty (no controls on the form) winforms project with <TargetFrameworks>net8.0-windows;net7.0-windows</TargetFrameworks> and
<ItemGroup>
<PackageReference Include="WinForms.DataVisualization" Version="1.9.2" />
</ItemGroup>
And designer fail to load with the same error. So I think we have here some sort of very interesting bug 🤔
The error : Could not load type 'System.Runtime.CompilerServices.NullableContextAttribute' from assembly 'System.Runtime, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. and the fact that NullableContextAttribute was introduced at .Net8 suggests that with multiple tfms the designer is trying to get this type from the wrong dll...
P.s. I've tried to build package with updated Microsoft.WinForms.Designer.SDK 1.6.0 version - not helped.
@Tanya-Solyanik @merriemcgaw This issue also related to multitarget, should we investigate further?
Yes, please. Search the designer repo issues to see if we have a duplicate please.
Yes, please. Search the designer repo issues to see if we have a duplicate please.
There are 2 multi target issues in designer repo, but they are not the same Created a new bug in Designer repo https://github.com/microsoft/winforms-designer/issues/6125
To make sure I've got the right of it - what we're seeing is that if we're targeting net8.0-windows first of multiple tfms and reference the DataVis 1.9.2 component we have the problem. Otherwise, we're seeing generally the right behavior?
@merriemcgaw
To make sure I've got the right of it - what we're seeing is that if we're targeting net8.0-windows first of multiple tfms and reference the DataVis 1.9.2 component we have the problem. Otherwise, we're seeing generally the right behavior?
I can't be 100% sure, but most likely it sounds like this:
If we're targeting net8.0-windows first of multiple tfms and reference the user component that support multiple tfms and out of process designer - we have the problem. Otherwise, we're seeing generally the right behavior.
In this case designer tring to load wrong dependencys : NullableContextAttribute version 7, but it was introduced only in .Net8.
So the problem not in .net8, we just caught this bug on net8 because earlier versions didn't have the NullableContextAttribute and we crashed.
Great explanation @kirsan31 thanks!
I'm going to go ahead and close this since we've got an internal issue tracking it now. @kirsan31 we'll reach out or reply on this issue when we have an update. I'm creating an internal item to review multi-targeting in general to do a deep dive and make sure we support as much as we can.