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

Reading application settings in NET WinForms OOP designer fails with exception 'Invalid URI: The hostname could not be parsed" #70318

Closed
tracktownsoftware opened this issue May 27, 2022 · 29 comments · Fixed by #71082

Comments

@tracktownsoftware
Copy link

Environment

Version 17.2.2

.NET version

net6.0-windows

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

No, this is new in VS2022 and the NET WinForms OOP designer.

Issue description

This is an issue in the new NET WinForms designer when using the microsoft.winforms.designer.sdk to add design-time support to a custom NET6 WinForms control. Reading application settings at design-time fails with exception “Invalid URI: this hostname could not be parsed”.

I also reported this as feedback from VS2022:
https://developercommunity.visualstudio.com/t/Reading-application-settings-fails-in-th/10055004

Steps to reproduce

My github sample to reproduce:
https://github.com/tracktownsoftware/MicrosoftWinFormsDesignerSDK_AppSettingsBug

The above repository includes a Nuget package you can use to test and reproduce. The nuget package contains a custom NET6 WinForms "MyButton" control with WinForms Designer Extensibility SDK design-time support.

Diagnostics

No response

@tracktownsoftware tracktownsoftware added area: VS designer untriaged New issue has not been triaged by the area owner labels May 27, 2022
@RussKie
Copy link
Member

RussKie commented May 30, 2022

The application settings are resolved in the context of the currently running app - which in the case of the out-of-proc designer is DesignToolsServer.dll.

Here's what's going on here. When we're trying to resolve Properties.Settings.HelloWorld, the .NET runtime is trying to locate the DesignToolsServer's settings and it fails here:

System.Private.Uri.dll!System.Uri.Uri(string uriString)
System.Configuration.ConfigurationManager.dll!System.Configuration.ClientConfigPaths.ClientConfigPaths(string exePath = null, bool includeUserConfig) Line 77
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs(77)
System.Configuration.ConfigurationManager.dll!System.Configuration.ClientConfigPaths.GetPaths(string exePath, bool includeUserConfig = true) Line 212
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ClientConfigPaths.cs(212)
System.Configuration.ConfigurationManager.dll!System.Configuration.Internal.ConfigurationManagerInternal.System.Configuration.Internal.IConfigurationManagerInternal.ExeProductName.get() Line 19
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/Internal/ConfigurationManagerInternal.cs(19)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.Initializer.get() Line 678
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(678)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.CreateSetting(System.Reflection.PropertyInfo propertyInfo = {System.Reflection.RuntimePropertyInfo}) Line 459
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(459)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.EnsureInitialized() Line 584
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(584)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.Properties.get() Line 140
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(140)
System.Configuration.ConfigurationManager.dll!System.Configuration.SettingsBase.GetPropertyValueByName(string propertyName = "HelloWorld") Line 55
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsBase.cs(55)
System.Configuration.ConfigurationManager.dll!System.Configuration.SettingsBase.this[string].get(string propertyName) Line 29
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/SettingsBase.cs(29)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.GetPropertyValue(string propertyName = "HelloWorld") Line 731
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(731)
System.Configuration.ConfigurationManager.dll!System.Configuration.ApplicationSettingsBase.this[string].get(string propertyName) Line 403
	at /_/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ApplicationSettingsBase.cs(403)
MyButtonLibrary.dll!MyButtonLibrary.Properties.Settings.HelloWorld.get()
MyButtonLibrary.dll!MyButtonLibrary.MyButton.ApplicationSettingsTest()
MyButtonLibrary.Design.dll!MyButtonLibrary.Design.MyButtonActionList.ApplicationSettingsBug()

The issue here is that the designer is located at a path similar to \\?\C:\Users\user\AppData\Local\Microsoft\VisualStudio\17.0_dfbd86c6Exp\WinFormsDesigner\figs3bhx.mvu\ and Uri is unable to handle \\? paths. This was fixed in #56897 for .NET 7, however, it doesn't appear the change was complete as .NET 7 still fails with the same error, though at a different point:
image
/cc: @krwq @jeffhandley

@MelonWang1
Copy link

Repro Steps:
1. Create a Winforms .NET Core 6.0 application
2. Download and copy "MyButtonLibrary.1.0.102.nupkg" from "\Pack\packages\MyButtonLibrary.1.0.102.nupkg" to "C:\Program Files (x86)\Microsoft SDKs\NuGetPackages"
3. Right click the project and select " Manguage NuGet Packages…"
4. The Package source select All and switch Installed to Browse
5. Search and install "MyButtonLibrary"
6. Switch to Form designer, drag and drop MyButton control onto Form1
7. Right click control and select "Change button text using application setting - This FAILS"

Actual Result:
The exception pops up.
error
seeting

Expected Result:
No exception pops up.

@tracktownsoftware
Copy link
Author

Do you have an ETA when this might be fixed? This issue has blocked us from adding design-time support for our NET6 WinForms control. We can't release until this is fixed.
Thanks.

@dotnet-issue-labeler
Copy link

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

@RussKie RussKie transferred this issue from dotnet/winforms Jun 7, 2022
@RussKie
Copy link
Member

RussKie commented Jun 7, 2022

@jeffhandley @krwq putting this on your radar.

@ghost
Copy link

ghost commented Jun 7, 2022

Tagging subscribers to this area: @dotnet/area-system-configuration
See info in area-owners.md if you want to be subscribed.

Issue Details

Environment

Version 17.2.2

.NET version

net6.0-windows

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

No, this is new in VS2022 and the NET WinForms OOP designer.

Issue description

This is an issue in the new NET WinForms designer when using the microsoft.winforms.designer.sdk to add design-time support to a custom NET6 WinForms control. Reading application settings at design-time fails with exception “Invalid URI: this hostname could not be parsed”.

I also reported this as feedback from VS2022:
https://developercommunity.visualstudio.com/t/Reading-application-settings-fails-in-th/10055004

Steps to reproduce

My github sample to reproduce:
https://github.com/tracktownsoftware/MicrosoftWinFormsDesignerSDK_AppSettingsBug

The above repository includes a Nuget package you can use to test and reproduce. The nuget package contains a custom NET6 WinForms "MyButton" control with WinForms Designer Extensibility SDK design-time support.

Diagnostics

No response

Author: tracktownsoftware
Assignees: -
Labels:

area-System.Configuration, untriaged, area: VS designer

Milestone: -

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 14, 2022

Thanks for the clear repro @tracktownsoftware and the additional details @RussKie as you pointed out the issue caused by the AppDomain.CurrentDomain.BaseDirectory path prefixed with \\?\ when creating Uri at:

Uri codeBase = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.ManifestModule.Name));

I could be able to fix this by removing the prefix if exist or something like that, but it seems better to be fixed at the Uri constructor or AppDomain.CurrentDomain.BaseDirectory level as @jkotas suggested in previous PR so that we will not see similar issues again. One of the issues even closed, so I would suggest you to go to those issues and ask for urgent fix

@buyaa-n buyaa-n removed the untriaged New issue has not been triaged by the area owner label Jun 14, 2022
@buyaa-n buyaa-n added this to the 7.0.0 milestone Jun 14, 2022
@RussKie
Copy link
Member

RussKie commented Jun 21, 2022

@karelz this is a core scenario for the Windows Forms designer

@danmoseley
Copy link
Member

@MihaZupan

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 21, 2022

Another workaround could be move the Uri creation code

Uri codeBase = new Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, assembly.ManifestModule.Name));

to the location where it is used:
This workaround at least works for the repro attached

@karelz
Copy link
Member

karelz commented Jun 21, 2022

I just answered on the other issue - #58712 (comment), trying to explain the context and limitations we are facing in the Uri space.
If there is reasonable workaround, we should strongly consider it before investing into Uri feature which is risky this late in the release cycle.

Who can help us better understand the details of the above scenario of \\?\ paths in Uri? Mainly why and how it is used, why Uri instead of Path, etc.

@jkotas
Copy link
Member

jkotas commented Jun 21, 2022

I agree with @karelz that fixing anything in Uri is complex and has very high risks. It does not make sense to push to address this in Uri for .NET 7. It would be a new feature and it may require new APIs.

There are cheaper and lower risk options to address the specific WinForms issue. We should look at those: Workaround it in the System.Configuration.ConfigurationManager library itself, or fix #58714

@jkotas
Copy link
Member

jkotas commented Jun 21, 2022

the details of the above scenario of \?\ paths in Uri? Mainly why and how it is used, why Uri instead of Path, etc.

Compatibility with .NET Framework.

The original .NET Framework code is here: https://github.com/microsoft/referencesource/blob/5697c29004a34d80acdaf5742d7e699022c64ecd/System.Configuration/System/Configuration/ClientConfigPaths.cs#L343-L411 . Notice that it does not use the problematic Uri constructor.

This is trying to mimic .NET Framework logic that was based on Code Access Security. It looks like that this logic deviated over time from .NET Framework one through series of bug fixes, so it does not fully match what .NET Framework did anyway. Another option to address the WinForms issues is to delete the part of the logic that tries to use Uris. It may be an observable behavior change, but I doubt that anybody will notice.

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 21, 2022

Another option to address the WinForms issues is to delete the part of the logic that tries to use Uris. It may be an observable behavior change, but I doubt that anybody will notice.

Looked up for all Uri creation within the System.Configuration.ConfigurationManager project and this is the only case that needs action. Only one other hit found which is already guarded with Uri.IsWellFormedUriString.

if (Uri.IsWellFormedUriString(externalConfigPath, UriKind.Absolute))
{
Uri externalConfigUri = new Uri(externalConfigPath, UriKind.Absolute);

I will move the that case as I mentioned here and probably use Uri.TryCreate() instead of using ctor

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jun 21, 2022
@RussKie
Copy link
Member

RussKie commented Jun 22, 2022

Looks like the discussion has split between here and #58712. And since the latter is closed, in attempt to merge the forks, @karelz I'm going to reply to your questions here:

Key questions I have: How does it work on .NET Framework? Is it a breaking change between .NET Core and .NET Framework?

In .NET Framework the Windows Forms designer is run in the VS process (as both the host and the designer use the same runtime). To facilitate the .NET support the designer was moved out-of-proc, and the server process is started with \\?\ path.

Are there workaround options?

There aren't any workarounds we can do in the designer AFAIK - as this is purely a .NET runtime scenario. I first reported at almost a year ago in #56897.
As for the .NET runtime - looks like @buyaa-n and @jkotas may have found a way to fix it, #70318 (comment).

It is worth noting, that the Windows Forms out-of-process designer codebase is targeting .NET Core 3.1 so that our customers can design .NET Windows Forms apps targeting .NET Core 3.1 and above. With .NET Core 3.1 starting to near its EOL there's no appetite to get this fixed in it, but we'd want the fix to be serviced in to .NET 6, as this bug is blocking the adoption (e.g., this one or #56897).

@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jun 22, 2022
@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 22, 2022

@RussKie the fix merged to preview 6, hope you could dogfood from there and test the WinForms designer scenarios

It fixes the repro attached to the issue, I don't see any other Uri creation logic that could cause similar issue within System.Configuration.ConfigurationManager project so I would not expect you will encounter an issue with similar root cause

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 22, 2022

but we'd want the fix to be serviced in to .NET 6, as this bug is blocking the adoption (e.g., this one or #56897)

Tagging @ericstj @jeffhandley for considering porting to .NET 6,

@buyaa-n buyaa-n reopened this Jun 22, 2022
@RussKie
Copy link
Member

RussKie commented Jun 23, 2022

Thank you @buyaa-n for the fix. I'll give it a try once it flows through to dotnet/winforms.

@ericstj
Copy link
Member

ericstj commented Jun 24, 2022

Can folks familiar with the bug and fix consider the servicing bug bar to see if they'd like to make the case to fix in .NET 6.0 servicing? If so, then the next steps would be to prepare such a PR and apply the template.

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 29, 2022

Can folks familiar with the bug and fix consider the servicing bug bar to see if they'd like to make the case to fix in .NET 6.0 servicing? If so, then the next steps would be to prepare such a PR and apply the template.

In our area pod triage we discussed this and decided to move forward with servicing request, the bot created the porting PR but I just found that 6.0 branch doesn't have the previous fix @krwq did, without that the fix is incomplete, not sure what we do in such case, I could cherry-pick the @krwq's change into the PR.

Further I am planning to build the 6.0 porting branch and give the binaries to @RussKie so that he test with their scenario before requesting for servicing.

@RussKie
Copy link
Member

RussKie commented Jun 30, 2022

Could you give me a hand and point me a release that I can test? I've downloaded the latest nightly (7.0.100-preview.7.22329.1) from dotnet/installer, and it only contains the runtime build from 15 June (7.0.0-preview.6.22314.11+eeb0c1551b5fc9ccd6ceeaf5d2b1504afab249d7), and the fix was merged on 23 June.
Thank you

@RussKie
Copy link
Member

RussKie commented Jun 30, 2022

I am afraid this won't work. The daily build contains only Microsoft.NETCore.App workload, and the fix went into System.Configuration.ConfigurationManager.dll, which is a part of Microsoft.WindowsDesktop.App workload.

@jkotas
Copy link
Member

jkotas commented Jun 30, 2022

You should be able to get daily build of the System.Configuration.ConfigurationManager.dll package using the instructions at the top of the document.

@buyaa-n
Copy link
Contributor

buyaa-n commented Jun 30, 2022

Could you give me a hand and point me a release that I can test?

In addition to what @jkotas suggestion I also sent you email with System.Configuration.ConfigurationManager.6.0.1.nupkg package built from 6.0 branch with the fixes

@buyaa-n
Copy link
Contributor

buyaa-n commented Jul 13, 2022

@RussKie please let us know your test result so that we can complete the servicing request

@buyaa-n buyaa-n modified the milestones: 7.0.0, 6.0.x Jul 13, 2022
@RussKie
Copy link
Member

RussKie commented Jul 22, 2022

Thank you @buyaa-n.

I installed 7.0.100-rc.1.22371.1 available at https://github.com/dotnet/installer, and tested the repro provided in https://github.com/tracktownsoftware/MicrosoftWinFormsDesignerSDK_AppSettingsBug. I created a Windows Forms app targeting .NET 7 and referenced the built NuGet from the repro project.

The issue is fixed:

70318.mp4

@RussKie
Copy link
Member

RussKie commented Jul 22, 2022

I have also retested the repro from #56897 (comment), and it also appears to be fixed by this.

🎉

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 22, 2022
@buyaa-n
Copy link
Contributor

buyaa-n commented Jul 22, 2022

Thanks @RussKie, updated the servicing PR description as needed, will send out servicing request email on Monday

@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 11, 2022
@buyaa-n buyaa-n closed this as completed Aug 15, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Sep 14, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants