Visual Studio 2022’s transition to a 64-bit architecture, driven by customer feedback across the full range of Visual Studio developers, marked a pivotal step towards enhancing the development experience. As Klaus Loffelmann describes in his blog post, this transition enhances overall performance and responsiveness, particularly when working with resource-intensive tasks and large codebases. However, this evolution brings with it a notable challenge for some .NET Framework projects using the Windows Forms designer in Visual Studio 2022. The challenge lies in the inability to design Forms in .NET Framework projects that rely on 32-bit references, a consequence of the inherent technical limitation where the 64-bit devenv.exe Visual Studio process cannot load 32-bit compiled references. This specific hurdle has emerged as a significant adoption blocker for users with Windows Forms .NET Framework projects that extensively leverage ActiveX/COM controls or other custom controls embedded in 32-bit assemblies. Until now, the workaround for such scenarios was to use Visual Studio 2019, where the Windows Forms designer operated as a 32-bit process, accommodating the specific needs of these projects.
Recognizing the limitations imposed by this shift, and its impact on our developers, we have been working hard on features to pave the way for designing legacy WinForms 32-bit .NET Framework applications in the latest Visual Studio environment. While these initial efforts will not comprehensively solve the entire problem space, our aim is to unblock customers and make the transition to a 64-bit Visual Studio 2022 smoother.
In the most recent Visual Studio 2022 release, v17.9, the WinForms team introduced a preview feature – the out-of-process designer support for .NET Framework projects. The ability to use our out-of-process designer for .NET Framework is currently in an early preview state, and we eagerly seek developers’ feedback to refine and improve its functionality. Notably, the Visual Studio 17.9 release brought forth crucial enhancements, including:
- Improved Type Resolution for .NET Framework projects
- ActiveX/COM support for both .NET Framework and .NET projects
- A new Designer Selection Feature to monitor 32-bit assembly load failures in .NET Framework projects
These additions signify our commitment to actively engage with the community, understand the intricacies of their projects, and steadily build features that pave the way for the best possible Visual Studio experience. We hope this approach will make it easier for developers to eventually migrate to .NET to gain all the benefits of a more modern platform without a complete rewrite of the user interface.
What’s Designer Selection Feature?
When the WinForms designer detects a 32-bit assembly load failure, it presents the following dialog which provides an option to select appropriate designer for the developer’s project:
By choosing ‘Yes,’ the project is reloaded, and the Windows Forms out-of-process designer comes into play. If the project is targeting x86, the designer initiates a 32-bit process to render the Form in the designer. The process is identified as ‘FxDesignToolsServer.exe.’ Within this process, control assemblies are loaded, and it executes the code in ‘InitializeComponent’ method aligned with the specified framework.
On selecting ‘No,’ the project will continue to use in-process designer, although you still won’t be able to design forms referencing 32-bit components simply because 32-bit binaries cannot be loaded in a 64-bit process.
With ‘Yes/No’ buttons, the designer selection will remember this setting for the current Visual Studio instance only. To add the designer selection as a project configuration property automatically, enable the option ‘Remember for current project.’ It will add the ‘UseWinFormsOutOfProcDesigner’ property to each project configuration. The WinForms Designer will read this property value to select the desired Designer version (In-Process or Out-Of-Process) automatically the next time project is open in Visual Studio. Here is a sample project configuration after adding this property:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\Debug\</OutputPath>
<UseWinFormsOutOfProcDesigner>True</UseWinFormsOutOfProcDesigner>
</PropertyGroup>
Note that the Designer Selection feature is currently under the following preview feature flag which is enabled by default in Visual Studio 2022 17.9:
You can enable or disable the feature in Visual Studio under Tools -> Options -> Preview Features.
The below InfoBar will show up when you use out-of-process designer for .NET Framework projects:
What this feature does and what it doesn’t do.
In contrast to the in-process designer which loads all assemblies related to third-party controls into the Visual Studio process, the out-of-process designer needs to be pickier; it loads design-time assemblies either into a dedicated server process or into the client Visual Studio process. This distinction in assembly loading is necessary because of the client-server architecture of the out-of-process designer and as a result, third-party control vendors need to use the new designer SDK for providing controls for out-of-process designer. Note that creating different design time assemblies for client and server processes is not necessary to support simple scenarios but it is required for more advanced scenarios. Learn more about it here. As a result, the out-of-process designer for .NET Framework projects will not be able to handle all third-party controls designed for an in-process design environment. If it encounters such a control, there is a possibility that this will simply omit code related to controls the designer cannot render. Hence, we recommend that you create a backup of your project beforehand.
- Controls referenced in your project will not appear in the Toolbox for use in other forms in the solution, yet. We are aiming to add this ability in one of the upcoming releases.
- When loading controls in the out of process designer which have custom CodeDOM serializers, the designer will currently omit the generated code in InitializeComponent (because it cannot run the CodeDOM serializer the way it used to). We hope to add warnings in a future release that will let you know in advance that the project will not be able to load the particular component.
Side Note: You may find that there is a significant difference in the code generated in ‘InitializeComponent’ method in .NET Framework projects that are using the new SDK-style project files as compared to the older legacy csproj files. This is because the out-of-process designer, when it encounters SDK-style projects, utilizes Roslyn behind the scenes for code generation rather than the older CodeModel technology. Learn more about this feature here. In the long run, this is a big win for your code and supports future multi-targeting and migration paths. There may be minor tweaks in the code generated for those legacy csproj style projects, but these would be much less significant and would work just fine should the same project be opened in VS 2019.
Roadmap for .NET Framework projects support in the Out-of-Process Designer
As mentioned earlier in this blog, we plan to add support for the following features in out-of-process designer in upcoming Visual Studio releases:
- Enhance Toolbox support for controls referenced in the solution.
- More detailed warnings when the designer is unable to load controls with custom CodeDOM Serializers.
What can you do to prepare for a 64-bit world?
This feature is not intended to make the transition to Visual Studio 2022 action-free on the part of developers of WinForms .NET Framework applications that use legacy 32-bit components in their code. The development landscape has changed dramatically since many of these legacy components were created. Many of them do not meet today’s standards for code-security, for example. The Designer Selection Feature, and the related support for .NET Framework WinForms applications in the out-of-process designer is intended to be a short-term bridge to a final solution for your applications. In the long run, applications that are currently using 32-bit components have two potential options: either upgrade the component to something AnyCPU or 64-bit, or preferably, upgrade your application to .NET 8 and beyond. The .NET 8 platform has full support for 32-bit COM and ActiveX controls in WinForms applications. There is also a robust 3rd party control vendor ecosystem that is growing every day.
To find out more about the strategy WinForms is taking with 32-bit components, see Klaus Loffelmann and Merrie McGaw’s recent blog: WinForms in a 64-Bit world – our strategy going forward.
Closing
We appreciate the time you’ve spent reporting issues/suggestions and hope you continue to give us feedback when using Visual Studio on what you like and what we can improve. Your feedback is critical to help us make Visual Studio the best tool it can be! You can share feedback with us via Developer Community: report any bugs or issues via report a problem and share your suggestions for new features or improvements to existing ones.
Stay connected with the Visual Studio team by following us on YouTube, Twitter, LinkedIn, Twitch and on Microsoft Learn.
You mentioned Klaus and Merrie's recent blog post which is here: https://devblogs.microsoft.com/dotnet/winforms-designer-64-bit-path-forward/
I was surprised that I missed it, as I usually stay on top of all the DevBlogs news - especially anything WinForms related. When I page back through the DevBlogs history, the post doesn't show up. I can see 4 other posts on Feb 22nd but not this one.
It also doesn't show up if you search for "WinForms" (or any of the...
I believe the reason is that this post is categorized under ‘dotnet’ rather than ‘visualstudio’.
There are errors in the code within the blog. Specifically, the OutputPath attribute in the code is missing the ‘>’ character. See
Good catch. Thank you.
I know this is slightly off topic, and a battle that's already lost, but it still strikes me as strange that Microsoft continues to go to such lengths to ensure that people using WinForms on old versions of .NET Framework have not just runtime but design time support, but left people using WebForms completely out to dry without even the ability to _run_ our applications in modern .NET, or the source code available for the...