Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OOP-Designer is unable to resolve assembly references when CopyLocal = false #12791

Open
furkane-3 opened this issue Jan 15, 2025 · 6 comments
Open
Labels
untriaged The team needs to look at this issue in the next triage

Comments

@furkane-3
Copy link

Environment

Version 17.12.3

.NET version

.NET 8.0

Did this work in a previous version of Visual Studio and/or previous .NET release?

Yes, in .NET 4.7.2

Issue description

Hi,

We are currently migrating a WinForms solution from .NET Framework (472) to .NET Core (8.0), but we are having issues with the Out-of-Process Designer resolving assembly references to several DLL's that are the output of another solution.

We are opting to do it this way because we still want to maintain backwards compatibility with the Framework edition of our codebase. It is our understanding that the general recommendation is to use NuGet feeds and/or CopyLocal = True for the referenced assemblies, but this does not work for our use case since both methods are disruptive to our workflow.

We are wondering if there is a way to assist the Designer in resolving these assembly references by indicating to it to look for:
<MySharedOutputDir>\MyAssembly.dll
instead of
C:\Users\<user>\AppData\Local\Microsoft\VisualStudio\17.0_XXXX\WinFormsDesigner\UserAppData\MyAssembly.dll?

Thanks!

Steps to reproduce

I have attached a reproduction below that causes the error when I try to add a UserControl. which refers to a class in the external assembly, to a Form.
WinFormsDesignerIssueRepro.zip

Caveat

I understand this example is quite simple and we could probably work around it by putting the instantiation of Class1 behind a check for DesignMode, but this would not work in our actual project due to the sheer complexity of refactoring it as such.

Steps:

  1. Build ClassLibrary solution => OK
  2. Build WinFormsApp solution => OK
  3. In VS, open Form1.cs with the Designer and try to drag the UserControl1 from the Toolbox onto it
  4. Observe error indicating that it was unsuccessful.
  5. Clicking "OK" displays the empty form without the UserControl => NOK

Image

Some diagnostic output from procmon64.exe that confirms the issue has to to with resolving the assembly reference:

Image

Temporary Workaround

  1. In WinFormsApp.csproj do the following:
...
    <Reference Include="ClassLibrary">
      <HintPath>..\..\build\ClassLibrary.dll</HintPath>
	<CopyLocal>True</CopyLocal>
    </Reference>
...
  1. Close all designers
  2. Rebuild WinFormsApp solution
  3. Reopen Form1.cs in Designer and try to add the UserControl1 from the Toolbox onto it => OK
    Image

Diagnostics

[14:50:52.629663] trce: Sending request: DesignerHosts/CreateComponent
[14:50:52.629663] info: [WinFormsApp]: TypeResolution: type = WinFormsApp.UserControl1, TimeTaken = 0 ms.
[14:50:52.629663] trce: DesignerHosts/CreateComponent took 00:00:00.0053744.
[14:50:52.629663] fail: Request failures: DesignerHosts/CreateComponent.
                        Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Could not load file or assembly 'ClassLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.

                        For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
[14:50:52.629663] fail: Exception: Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Could not load file or assembly 'ClassLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
                           at Microsoft.DotNet.DesignTools.Client.DesignToolsClient.<SendRequestAsync>d__49`1.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.VisualStudio.Threading.JoinableTask.CompleteOnCurrentThread()
                           at Microsoft.VisualStudio.Threading.JoinableTask`1.CompleteOnCurrentThread()
                           at Microsoft.DotNet.DesignTools.Protocol.Endpoints.DesignToolsEndpoints.DesignerHostsImpl.CreateComponent(SessionId sessionId, TypeIdentity type, String name, NameValuePairs defaultValues)
                           at Microsoft.WinForms.DesignTools.Client.Toolbox.WinFormsToolboxItem.CreateComponentsCore(IDesignerHost host, IDictionary defaultValues)
                           at System.Drawing.Design.ToolboxItem.CreateComponents(IDesignerHost host, IDictionary defaultValues)
                           at Microsoft.DotNet.DesignTools.Client.Designers.ComponentProxyDesigner.CreateTool(ToolboxItem tool, Nullable`1 location, Nullable`1 size, ObjectProxy toolboxSnapArgs)

                        For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
[14:50:52.629663] fail: Exception message = Microsoft.DotNet.DesignTools.Client.DesignToolsServerException: Could not load file or assembly 'ClassLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
                           at Microsoft.DotNet.DesignTools.Client.DesignToolsClient.<SendRequestAsync>d__49`1.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.VisualStudio.Threading.JoinableTask.CompleteOnCurrentThread()
                           at Microsoft.VisualStudio.Threading.JoinableTask`1.CompleteOnCurrentThread()
                           at Microsoft.DotNet.DesignTools.Protocol.Endpoints.DesignToolsEndpoints.DesignerHostsImpl.CreateComponent(SessionId sessionId, TypeIdentity type, String name, NameValuePairs defaultValues)
                           at Microsoft.WinForms.DesignTools.Client.Toolbox.WinFormsToolboxItem.CreateComponentsCore(IDesignerHost host, IDictionary defaultValues)
                           at System.Drawing.Design.ToolboxItem.CreateComponents(IDesignerHost host, IDictionary defaultValues)
                           at Microsoft.DotNet.DesignTools.Client.Designers.ComponentProxyDesigner.CreateTool(ToolboxItem tool, Nullable`1 location, Nullable`1 size, ObjectProxy toolboxSnapArgs)

                        For information on how to troubleshoot the designer refer to the guide at https://aka.ms/winforms/designer/troubleshooting.
@furkane-3 furkane-3 added the untriaged The team needs to look at this issue in the next triage label Jan 15, 2025
@Zheng-Li01
Copy link
Member

@furkane-3, no exception pops up when add the usercontrol from toolbox to Form1.cs[Design] page as below screenshot,
Image

@furkane-3
Copy link
Author

Hi Zheng,

Thank you for the response.

It appears as though you have the projects under the same solution, which is different from the structure in the repro that I sent.

What you have:

WinFormsApp.sln
|
| --- ClassLibrary.csproj
|
| --- WinFormsApp.csproj

What I have:

ClassLibrary.sln
|
| --- ClassLibrary.csproj

...

WinFormsApp.sln
|
| --- WinFormsApp.csproj

Sorry for the confusion.

We are doing this because we have domain-specific code in this separate ClassLibrary solution, that we are referring to in our WinFormsApp solution to render our views. Therefore, trying to add a UserControl, which refers to something (i.e. a Class) in the external ClassLibrary.dll, to a Form in the WinFormsApp solution, results in an exception in the Designer.

Could you please try again with the project structure that I have suggested?

Thanks!

@Tanya-Solyanik
Copy link
Member

@Zheng-Li01 - please move this issue to the designer repo once you can repro it.

@Zheng-Li01
Copy link
Member

@furkane-3, thanks for your response. and the issue can reproduce based on your description. just there still have a question need to confirm with you. in my testing, the usercontrol can be added successfully when setting the CopyLocal = false & Private = True or uncommand the Private = False in the .csproj file as below screenshot. so this issue seems related the Private filed setting?
Image
Repo.zip

@furkane-3
Copy link
Author

Hi @Zheng-Li01 ,

Glad to hear that!

I think the Private and CopyLocal tags are related. Per the docs:

Private | Optional boolean. Specifies whether the reference should be copied to the output folder. This attribute matches the Copy Local property of the reference that's in the Visual Studio IDE.

So in the case where you are able to add the UserControl with CopyLocal = False and Private = True, the value assigned to Private is overriding the value assigned to CopyLocal, so it is still copying the external assembly, which is not intended.

Please correct me if I am wrong.

Thanks

@Zheng-Li01
Copy link
Member

@furkane-3, thanks for your response. and the issue can reproduce based on your description. just there still have a question need to confirm with you. in my testing, the usercontrol can be added successfully when setting the CopyLocal = false & Private = True or uncommand the Private = False in the .csproj file as below screenshot. so this issue seems related the Private filed setting? Image Repo.zip

@Tanya-Solyanik could you please have a check for above results. if still need to open a GH DT issue to track this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
untriaged The team needs to look at this issue in the next triage
Projects
None yet
Development

No branches or pull requests

3 participants