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

IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and .NET 6 builds on iOS #74642

Closed
dtaylorus opened this issue Aug 26, 2022 · 9 comments · Fixed by #75541
Assignees
Milestone

Comments

@dtaylorus
Copy link

dtaylorus commented Aug 26, 2022

Description

The path of a file created by IsolatedStorageFile.GetUserStoreForApplication() changes between Xamarin.iOS and .NET 6, and also changes between different builds of the application under .NET 6.

This makes IsolatedStorageFile unusable in .NET 6 since an updated build cannot open a file created by a previous build. Each time the build is updated, all of the files previously created on behalf of the user are effectively gone.

For example, the following code:

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
            // Write file contents here

results in the file being written to various locations in the iOS device file system depending on the build of the application:

/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.j1gfq4nxq1m4zfi31rjvtcuna3umf3fb/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.vb0fraupqrlwtvom530yjpnqlhlbggfc/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.az1iqc1z0lv42e3agh4zvg5aa5rbihzj/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.efra4nhzgkrws2l30v4hbayjiohm2ofj/AppFiles/settings.txt
...

In Xamarin.iOS the path of the file was consistent across builds of the app.

Reproduction Steps

Build the code below on Xamarin.iOS and execute on an iOS device.
Migrate the app to dotnet 6, rebuild and execute on the same iOS device.
Note that the file is created in a different file system location on the device.
Clean and rebuild the dotnet 6 app and execute on the same iOS device.
Note that the file is created in yet another file system location on the device.

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
        }
    }

Expected behavior

The settings.txt file should be created in the same file system location (path) for every version of the built application.

Actual behavior

The settings.txt file is created in a different file system location (path) for every version of the built application on dotnet 6

Regression?

Yes, this is a regression. The file system path for IsolatedStorageFile was consistent in .NET Framework applications I've built over the past decade with many different versions of .NET and Xamarin.iOS.

Known Workarounds

I don't know of any workaround using the .NET 6 IsolatedStorageFile API. Applications would have to use some other file system API and maybe Environment.GetFolderPath(SpecialFolder folder).

Configuration

.NET 6
iOS
ARM64

This issue is specific to .NET 6 on iOS

Other information

No response

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Aug 26, 2022
@ghost
Copy link

ghost commented Aug 26, 2022

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

Issue Details

Description

The path of a file created by IsolatedStorageFile.GetUserStoreForApplication() changes between Xamarin.iOS and dotnet 6, and also changes between different builds of the application under dotnet 6.

For example, the following code:

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
            // Write file contents here

results in the file being written to various locations in the iOS device file system depending on the build of the application:

/var/mobile/Containers/Data/Application/9E0C3C7C-7705-4561-9301-9D14F7D5078D/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.j1gfq4nxq1m4zfi31rjvtcuna3umf3fb/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/9E0C3C7C-7705-4561-9301-9D14F7D5078D/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.vb0fraupqrlwtvom530yjpnqlhlbggfc/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/9E0C3C7C-7705-4561-9301-9D14F7D5078D/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.az1iqc1z0lv42e3agh4zvg5aa5rbihzj/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/9E0C3C7C-7705-4561-9301-9D14F7D5078D/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.efra4nhzgkrws2l30v4hbayjiohm2ofj/AppFiles/settings.txt
...

In Xamarin.iOS the path of the file was consistent across builds of the app.

Reproduction Steps

Build the code below on Xamarin.iOS and execute on an iOS device.
Migrate the app to dotnet 6, rebuild and execute on the same iOS device.
Note that the file is created in a different file system location on the device.
Clean and rebuild the dotnet 6 app and execute on the same iOS device.
Note that the file is created in yet another file system location on the device.

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
        }
    }

Expected behavior

The settings.txt file should be created in the same file system location (path) for every version of the built application.

Actual behavior

The settings.txt file is created in a different file system location (path) for every version of the built application on dotnet 6

Regression?

Yes, this is a regression. The file system path for IsolatedStorageFile was consistent in .NET Framework applications I've built over the past decade with many different versions of .NET and Xamarin.iOS.

Known Workarounds

I don't know of any workaround using the dotnet IsolatedStorageFile API. Applications would have to use some other file system API and maybe Environment.GetFolderPath(SpecialFolder folder).

Configuration

dotnet 6
iOS
ARM64

This issue is specific to dotnet 6 on iOS

Other information

No response

Author: dtaylorus
Assignees: -
Labels:

area-System.IO

Milestone: -

@dtaylorus
Copy link
Author

dtaylorus commented Aug 26, 2022

The legacy IsolatedStorageFile.GetUserStoreForApplication() folder on Xamarin.iOS is:

    /var/mobile/Containers/Data/Application/<GUID>/Documents/.config/.isolated-storage/

As a workaround, this path can be recreated manually in .NET 6 using Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) as the base path and appending ".config/.isolated-storage/".

Legacy files can then be accessed using System.IO.File instead of IsolatedStorageFile.

@dtaylorus dtaylorus changed the title IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and dotnet 6 builds on iOS IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and .NET 6 builds on iOS Aug 27, 2022
@dtaylorus
Copy link
Author

dtaylorus commented Aug 27, 2022

This is broken in the same way on Android. The legacy IsolatedStorageFile.GetUserStoreForApplication() folder on Xamarin.Android is:

    /data/user/0/<PackageId>/files/.config/.isolated-storage/

As a workaround, this legacy path can be recreated manually in .NET 6 using Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) as the base path and appending ".config/.isolated-storage/".

Legacy files can then be accessed using System.IO.File instead of IsolatedStorageFile.

@ghost
Copy link

ghost commented Aug 27, 2022

Tagging subscribers to 'os-ios': @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

The path of a file created by IsolatedStorageFile.GetUserStoreForApplication() changes between Xamarin.iOS and .NET 6, and also changes between different builds of the application under .NET 6.

This makes IsolatedStorageFile unusable in .NET 6 since an updated build cannot open a file created by a previous build. Each time the build is updated, all of the files previously created on behalf of the user are effectively gone.

For example, the following code:

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
            // Write file contents here

results in the file being written to various locations in the iOS device file system depending on the build of the application:

/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.j1gfq4nxq1m4zfi31rjvtcuna3umf3fb/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.vb0fraupqrlwtvom530yjpnqlhlbggfc/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.az1iqc1z0lv42e3agh4zvg5aa5rbihzj/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.efra4nhzgkrws2l30v4hbayjiohm2ofj/AppFiles/settings.txt
...

In Xamarin.iOS the path of the file was consistent across builds of the app.

Reproduction Steps

Build the code below on Xamarin.iOS and execute on an iOS device.
Migrate the app to dotnet 6, rebuild and execute on the same iOS device.
Note that the file is created in a different file system location on the device.
Clean and rebuild the dotnet 6 app and execute on the same iOS device.
Note that the file is created in yet another file system location on the device.

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
        }
    }

Expected behavior

The settings.txt file should be created in the same file system location (path) for every version of the built application.

Actual behavior

The settings.txt file is created in a different file system location (path) for every version of the built application on dotnet 6

Regression?

Yes, this is a regression. The file system path for IsolatedStorageFile was consistent in .NET Framework applications I've built over the past decade with many different versions of .NET and Xamarin.iOS.

Known Workarounds

I don't know of any workaround using the .NET 6 IsolatedStorageFile API. Applications would have to use some other file system API and maybe Environment.GetFolderPath(SpecialFolder folder).

Configuration

.NET 6
iOS
ARM64

This issue is specific to .NET 6 on iOS

Other information

No response

Author: dtaylorus
Assignees: -
Labels:

area-System.IO, os-android, untriaged, os-ios

Milestone: -

@mkhamoyan
Copy link
Member

Hi @dtaylorus,
I was trying to reproduce it locally from both runtime and from maui app, but still I can see after several builds same URl."hash". Here are my steps from maui.

  1. Created Maui app and added these lines
    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
    using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
    // Write file contents here
  2. Tried several times clean/build, uninstalling app from phone but the root is still the same.
    This was what I saw for several builds
    "/data/user/0/com.companyname.testmaui/files/IsolatedStorage/0h0aylru.guc/lh5b4jf5.cnu/Url.kvaj4cxhwjeypoiko55puloz0kgusnnw/AppFiles/"

I'm trying on Android device, running on Debug mode using Visual Studio 2022 for Mac v17.4 Preview. (For release mode unfortunately I still have exception while running, working on it)
Could you please add more details which mode are you running and if possible upload your project ?

@dtaylorus
Copy link
Author

Probably the simplest thing to do is create the same project for legacy Xamarin.Android (not .NET 6) and see that the path is completely different and doesn't even contain the 'Url' part of the path that is new in .NET 6 for Android.

This means that projects that were released on legacy Xamarin.Android will lose access to files created with IsolatedStorageFile after upgrading the project to .NET 6.

If this backward compatibility issue is fixed, the part of this issue about the path constantly changing will be irrelevant anyway since there won't be a Url part of the path that can change.

Also note that I found the behavior about the path changing on .NET 6 for iOS, not Android. I only verified that the backward compatibility issue exists on Android (where the path changes between Xamarin.Android and .NET 6 for Android). I have not tested for the changing path between builds on Android being the same as on iOS.

Hope that makes sense. Thanks for looking into this issue

@dtaylorus
Copy link
Author

dtaylorus commented Aug 30, 2022

To answer your specific questions, I'm building on Visual Studio 2022 for Windows. My Android builds are local (SDK version 33) and my iOS builds are via a remote connection to a MacOS machine. I've tested in both debug and release builds and the results appear to be the same.

My project is a released app that is way too big to share. I encountered this problem when I was forced to upgrade the project to .NET 6 because of some dependencies. I was able to work around the issue by replacing all references to IsolatedStorageFile with direct use of System.IO.File.

@steveisok steveisok removed the untriaged New issue has not been triaged by the area owner label Sep 12, 2022
@steveisok steveisok added this to the 8.0.0 milestone Sep 12, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 13, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 16, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 16, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 16, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 16, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 16, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 20, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 20, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 26, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 26, 2022
mkhamoyan added a commit to mkhamoyan/runtime that referenced this issue Sep 26, 2022
mkhamoyan added a commit that referenced this issue Sep 27, 2022
* #74642 changed isolated storage path for mobile platforms
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
github-actions bot pushed a commit that referenced this issue Sep 27, 2022
@akoeplinger
Copy link
Member

akoeplinger commented Sep 28, 2022

This was fixed in main with #74642 and we have a backport PR open to fix it for .NET 7 with #76254

@dtaylorus
Copy link
Author

Fantastic. Thanks all!

carlossanlop pushed a commit that referenced this issue Sep 28, 2022
* #74642 changed isolatedstorage path

* #74642 Refactored and changed root only for mobile

* #74642 minor changes

* #74642 removed redundunt code

* #74642 rename IsolatedStorageDirectoryName

* #74642 change also in comments

* #74642 changed IsolatedStorageDirectoryName for only mobile

* #74642 done minor changes

* #74642 made IsolatedStorageDirectoryName const

* #74642 removed whitespaces

* #74642 fix csproj for linux

Co-authored-by: Meri Khamoyan <[email protected]>
@ghost ghost locked as resolved and limited conversation to collaborators Oct 29, 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.

5 participants