-
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
Environment.GetFolderPath() doesn't support all KNOWNFOLDERID's #554
Comments
Looks like this is because on .NET Framework, This is essentially an API request for new members of Environment.SpecialFolders. Someone interested in this should make a list of proposed additions. Note that they ideally all have some meaning on Mac and Linux. We should not add "CameraRoll" unless it's actually important. Downloads seems pretty basic though. |
If it's documented, I recommend including it since determining importance is a fool's errand. For example, CameraRoll might not be important to many, but since it is included in One Drive Known Folder Move it is of interest to people trying to use that.
|
Maybe if Windows was the only relevant OS, but it is not: as the list gets longer there are more entries without clear mappings on various Linux distros, macOS, Android, iOS, etc. We can take guesses or return empty string but that potentially makes life harder for folks trying to target those OS, who must now figure out which members of the enumeration are going to be useful. Eg., what should CameraRoll return on Ubuntu? Maybe there is no mapping, or several possible mappings. If I'm writing a photo editor app, should I offer it in my "open file" picker? We are already returning empty string in quite a few cases for Unix runtime/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs Line 143 in 2d4acbd
And for example on about 30 cases on iOS |
Sure, Windows is not the only targeted OS. I'm a great advocate of non-Windows .NET Core / PowerShell. But OTOH, not all code / scripts is / are written to be xplat! I hate that I have to write weird code (mainly on Windows) to determine where the Downloads folder resides... |
It would be good to improve the doc so it has a big table showing what works on what platform. It looks like it's not been updated for cross plat. https://docs.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netcore-3.1 |
Yes! And that big table would have Windows-only entries ;-) Or "not MacOS" entries. Whatever. |
Merge from dotnet/runtime
Per #57133, we should consider the Saved Games folder as a candidate too. |
In the interest of pushing this forward I've put together a spreadsheet of all the KnownFolderIds that are missing, as well as whether they're usable on *nix or mac. What I don't have is a good way to collaborate on these, as I'm not a mac or *nix user so I'm not sure what the sane defaults would be. (read-only view of the spreadsheet) One thing that struck me as a bit odd while I was working on this is that MyComputer is a valid SpecialFolder. This is the only KnownFolderId which is marked as a Virtual folder, and I don't think it will EVER return a valid path on Windows. |
This seems to be the newest discussion on this topic.
1 Judging from existing code and https://wiki.archlinux.org/title/XDG_user_directories I noticed some things while doing so:
I did not tackle the "Saved Games" folder as only Windows has it, and the discussion went into the direction of focusing folders that have viable cross-platform paths first. If you are interested, I can write an API Proposal to add these two folders. Wanted to hear some feedback on this existing issue first :-) |
On my Windows 7 VM, only Documents, Music, Pictures, and Videos have the My prefix. (Matches https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid) |
I don't have a Mac but I don't believe so. If Macs have a "movies" folder then we should implement it to return that for SpecialFolders.MyVideos. That's just a bug fix -- #68323 BTW, I found #25577 and #63214 -- lots of discussion here, as no maintainers like me have sat down and organized. I wouldn't bother to add to the VB enum as you point out. It would be great to open an API proposal for those two, and any others you believe (based on all these discussions) seem to make general sense. Perhaps we can end up closing all these issues.. |
BTW @RayKoopa thanks for reviving this. And @AtomicBlom for the spreadsheet, which I pasted here in case it gets lost. https://gist.github.com/danmoseley/edb3708c1bacc2998890e44e7ea4e4d4 |
Thank you for checking on the folder names and other discussions. I'm still sorting my notes a bit from the many comments written throughout the years, but have updated mine above (which I slightly use as my blueprint for an API proposal):
For simplicity, at the moment I'd prefer to only focus on the "missing user folders" common to Linux / macOS / Windows, e.g. "Downloads" and "Public" (despite the latter not being a user-specific folder on Windows, but I think that is neglectible since everyone has access to it by default). |
Thanks for saving the spreadsheet. Shouldn't it include a column indicating what is currently supported by .NET (might even depen on version?)? |
Phew, I've now dug through related issues, PRs and API proposals. They currently block me moving forward with my blueprint above as they make valid points in that extending the enum may not be a good idea. However, I cannot rate how important the points made are today:
So either
What do? 🤔 |
I would honestly like to see a short-term fix in place for at least the user folders. I stumbled across and became invested in this task after I became aware of how few developers were making use of the "Saved Games" folder in windows, and many games scatter their saved games everywhere across local app data, roaming app data, my documents, etc. All this means that for games that don't cloud save, it's very difficult to back them all up I wanted to make sure that my games used what I perceive to be the best location for them, and I want to promote that there is a location for saved games, However the Enum value doesn't work for non-windows platforms, so it's back to square one. |
Me too. The only "real" reason against short-term extending the enum because "code assuming it maps to Windows' CSIDLs would break" is valid but exotic. What would be a use case for that? Any code doing this...
These two reasons actually made me exclude the "Saved Games" in an API Proposal I'd write so far, and only focus on the more commonly requested "Downloads" and "Public" first - unless maintainers are okay with "Saved Games" returning "yet another" |
Just wanted to leave a quick note, that the public directory functions a little differently between Windows and Linux/MacOS. Also, this may just be a thing that's unclear due to it being short, but for the Linux assignments, it shouldn't be an "or", rather a "fallback" should the former variable not exist. If you're using |
Before this stales away again, should I push ahead and make an API proposal as I outlined above? To recap: 🟢 Extend
Reasoning:
This has already been started just recently here: #68610. I will wait on the acceptance / merge of that PR first before continuing with the new folder proposal to prevent clashes / confusion. |
Linking #68610 here as well... |
Thanks for letting me know. I crossed out the breaking changes in my recap that are already started there and wait for the outcome of the PR / discussions first. |
This looks reasonable, but I want to ask for clarification regarding the public subfolders on Linux: Are the subfolder names fixed to the values mentioned above or are the translated values of the personal download/music/document/... folders used? Sadly those folders are locale-dependent (seemingly every OS needs to make that mistake at least once) and in my opinion using a fixed language for public subdirs would be wrong: If So |
Thanks for opening the discussion on that. I included the paths returned on Unix based on the currently used fallback names, and only added them for "convenience".
So if you ask me, either use hardcoded English names, or not return any paths for these folders on Unix. |
That's exactly what
I think this is already spelled out in the spec. There is no reason why subdirs should behave differently.
That's a good point!
That also sounds fine to me. |
|
Agree here that the public subfolders should rather not return anything at all on Linux. For consistency's sake, should MacOS not return anything for those subfolder as well then? Since they also technically do not exist there, and from what I understand from the docs they'd rather have only Users use those. Not to mention that those folders are translated in MacOS. Not via naming, but by having a |
Yeah, whenever I mentioned "Unix", I meant both macOS and Linux. And I agree, adding exceptionally much magic for determining these folder's names or getting them localized is not meaningful here. After this discussion and my own personal reconsideration, I updated my recap to return empty paths on those systems. EDIT: Now my last bullet "Other "special" folders (like Windows' "Saved Games" or "Public Desktop") are not included due to them having no meaningful cross-platform counterpart." looks a little dumb. I could just aswell add those folders for Windows-only now. |
Considering that Win7 is now EOL, with there only coming security updates, and everything before already being not supported, is this really worth adding? |
Probably not - yet Windows 7 is still in extended support, and apparently going to be supported in .NET 7. I don't know about the support periods of Windows 8 right now but would assume they're longer. According to just this it would be better to add it. However, the only use-case I could think of is someone designing their own OpenFileDialog or wanting to display user favorites - but they'd need special logic for Windows 10 anyway as it uses a different storage for managing "Quick Access". The Links folder still exists in Windows 10 but has no real use anymore IIRC (I think I actually deleted mine completely...). EDIT: I rated this use case as quite exotic and moved that folder to ❌. |
|
You're actually right, it should be in there given "Desktop" by itself is a common user folder on all systems, which I forgot. Adjusted my comment. |
#68610 does not move the iOS myVideos to Movies, only does for MacOS. |
I don't have an iPhone or iOS emulator here too, so I wonder if a participant of this discussion could check for the existence of either "Movies" or "Videos" on a relatively clean device / installation.
To me that line of code looks like |
Last part was a typo, meant Look at: It should probably be still changed to I also used |
Just realized, that this also means that the iOS part in your Documents table is wrong as well. The Documents entry on iOS, from what I can see, doesn't need any updating at all. |
Right, I thought But I'm getting a bit more confused now, please let me know if I understood correctly:
Understood and adjusted. Didn't expect the iOS code to be like "that" :-) |
You need to differentiate here between iOS and MacOS.
Nope, the way it is right now is intended. The UNIX changes do not affect iOS; iOS already invokes
Sorry, I don't get quite what you're meaning with this. If you're confused about the sandboxing and haven't looked at the doc I linked above:
In other words, no access to |
If I understood correctly, this means iOS apps have no way of accessing the |
It seems possible to do via
|
Okay, understood. Logically I'll just stay inside the sandboxed folders like .NET already does then, adding the return Path.Combine(GetFolderPathCore(SpecialFolder.Personal, SpecialFolderOption.None), "Downloads"); I hope my iOS columns in my recap above are now correct at least. |
An Android column is missing as well btw. You can see current mappings here: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Environment.Android.cs#L35 |
I did not find the Android specific part which is why I thought it's handled by the "Linux (without XDG)" column. The linked file does not exist on the master branch, I suppose it is handled by Unix now, but I am not sure. |
Sorry wrong link. Edited it. |
Yeah, from my first uneducated look on that it seems that Personal/MyDocuments is "incorrect" on Android too. Should go in sync with your existing changes on macOS / Linux. Also, I'm not sure why I'll definitely wait until you finished your changes to not clash with them, and then update my post above to include Android. |
The full folder path contains the user-desired name – searching for some translation that the user may or may not have chosen is not the correct approach – that's why I suggested Now, as mentioned, leaking that name might not be a good idea, so I'd be in favor of omitting the dir on Linux completely. |
…416.2 (dotnet#554) [main] Update dependencies from dotnet/arcade
(Redirecting from (PowerShell/PowerShell#11240))
It should be possible to retrieve the location of all "special folders" instead of hardcoding them (or assuming they are just subfolders of the user's profile folder).
As of today,
Environment.GetFolderPath()
(which reportedly relies on SHGetKnownFolderPath()) doesn't support all KNOWNFOLDERID's. Here's a few of the ones that are not supported:This piece of code
outputs only this subset of folder paths:
The text was updated successfully, but these errors were encountered: