-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Change IsolatedStorageFile path for mobile #83380
Changes from 11 commits
257eca4
e7f1816
b41f38b
22e3e92
4d6d9e5
a420ae1
9a062e8
887571f
b5cb260
c8093be
1b0c5ae
295d058
3ebde2b
af2ba4e
1563f3a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -5,6 +5,57 @@ namespace System.IO.IsolatedStorage | |||||
{ | ||||||
internal static partial class Helper | ||||||
{ | ||||||
// we're using a different directory name for compatibility with legacy Xamarin | ||||||
public const string IsolatedStorageDirectoryName = ".isolated-storage"; | ||||||
|
||||||
internal static string GetDataDirectory(IsolatedStorageScope scope) | ||||||
{ | ||||||
// This is the relevant special folder for the given scope plus IsolatedStorageDirectoryName. | ||||||
// It is meant to replicate the behavior of the VM ComIsolatedStorage::GetRootDir(). | ||||||
// | ||||||
// In legacy Xamarin for Roaming Scope we were using Environment.SpecialFolder.LocalApplicationData | ||||||
// In .Net 7 for Roaming Scope we are using Environment.SpecialFolder.ApplicationData | ||||||
// e.g. .Net 7 path = /data/user/0/{packageName}/files/.isolated-storage/{hash}/{hash}/AppFiles/ | ||||||
// e.g. Xamarin path = /data/user/0/{packageName}/files/.config/.isolated-storage" | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these example paths are from Android, I'd also add iOS examples to make it clearer |
||||||
// | ||||||
// Since we shipped that behavior as part of .NET 7 we can't change this now or upgraded apps wouldn't find their files anymore. | ||||||
// We need to look for an existing directory first before using the legacy Xamarin approach. | ||||||
|
||||||
Environment.SpecialFolder specialFolder = | ||||||
IsMachine(scope) ? Environment.SpecialFolder.CommonApplicationData : // e.g. /usr/share; | ||||||
IsRoaming(scope) ? Environment.SpecialFolder.ApplicationData : // e.g. /data/user/0/{packageName}/files/.config; | ||||||
Environment.SpecialFolder.LocalApplicationData; // e.g. /data/user/0/{packageName}/files; | ||||||
|
||||||
string dataDirectory = Environment.GetFolderPath(specialFolder); | ||||||
dataDirectory = Path.Combine(dataDirectory, IsolatedStorageDirectoryName); | ||||||
if (Directory.Exists(dataDirectory)) | ||||||
{ | ||||||
return dataDirectory; | ||||||
} | ||||||
// Otherwise return legacy xamarin path | ||||||
else | ||||||
{ | ||||||
specialFolder = | ||||||
IsMachine(scope) ? Environment.SpecialFolder.CommonApplicationData : | ||||||
IsRoaming(scope) ? Environment.SpecialFolder.LocalApplicationData: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need to change this case on Android since we had the breaking change of
You can use hardcoded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in general I'd recommend creating a sample app that uses all possible combinations for IsolatedStorageFile scopes and then comparing each computed path between Xamarin and dotnet to make sure they match |
||||||
Environment.SpecialFolder.ApplicationData; | ||||||
|
||||||
dataDirectory = Environment.GetFolderPath(specialFolder, Environment.SpecialFolderOption.Create); | ||||||
dataDirectory = Path.Combine(dataDirectory, IsolatedStorageDirectoryName); | ||||||
} | ||||||
|
||||||
return dataDirectory; | ||||||
} | ||||||
|
||||||
internal static string GetRandomDirectory(string rootDirectory, IsolatedStorageScope _) | ||||||
{ | ||||||
// In legacy Xamarin we didn't have a random directory inside of the isolated storage root for each app, | ||||||
// we tried to preserve that in https://github.com/dotnet/runtime/pull/75541 but the fix wasn't complete enough | ||||||
// and we still created random directories when not using the Roaming scope. | ||||||
// | ||||||
// Since we shipped that behavior as part of .NET 7 we can't change this now or upgraded apps wouldn't find their files anymore. | ||||||
// We need to look for an existing random directory first before using the plain root directory. | ||||||
return GetExistingRandomDirectory(rootDirectory) ?? rootDirectory; | ||||||
} | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,68 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Threading; | ||
using System.Security; | ||
|
||
namespace System.IO.IsolatedStorage | ||
{ | ||
internal static partial class Helper | ||
{ | ||
public const string IsolatedStorageDirectoryName = "IsolatedStorage"; | ||
|
||
internal static string GetDataDirectory(IsolatedStorageScope scope) | ||
{ | ||
// This is the relevant special folder for the given scope plus IsolatedStorageDirectoryName. | ||
// It is meant to replicate the behavior of the VM ComIsolatedStorage::GetRootDir(). | ||
|
||
// (note that Silverlight used "CoreIsolatedStorage" for a directory name and did not support machine scope) | ||
|
||
Environment.SpecialFolder specialFolder = | ||
IsMachine(scope) ? Environment.SpecialFolder.CommonApplicationData : // e.g. C:\ProgramData | ||
IsRoaming(scope) ? Environment.SpecialFolder.ApplicationData : // e.g. C:\Users\Joe\AppData\Roaming | ||
Environment.SpecialFolder.LocalApplicationData; // e.g. C:\Users\Joe\AppData\Local | ||
|
||
string dataDirectory = Environment.GetFolderPath(specialFolder, Environment.SpecialFolderOption.Create); | ||
dataDirectory = Path.Combine(dataDirectory, IsolatedStorageDirectoryName); | ||
|
||
return dataDirectory; | ||
} | ||
|
||
internal static string GetRandomDirectory(string rootDirectory, IsolatedStorageScope scope) | ||
{ | ||
string? randomDirectory = GetExistingRandomDirectory(rootDirectory); | ||
if (string.IsNullOrEmpty(randomDirectory)) | ||
{ | ||
using (Mutex m = CreateMutexNotOwned(rootDirectory)) | ||
{ | ||
if (!m.WaitOne()) | ||
{ | ||
throw new IsolatedStorageException(SR.IsolatedStorage_Init); | ||
} | ||
|
||
try | ||
{ | ||
randomDirectory = GetExistingRandomDirectory(rootDirectory); | ||
if (string.IsNullOrEmpty(randomDirectory)) | ||
{ | ||
// Someone else hasn't created the directory before we took the lock | ||
randomDirectory = Path.Combine(rootDirectory, Path.GetRandomFileName(), Path.GetRandomFileName()); | ||
CreateDirectory(randomDirectory, scope); | ||
} | ||
} | ||
finally | ||
{ | ||
m.ReleaseMutex(); | ||
} | ||
} | ||
} | ||
|
||
return randomDirectory; | ||
} | ||
|
||
private static Mutex CreateMutexNotOwned(string pathName) | ||
{ | ||
return new Mutex(initiallyOwned: false, name: @"Global\" + IdentityHelper.GetStrongHashSuitableForObjectName(pathName)); | ||
} | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment isn't meaningful for us, I'd remove it.