dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.62k stars 4.56k forks source link

Environment.GetFolderPath(Environment.SpecialFolder.Personal) returns different path for Xamarin.Forms and for MAUI on Android #102110

Open yevgeny-sotnikov opened 2 months ago

yevgeny-sotnikov commented 2 months ago

Description

During migration of an app from Xamarin.Forms was found weird behaviour:

Environment.GetFolderPath(Environment.SpecialFolder.Personal) returns another path on Android platform:

Xamarin.Forms: /data/user/0//files

MAUI: /data/user/0//files/Documents

It creates issue with an access to saved files during update process

Steps to Reproduce

  1. Create Core .net Standard project with class which returns Environment.GetFolderPath(Environment.SpecialFolder.Personal);
  2. Create Xamarin.Forms project and add reference to Core project.
  3. Call core-class from Xamarin.Forms somehow, check string
  4. Create MAUI project and add reference to Core project.
  5. Call core-class from MAUI somehow, check string
  6. Compare strings from both apps

Link to public reproduction project repository

https://github.com/yevgeny-sotnikov/MAUI-issues/tree/environment-folder-android-issue

Version with bug

8.0.7 SR2

Is this a regression from previous behavior?

Yes, this used to work in Xamarin.Forms

Last version that worked well

5.0.0.2012

Affected platforms

Android

Affected platform versions

Android 10 and upper

Did you find any workaround?

Remove last Documents folder at path

Relevant log output

No response

vitek-karas commented 2 months ago

@ivanpovazan - possibly related to the other issue around GetFolderPath.

ivanpovazan commented 2 months ago

@yevgeny-sotnikov the behaviour in Xamarin.Forms was incorrect and it didn't meet user expectations for Linux, macOS, and Android. In .NET8 preview 1 we corrected this and introduced this breaking change: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/8.0/getfolderpath-unix

To get the desired behaviour, the recommended action is to use: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) instead.


@jonathanpeppers what would be the best place to include information about such required actions while migrating to MAUI?

yevgeny-sotnikov commented 2 months ago

@ivanpovazan

@yevgeny-sotnikov the behaviour in Xamarin.Forms was incorrect and it didn't meet user expectations for Linux, macOS, and Android. In .NET8 preview 1 we corrected this and introduced this breaking change: https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/8.0/getfolderpath-unix

To get the desired behaviour, the recommended action is to use: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) instead.

Will it keep same folder path on iOS and mac (same as at xamarin)? I don't want to change current folder of files for all platforms

jonathanpeppers commented 2 months ago

@ivanpovazan if you wanted to add a note here, and link to that getfolderpath-unix page:

There is probably a similar page for Xamarin.iOS.

jaosnz-rep commented 2 months ago

Can repro this issue at Android platform on the latest 17.10 Preview 5 (8.0.1 & 8.0.20 & 8.0.14).

Eilon commented 2 months ago

@jonathanpeppers - is this a dotnet/runtime issue?

dotnet-policy-service[bot] commented 2 months ago

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

vitek-karas commented 2 months ago

The macCatalyst version of this is https://github.com/dotnet/runtime/issues/100440. @yevgeny-sotnikov could you please check it - there we plan to change the behavior at least in some cases.

ivanpovazan commented 6 days ago

Will it keep same folder path on iOS and mac (same as at xamarin)? I don't want to change current folder of files for all platforms

It depends on which folder you would expect to retrieve. The following tables describe the difference between the behavior in previous releases (and the introduced breaking change in .NET8).

.NET 7 Android iOS MacOS
Environment.GetFolderPath(Environment.SpecialFolder.Personal) /data/user/0/app_name/files /var/mobile/Containers/Data/Application/app_guid/Documents /Users/username/
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) /data/user/0/app_name/files /var/mobile/Containers/Data/Application/app_guid /Users/username/
.NET 8
Environment.GetFolderPath(Environment.SpecialFolder.Personal) /data/user/0/app_name/files/Documents /var/mobile/Containers/Data/Application/app_guid/Documents /Users/username/Documents
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) /data/user/0/app_name/files /var/mobile/Containers/Data/Application/app_guid /Users/username/

Please let us know if you have any other question.

dotnet-policy-service[bot] commented 6 days ago

This issue has been marked needs-author-action and may be missing some important information.

kiranbasvaraj commented 1 day ago

Even i have the same issue with local dabase where the app failed to get the data base path i have tried the above solution of using Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) but Application is failing to deploy on top of xamarin forms application.

ivanpovazan commented 1 day ago

@kiranbasvaraj I am not sure I understand this part:

Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) but Application is failing to deploy on top of xamarin forms application.

Are you also doing the migration from Xamarin.Forms to MAUI? Which platform are you targeting?