WinJS - How to access whole folder tree without FolderPicker - windows-store-apps

I'm building a Store App using WinJS and I need to create a structure with some info related the user's tree folder (every drive, not only C:), is there any way to get the whole Folder structure from every drive without using the File/FolderPicker?

No, by design Windows Store Apps run inside an app container that limits what they're allowed to do without user consent. The only areas of storage that are openly accessible without further consent are the app's package location (which is read-only, see [Windows.ApplicationModel.Package.Current.installedLocation][1]) and its app data folders (see Windows.Storage.ApplicationData).
If the app declares library access in its manifest (for Pictures, Videos, and Music), these are noted on the app's page in the Store such that the act of installing the app amounts to user consent. There is also a RemovableStorage library that's similar, but for that you have to declare specific file types.
If an app is registered for a file type association in its manifest, and the user launches the app through a file, that grants access.
Beyond this, the way you get access to any other storage location is through the pickers. However, if you have the user pick once, you can save that consent by saving the StorageFolder into the Windows.Storage.AccessCache API, so that you can open the folder again in an future app session without having to reacquire consent.
For all the details of this, refer to the first section of Chapter 11, "The Story of State, Part 2: User Data," of my free ebook, Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition.

Related

How to deploy resource files for a windows store app

I am working on a windows store app, one of the workflows within the app would allow the user to export a report in html format. The html report relies on a css file so I would like to ensure that the install process could deploy the file in a local folder. If not I would need to read out the file from the assets folder (within the install bundle) and manually write it out but that seems pretty kludgy
https://learn.microsoft.com/en-us/uwp/api/Windows.Storage.KnownFolders?view=winrt-22000
mentions that "The Documents library is not intended for general use." so would require use through file picker but I would prefer to be able to export the document without user intervention without additional store approval headaches (apparently adding Documents library capability to manifest requires additional Microsoft store approval).
Questions
When I create files within the store app it seems the location options are limited and I can only write to Localfolder (which is actually hidden and users cannot easily get to it) - There must be a way to create a file within the MyDocuments directory that is easily accessible by users but looks like that is off limits to a windows store app? So what is the best approach to write reports to storage that can be easily accessed by users
How can one deploy files to a specific directory during install time? Assuming there are some installer commands/manifest directives that would allow this capability?
Or maybe there is a entirely different mechanism to allow for this functionality within the store app and I am just looking in all the wrong places...

How can I access app data from a browser addon?

I want to add Google Drive integration to a browser add-on I developed. Basically I want to share user settings between devices, and the settings files are too big to fit inside the 100KB limit for the storage.sync API.
But when I go to my API console and try and activate permissions for the Drive API, I get this:
Browser apps (and Android apps) aren't allowed to access app data. That's not just a warning, you actually can't continue the process until you choose a different platform. Weirdly, I can go ahead if I select "User data" (so user data is less sensitive than app data??)
What I like about app data over user data is that, if I understand correctly, app data goes in a hidden folder uniquely tied to your app, whereas user data goes in the actual user's drive. I don't want my app to have access to the broader drive, I don't want to risk messing their data up and I don't want them to see my app's config files every time they access their drive.
How can I get this "hidden folder" behavior from a browser addon?
Try the solution from this related SO post.
To be able to use your Application Data folder, request access to the following scope:
https://www.googleapis.com/auth/drive.appdata

Directory sandboxed access for Google Drive / Dropbox API / RemoteStorage apps?

Is there a way to get sandboxed, user-selected directory access on any major file service without first getting read level access to their entire filesystem?
There's a lot of talk about "unhosted" static webapps that allow users to access their data from a 3rd party file service (Google Drive, Dropbox, their own server, etc.). The most notable effort I've found so far is remoteStorage.io, but there doesn't seem to be a way with any major provider to let the user select a directory and then use that as a sandbox without breaking their trust (i.e. getting read access to all their files first).
From the user's perspective, the webapp shouldn't have access to anything else on the remote file storage except the one folder the user grants it access to (for example, I might grant a text editor access to my FunnyJokes folder).
The current work around seems to be having the webapp force a specific folder name ahead of time ("this app wants access to /appname_notes"), but that rules out letting the user point it to where they may already have their notes.
Does anyone know of a nice way to do this with Google Drive, Dropbox, or the like?
The user experience that makes the most sense to me is something like...
User opens an unhosted webapp (for example, a basic text editor TextyApp). They click a button to connect with their data.
3rd party auth page appears (for example, Google Drive) and it says "The app TextyApp has requested read/write access to your files. Please select a directory to use."
Confirmation screen: "Grant read/write access to folder FunnyJokes for TextyApp?"
The page redirects back to the webapp with sandboxed accessed to the user-specified folder and the files within it.
This seems like how remote file storage should work, but I haven't found a way to do it yet. Any thoughts/suggestions would be great!
Cheers,
Adam
Edit: To clarify, I'm not talking about storing hidden "application data", but instead letting the user specify a particular directory to sandbox for use with a webapp that they may not want to give broader access to.
The Dropbox Apps API provides the ability to restrict any app using your API key to a single directory of your Dropbox account. So users could create an API key with access to a specific directory and then plug that into your app. However, that's not a user-friendly workflow.
I think the Dropbox Drop-Ins Chooser/Saver API might be close to what you want. The user is presented with a Dropbox file selection popup, and your app only gets access to the specific file(s) that the user selects.
With remoteStorage, sandboxed directory access is currently the default way for apps to request (and users to grant) access to the storage. However, users cannot manually select or enter custom directories during the connect phase.

Google Drive Permissions

I work for an un-launched startup that handles a large amount of user media. We are looking to integrate Google Drive as a way for a user to store that media.
Is it possible to have read/write access to a user's Google Drive, after obtaining their permission via OAUTH2? More specifically the ability to create folders on their drive and access them for read/write scenarios.
We would also need to be able to generate direct links to their photos, videos, etc.
We've successfully integrated with Dropbox in this manner and would like to offer Google Drive as an alternative. Are these scenarios possible with Google Drive?
Yes, this is absolutely possible.
You will want to read about our Auth Scopes and determine what the minimal set of scopes are that you need to operate. As an example, drive.file scope will enable you to create files & folders, read them, as well as read/write any existing files that a user explicitly opens with your application.
The 'explicitly open' part can be handled in 2 ways. You can register an 'Open' action for your app in the Drive UI for certain file types and you can use our 'File Picker' widget in your app to enable the user to select which files to open/grant access. You can read about opening files in our docs

Chrome App: Getting a list of files in a designated folder

I am building a chrome app for Digital Signage where I need the user to select some files from a particular folder (preferably in the app's directory) i.e audio, videos, photos which should be created by the app on install.
The sample code provided by Google requires that the user navigates to a folder like this
chrome.fileSystem.chooseEntry({type: 'openDirectory'}, function(theEntry) {
if (!theEntry) {
output.textContent = 'No Directory selected.';
return;
}
// use local storage to retain access to this file
chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
loadDirEntry(theEntry);
});
However, my app simply needs the name of files in that (say Video) known directory for the user to build a playlist, rather than actually selecting a video file.
Is this supported in chrome.fileSystem API? Any pointers to how I cold get this done?
It sounds like you should be using either the app's sandboxed file systems, or the app's install folder itself.
The sandboxed file systems allow the app to store whatever data it wants, in whatever structure it wants. There are two to choose from: persistent or temporary. Temporary may be cleared at any point in time. To use these check out this article. Some of its code may be out of date with the spec. Note also apps need to request the unlimitedStorage to use these.
The install folder itself can be used in a read only way. To do this you use chrome.runtime.getPackageDirectoryEntry.