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

Updating the Default Settings file in a WinForms .NET 5 Visual Basic app fails. #6784

Closed
Tracked by #8058
KlausLoeffelmann opened this issue Dec 9, 2020 · 13 comments · Fixed by #7647
Closed
Tracked by #8058
Assignees
Labels
Area-VisualBasic Specific to the VB.NET language. Feature-WinForms Features related to bringing up the Windows Forms designer and related features. Must-Have Items that must be delivered by the end of the assigned milestone Triage-Investigate Reviewed and investigation needed by dev team
Milestone

Comments

@KlausLoeffelmann
Copy link
Member

Visual Studio Version:
>=16.8
Summary:
Attempting to save after changing a value in the Default Settings file of a WinForms .NET 5 Visual Basic app fails.

Steps to Reproduce:

  1. Create a new .NET 5 WinForms App.
  2. Insert a new App.Config to the project by chosing Add/New Items and General/Application Configuration File.
  3. Show All Files in the Solution Explorer and select the My Project branch.
  4. Insert a new Settings file to the project by choosing Add/New Items and General/Settings File. Make sure to rename the Name to Settings.settings.
  5. In the Settings editor, which appears now, add a value and try to save the settings.

Expected Behavior:
Settings file should be written, settings designer code be generated.
Actual Behavior:
image

Exception:
'An error occurred creating the configuration section handler for userSettings/VbWinForms5EventTest.Settings: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified.'

User Impact:
Interactively using the settings designer in a .NET 5 VB WinForms App is not possible.

Stack Trace:

   at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at Microsoft.VisualStudio.Shell.Design.Serialization.ConfigurationHelperService.GetConfigSection(Configuration config, String sectionName, Boolean isUserScoped, Boolean declare)
   at Microsoft.VisualStudio.Shell.Design.Serialization.ConfigurationHelperService.ReadSettings(ExeConfigurationFileMap fileMap, ConfigurationUserLevel userLevel, DocData appConfigDocData, String sectionName, Boolean isUserScoped, SettingsPropertyCollection settings)
   at Microsoft.VisualStudio.Editors.SettingsDesigner.AppConfigSerializer.SynchronizeUserConfig(String SectionName, IVsHierarchy Hierarchy, ConfigurationHelperService ConfigHelperService, Dictionary`2 SettingsTheDesignerKnownsAbout, DocData AppConfigDocData) in D:\Git\project-system\src\Microsoft.VisualStudio.Editors\SettingsDesigner\AppConfigSerializer.vb:line 402
   at Microsoft.VisualStudio.Editors.SettingsDesigner.AppConfigSerializer.SynchronizeUserConfig(String SectionName, IVsHierarchy Hierarchy, ConfigurationHelperService ConfigHelperService, DesignTimeSettings Settings, DocData AppConfigDocData) in D:\Git\project-system\src\Microsoft.VisualStudio.Editors\SettingsDesigner\AppConfigSerializer.vb:line 347
   at Microsoft.VisualStudio.Editors.SettingsDesigner.AppConfigSerializer.Serialize(DesignTimeSettings Settings, SettingsTypeCache typeCache, SettingsValueCache valueCache, String SectionName, DocData AppConfigDocData, IVsHierarchy Hierarchy, Boolean ShouldSynchronizeUserConfig) in D:\Git\project-system\src\Microsoft.VisualStudio.Editors\SettingsDesigner\AppConfigSerializer.vb:line 320
@KlausLoeffelmann KlausLoeffelmann added the Area-VisualBasic Specific to the VB.NET language. label Dec 9, 2020
@swesonga swesonga added this to the 16.10 milestone Dec 15, 2020
@swesonga swesonga added the Triage-Investigate Reviewed and investigation needed by dev team label Dec 15, 2020
@melytc melytc added the Feature-WinForms Features related to bringing up the Windows Forms designer and related features. label Apr 19, 2021
@jjmew jjmew added the Must-Have Items that must be delivered by the end of the assigned milestone label Apr 19, 2021
@tmeschter
Copy link
Contributor

The issue here is that we've serialized a System.Configuration.ClientSettingsSection containing the user settings to the app.config file. VS is a .NET Framework 4.8 app, but we know the WinForms app is targeting .NET 5, so we've used the Microsoft.VSDesigner.MultiTargetService to map to the .NET 5 type name (including the full assembly name) and that is what has been persisted in the file.

The problem is when we want to read that data later. The .NET Framework 4.8 (running in VS) doesn't know anything about that the .NET 5 assembly, and so it can't deserialize it for us.

The MultiTargetService was designed for a world where VS was always running on the latest .NET Framework, though you might be targeting an older version for you app. Since VS was always using the latest Framework, it could count on type forwarders being in place such that the runtime would always be able to deserialize types from previous versions. But now VS is using an older Framework version, and that design no longer works.

The only solution I can think of is to have a variant of the MultiTargetService that always returns .NET Framework 4.8 types names, regardless of the target type of the app, on the assumption that all .NET 5, 6, and 7 (and beyond) runtimes will have the appropriate type forwarding in place. The .NET Framework 4.8 version of a type name would effectively become the canonical version.

@tmeschter
Copy link
Contributor

My proposed solution will not work here. The System.Configuration shim assembly in .NET 5 does not have a type forwarder for System.Configuration.ClientSettingsSection, though it does have one for the base type, System.Configuration.ConfigurationSection.

@jjmew jjmew modified the milestones: 16.10, 17.0 Jun 22, 2021
@Perpete
Copy link

Perpete commented Aug 21, 2021

Hello,
By creating a first project with WPF in VB with .net 5 under the Visual Studio 16.11.1 version, I noticed the same issue while creating and using user settings in app.config.

When we add or modify parameters or values of these parameters and save the new information, we get the display of an error message.

Message :
'An error occurred while saving values to the app.config file. This file may be damaged or contains invalid XML code. '

2021-08-20 17_02_51-WpfApp5 - Microsoft Visual Studio

When using a parameter reading using one of the following instructions
lbEssai.Content = My.MySettings.Default.Essai or lbEssai.Content = My.Settings.Essai,
I have an error in the Settings.Designer.vb file.

2021-08-20 17_09_54-WpfApp5 (Débogage) - Microsoft Visual Studio

Here are the details of the error.

2021-08-20 17_47_15-_D__Documents_Visual Studio 2019_Projects_IOCenterOPC_DLL_IOCenterOPC_DLL sln -

Here is just my test program.

`Class MainWindow

Private Sub Button_Click(sender As Object, e As RoutedEventArgs)

	lbEssai.Content = My.MySettings.Default.Essai

	lbEssai.Content = My.Settings.Essai
End Sub

End Class`

The same program in C # works fine.

What is the solution in VB?

@Perpete
Copy link

Perpete commented Aug 21, 2021

Hello,
In the App.config file, I deleted all the contents of the 'system.diagnostics' tag.
I no longer have an error detected in the Settings.Designer.vb file when reading the setting.
The reading of the parameter value is correct.

2021-08-20 19_27_58-WpfApp5 - Microsoft Visual Studio

On the other hand, from the parameter data grid, there is always the display of the error message when adding or modifying the parameters or the values of these parameters when saving the new information.

@RussKie
Copy link
Member

RussKie commented Aug 31, 2021

@melytc @KlausLoeffelmann @KathleenDollard the diagnostics section is defined in a template under src/vsproject/Templates/Windows/VisualBasic/ItemTemplates/AppConfigurationInternal path.

@RussKie
Copy link
Member

RussKie commented Aug 31, 2021

Copying from AB#1388851

Different scenarios with associated steps to reproduce can be found at https://gist.github.com/RussKie/e33dd2ee4dc18a04f9237b6b42db9596

This is a functionality gap that impacts migration scenarios. In essence, whenever Settings.settings are written into an app.config versions must be locked at 4.0.0.0 and not at the current app's TFM:

    <configSections>

        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="settings_issue.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="settings_issue.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>

    </configSections>

@RussKie
Copy link
Member

RussKie commented Sep 1, 2021

.NET Framework

A brand new VB Windows Forms .NET Framework (4.7.2) app contains the following app.config
image

Adding/modifying settings makes the following changes to the app.config:
image

.NET

A brand new VB Windows Forms .NET (6.0) app does not contain an app.config.
A brand new app.config gets created when settings are added (unlike C#, AB#1386445) but the app.settings contains the spurious system.diagnostics section:
image

@RussKie
Copy link
Member

RussKie commented Sep 1, 2021

The second key problem is that the types are written against the app's TFM (e.g. net5.0), which is different from the VS TFM (net472), and this makes VS unable to parse the app.config. And it fails here:

Dim objectDirty As AppConfigSerializer.DirtyState =
AppConfigSerializer.Deserialize(RootComponent,
DirectCast(GetService(GetType(SettingsTypeCache)), SettingsTypeCache),
cfgHelper.GetSectionName(ProjectUtils.FullyQualifiedClassName(GeneratedClassNamespace(True), GeneratedClassName), String.Empty),
_appConfigDocData,
AppConfigSerializer.MergeValueMode.Prompt,
CType(GetService(GetType(System.Windows.Forms.Design.IUIService)), System.Windows.Forms.Design.IUIService))
If objectDirty <> AppConfigSerializer.DirtyState.NoChange Then
' Set flag if we make changes to the settings object during load that should
' set the docdata to dirty immediately after we have loaded.
'
' Since component change notifications are ignored while we are loading the object,
' we have to do this after the load is completed....
_modifiedDuringLoad = True
End If
Catch ex As Configuration.ConfigurationErrorsException
' We failed to load the app config xml document....
DesignerFramework.DesignUtil.ReportError(_serviceProvider, My.Resources.Microsoft_VisualStudio_Editors_Designer.SD_FailedToLoadAppConfigValues, HelpIDs.Err_LoadingAppConfigFile)
Catch Ex As Exception When ReportWithoutCrash(Ex, "Failed to load app.config", NameOf(SettingsDesignerLoader))
Throw
End Try

Here's what's is being currently serialised (-) instead of what must be serialised (+):

    <configSections>
-       <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" >
+       <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
-           <section name="WinFormsApp1.My.MySettings" type="System.Configuration.ClientSettingsSection, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+           <section name="WinFormsApp1.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
-       <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" >
+       <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
-           <section name="WinFormsApp1.My.MySettings" type="System.Configuration.ClientSettingsSection, System.Configuration.ConfigurationManager, Version=5.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" requirePermission="false" />
+           <section name="WinFormsApp1.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
  1. System.Configuration.ConfigurationManager -> System
  2. Version=5.0.0.0 -> Version=4.0.0.0
  3. PublicKeyToken=cc7b13ffcd2ddd51 -> PublicKeyToken=b77a5c561934e089

RussKie added a commit that referenced this issue Sep 29, 2021
* Pin configuration type names to the desktop identities so not only we
can create necessary configuration sections and serialize data, but also
that we can deserialize those as well.
Affected types:
    - System.Configuration.ApplicationSettingsGroup
    - System.Configuration.ClientSettingsSection
    - System.Configuration.UserSettingsGroup

Fixes #6784
Resolves dotnet/winforms#4308

* Remove ability to browse and serialize arbitrary types, and restrict
the set of type to the the known list

Resolves https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1388857/
@ghost ghost added the Resolution-Fixed The bug has been fixed, refer to the milestone to see in which release it was fixed. label Sep 30, 2021
@RussKie
Copy link
Member

RussKie commented Oct 1, 2021

Reopening as the rogue system.diagnostics section is still unaddressed. @KathleenDollard and @KlausLoeffelmann need to make a call.

@RussKie RussKie reopened this Oct 1, 2021
@melytc melytc removed the Resolution-Fixed The bug has been fixed, refer to the milestone to see in which release it was fixed. label Dec 7, 2021
@melytc melytc removed this from the 17.1 milestone Dec 7, 2021
@melytc melytc added this to the 17.2 milestone Dec 7, 2021
@merriemcgaw
Copy link
Member

@KlausLoeffelmann / @KathleenDollard a quick ping here to see how we want to proceed (most importantly for .NET 6 apps)

@KlausLoeffelmann
Copy link
Member Author

We need to discuss this with @melytc in the upcoming project system/vb sync.

@melytc
Copy link
Contributor

melytc commented May 4, 2022

Change missing here is removing the system.diagnostics content from the VB AppConfiguration template. Closing this in favor of #7448 which needs the same change.

@ocallesp
Copy link
Contributor

The PR https://devdiv.visualstudio.com/DevDiv/_git/VS/pullrequest/403807 should handle the issue in system.diagnostics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-VisualBasic Specific to the VB.NET language. Feature-WinForms Features related to bringing up the Windows Forms designer and related features. Must-Have Items that must be delivered by the end of the assigned milestone Triage-Investigate Reviewed and investigation needed by dev team
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants