dotnet / runtime

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

LocalApplicationData path does not get created #74884

Open R0BC0D3R opened 2 years ago

R0BC0D3R commented 2 years ago

Description

I have an application created from .NET MAUI Blazor App template.

When creating directory inside LocalApplicationData path, it returns success but there is no actually directory created. The first time code from Steps to Reproduce runs it will create the directory and any consecutive time Directory.Exists will return true, yet when application tries to open that newly created directory or when you browse to that path in File Explorer, it's not there.

This affects Windows and Android. I have not tested with iOS.

Steps to Reproduce

string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MyApp1");

if (!Directory.Exists(path))
{
    DirectoryInfo dir = Directory.CreateDirectory(path);
}

Version with bug

Preview 14 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android, Windows

Affected platform versions

Windows SDK 10.0.19041, Android 11.0

Did you find any workaround?

Replacing LocalApplicationData with CommonApplicationData works on Windows, but fails on Android with error: System.IO.IOException: 'Read-only file system : '/usr/share/MyApp1''

Relevant log output

No response

shimingsg commented 2 years ago

verified with VS 17.2.0 Preview 3.0 [32317.342.main] on windows and Android 11 with above code snippet

Redth commented 2 years ago

For now, we recommend using the FileSystem type in MAUI to get these folders.

@steveisok should this issue be moved to runtime at least for iOS/Android?

For .NET 7 it seems like a good idea to make these API's do something more expected/useful.

steveisok commented 2 years ago

@directhex do you recall the LocalApplicationData behavior on Android?

directhex commented 2 years ago

The only time I ever really messed with this was for Catalyst. Need to dig through the old Catalyst related PRs to find whether there was discussion around behaviour on other platforms

Sent from my iPhone

On Mar 22, 2022, at 1:56 PM, Steve Pfister @.***> wrote:

 @directhex do you recall the LocalApplicationData behavior on Android?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

FarFlyer commented 2 years ago

For now, we recommend using the FileSystem type in MAUI to get these folders.

@steveisok should this issue be moved to runtime at least for iOS/Android?

For .NET 7 it seems like a good idea to make these API's do something more expected/useful.

In the RC1 I got this error using Filesystem: 'FileSystem' is an ambiguous reference between 'Microsoft.Maui.Storage.FileSystem' and 'System.IO.FileSystem'

Ewerton commented 2 years ago

I'am having the exact same problem. Furthermore, I don't know how to create a Directory since the FileSystemclass doesn't have something like FileSystem.CreateDirectory(path) method to call

Ewerton commented 2 years ago

@R0BC0D3R Maybe my findings today could help you and others. In my project I was trying to create an custom folder and, inside it, create and sqlite db file (MyDatabase.db): My project is an .Net MAUI Native App, so the path where I tried to create my custom folder is: Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) which evaluates to C:\Users\ewer\AppData\Local\ After I call Directory.CreateDirectory(path) I opened Windows Explorer at that location and my new folder wasn't there. So I tried to use the Windows Search to search for MyDatabase.db and... Bingo! The file was in the followin path C:\Users\ewer\AppData\Local\Packages\A7BC0349-3D8D-4A12-9E79-B65BC495C95E_9zz4h110yvjzm\LocalCache\Local So, for some reason which I don't know, Visual Studio generates that random folder name and put things there.

degenet commented 2 years ago

I'm experiencing the same issue. The only way I could get it to work was to retrieve the package ID from

Windows.ApplicationModel.Package.Current.Id.FamilyName

ghost commented 2 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ccarv commented 2 years ago

Until this is addressed, Blazor MAUI applications cannot save settings to AppData. This should be a high priority item.

ghost commented 2 years ago

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

Issue Details
### Description I have an application created from .NET MAUI Blazor App template. When creating directory inside LocalApplicationData path, it returns success but there is no actually directory created. The first time code from Steps to Reproduce runs it will create the directory and any consecutive time Directory.Exists will return true, yet when application tries to open that newly created directory or when you browse to that path in File Explorer, it's not there. This affects Windows and Android. I have not tested with iOS. ### Steps to Reproduce ``` string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MyApp1"); if (!Directory.Exists(path)) { DirectoryInfo dir = Directory.CreateDirectory(path); } ``` ### Version with bug Preview 14 (current) ### Last version that worked well Unknown/Other ### Affected platforms Android, Windows ### Affected platform versions Windows SDK 10.0.19041, Android 11.0 ### Did you find any workaround? Replacing LocalApplicationData with CommonApplicationData works on Windows, but fails on Android with error: **System.IO.IOException:** 'Read-only file system : '/usr/share/MyApp1'' ### Relevant log output _No response_
Author: R0BC0D3R
Assignees: directhex
Labels: `area-System.IO`
Milestone: -
steveisok commented 2 years ago

@directhex if / when there is a fix, we should backport to 6 and 7.

steveisok commented 2 years ago

@mkhamoyan I ran this block in our functional test and I was able to read back the file I wrote.

string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "MyApp1");
string file = Path.Combine(path, "test.txt");

Console.WriteLine("SPECIAL FOLDER PATH: " + path);

if (!Directory.Exists(path))
{
    DirectoryInfo dir = Directory.CreateDirectory(path);

     if (dir.Exists)
     {
         Console.WriteLine("DIRECTORY EXISTS");
     }
     else
     {
         Console.WriteLine("DIRECTORY DOES NOT EXIST");
     }

    File.WriteAllText(file, "THIS IS A TEST");
    var bits = File.ReadAllText(file);
    Console.WriteLine("FILE CONTENTS: " + bits);
}

I wonder if this is device specific? I've got a pixel that I'm testing on. Can you sanity check me?

degenet commented 2 years ago

In my case it only happens on Windows. When evaluating the path, it contains the user’s AppData folder, instead of the actual physical path inside the package directory. I worked around it by constructing the correct file path using the id of the package.

mkhamoyan commented 2 years ago

@steveisok works for me too. Tried from functional test, also from .NET MAUI Blazor App template. Checked with android device and emulator.

steveisok commented 2 years ago

@R0BC0D3R can you please try again with the latest MAUI bits targeting Android? Based on the comments, this might be exclusive to Windows and I would like to make sure.

steveisok commented 2 years ago

@danmoseley Is there someone that can chime in on the windows side of this issue? I'm pretty confident there is not a problem with android from what I've tested.

AFranklin520 commented 2 years ago

@danmoseley Is there someone that can chime in on the windows side of this issue? I'm pretty confident there is not a problem with android from what I've tested. Tested working with Android Emulator (WSL2) on Windows, which was throwing errors with System.IO.... Thank you! Output:

[DOTNET] SPECIAL FOLDER PATH: /data/user/0/com.companyname.taskmaster_dev/files/TaskMaster_DEV/DailyLogs [DOTNET] DIRECTORY EXISTS [DOTNET] FILE CONTENTS: THIS IS A TEST [DOTNET] SPECIAL FOLDER PATH: /data/user/0/com.companyname.taskmaster_dev/files/TaskMaster_DEV/DailyLogs [DOTNET] SPECIAL FOLDER PATH: /data/user/0/com.companyname.taskmaster_dev/files/TaskMaster_DEV/DailyLogs [DOTNET] SPECIAL FOLDER PATH: /data/user/0/com.companyname.taskmaster_dev/files/TaskMaster_DEV/DailyLogs

Ewerton commented 1 year ago

Tested on Windows, seems like it's a Windows only problem. I get the following:

SPECIAL FOLDER PATH: C:\Users\ewer\AppData\Local\MyApp1
DIRECTORY EXISTS
FILE CONTENTS: THIS IS A TEST

But, if I try open that path C:\Users\ewer\AppData\Local\MyApp1 in Windows Explorer it doesn't exists there, the MyApp1 folder isn't there and, Thats the problem!

I already mentioned it in a previous message here.

@R0BC0D3R Maybe my findings today could help you and others. In my project I was trying to create an custom folder and, inside it, create and sqlite db file (MyDatabase.db): My project is an .Net MAUI Native App, so the path where I tried to create my custom folder is: Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) which evaluates to C:\Users\ewer\AppData\Local\ After I call Directory.CreateDirectory(path) I opened Windows Explorer at that location and my new folder wasn't there. So I tried to use the Windows Search to search for MyDatabase.db and... Bingo! The file was in the followin path C:\Users\ewer\AppData\Local\Packages\A7BC0349-3D8D-4A12-9E79-B65BC495C95E_9zz4h110yvjzm\LocalCache\Local So, for some reason which I don't know, Visual Studio generates that random folder name and put things there.

So again, and just for check everything, I searched for test.txt in Windows Explorer and the file was found at: C:\Users\ewer\AppData\Local\Packages\A7BC0349-3D8D-4A12-9E79-B65BC495C95E_9zz4h110yvjzm\LocalCache\Local\MyApp1 and not in C:\Users\ewer\AppData\Local\MyApp1

I understand this happens because Visual Studio install my App in Windows when I run it, but this behavior makes things very confusing.

steveisok commented 1 year ago

@jeffhandley since this appears to be windows specific, can you please assign to right person?

jeffhandley commented 1 year ago

Tagging @dotnet/area-system-io for renewed visibility.

danmoseley commented 1 year ago

do I understand correctly that you're running this code in some kind of packaged Windows App (a MAUI app I guess)? and the repro above works normally in eg., a plain console app (it does for me)?

If so I guess what is happening is Windows is redirecting writes (and no doubt also reads) to the regular local app data folder into an app specific location as part of isolating apps from other apps and the system.

Why does it return the "regular" path when you ask for it? I guess they don't need to, and perhaps also they think it might break existing libraries. There may or may not be some other Windows API to get the redirected path but I'm guessing they see it as an implementation detail only interesting to app devs. And as an app dev, once you know where it is, you know.

If the above is correct this seems like intended behavior.

Ewerton commented 1 year ago

do I understand correctly that you're running this code in some kind of packaged Windows App (a MAUI app I guess)? and the repro above works normally in eg., a plain console app (it does for me)?

Yes, thats correct.

If so I guess what is happening is Windows is redirecting writes (and no doubt also reads) to the regular local app data folder into an app specific location as part of isolating apps from other apps and the system.

I agree, I'm guessing that too.

Why does it return the "regular" path when you ask for it? I guess they don't need to, and perhaps also they think it might break existing libraries. There may or may not be some other Windows API to get the redirected path but I'm guessing they see it as an implementation detail only interesting to app devs. And as an app dev, once you know where it is, you know.

Makes sense, and if it's true, maybe the documentation should state this clearly or instruct developers what lib to use when dealing with file reading/writting in Windows Packaged Applications like Maui. It could improve the developer's experience.

danmoseley commented 1 year ago

We'd welcome a PR if you want to clarify docs (look for pencil icon button on the doc page)

RuddyOne commented 6 months ago

I believe I am also running into this issue. Very odd, what was the correct way to get the package folder?