locked
Where does application data go?

    Question

  • Where exactly are the install location and application data store of a Windows store app? What is the intuitive way to let end-users to put their data files into the application data store of my app? I'm developing a satellite-radar image viewer. My app would be useless unless users put their data files into the application data store.

    Monday, October 8, 2012 3:50 PM

Answers

  • You need to open the picked StorageFile with StorageFile.OpenAsync and use the stream that is returned.

    You cannot use fopen here for two reasons:

    1) Your application doesn't have access to the location the file came from. Your app has direct access only to its app package and app data folders. It cannot directly read or write anywhere else in the file system. When the user picks a file with the FileOpenPicker (or when the app acquires a StorageFile for declared libraries) the file is actually read by an external broker process running with the user's full permissions. This process has access to read the file and then provides a stream with the contents to your app.

    2) There may not be a path to the file at all. The user may pick a file provided from another app which implements the file picker extension contract. This lets the other app provide the data without it necessarily being present on the system. For example, the SkyDrive app can provide "files" from the user's SkyDrive, a Facebook app could provide photos from the user's Facebook stream, etc.

    --Rob

    • Proposed as answer by Leomia800 Tuesday, October 9, 2012 1:56 AM
    • Unproposed as answer by Leomia800 Tuesday, October 9, 2012 1:57 AM
    • Marked as answer by Leonard Tuesday, October 9, 2012 4:03 AM
    Monday, October 8, 2012 5:49 PM
    Owner
  • In the case of files, you could use standard C file functions and C++ iostream functions based on the StorageFile property Path. The thing is that only works if it is actually a file. The WinRT stream APIs can deal with local files, web files, cloud storage, etc.

    If you are trying to use some existing C++ code to parse your data files, what you might want to do is have your Windows Store app look for it's data in Windows::Storage::ApplicationData::Current->LocalFolder path. You can then add an Import option that uses the WinRT APIs to let users pull in data from wherever they have it stored and then you copy that data into your apps LocalFolder isolated path. The WinRT code to do a fetch and copy of the data file should be pretty trivial, and then you can continue to leverage your existing file parsing code assuming it's reasonably modern and portable C or C++ code once you know it's really a 'file' you have access to.

    The complexity here arises mostly from the fact that Windows Store apps are subject to isolated storage to limit the pontential damage malware can do.

    • Marked as answer by Leonard Friday, October 12, 2012 10:49 PM
    Thursday, October 11, 2012 8:39 PM

All replies

  • The install location is for data included in your appx package itself. This cannot be written to. You can find it at runtime with Package::Current->InstalledLocation .

    The application data locations can be found from the Windows::Storage::ApplicationData classes, with different properties depending on if you want the data to stay local, to roam, to be temporary, etc. See Managing app data for an overview.

    Application data is for data from the application itself, not for customer documents. It isn't a location users are generally aware of, but is for use by the app. If you want to store user-oriented documents then they should be stored in user-oriented folders such as the Libraries or somewhere chosen by the user via the file pickers.

    Image files would typically go in the Pictures Library rather than in application data, although if they are app-specific images that the user isn't expected to manage from outside of the app then the app could place them in app data.

    --Rob

    Monday, October 8, 2012 4:57 PM
    Owner
  • Thanks Rob.

    In my app, I use the FileOpenPicker to let user choose a satellite image data file, and then call fopen to open that file for decoding, but fopen always returns NULL unless the user file is put under the project debug folder (Debug\myapp\AppX). Here is the code

    StorageFile^ file;
    char *strFilename;
    const wchar_t *wstrFilename = file->Path->Data();
    // in-house function to convert unicode string to ascii string, I can verify it works.
    ConvertStringW2A(wstrFilename, &strFilename);
    if ( (fp=fopen(strFilename, "rb"))==NULL ) {
    
    I also try to  I declared Document library capability to my app and put data files there (C:\users\lianq_000\Documents\userfilename), but fopen still returns NULL. So my question is will my method (FileOpenPicker followed by fopen) be viable if I declared Document library capability to my app? I thought it works but actually it doesn't.
    Monday, October 8, 2012 5:27 PM
  • You need to open the picked StorageFile with StorageFile.OpenAsync and use the stream that is returned.

    You cannot use fopen here for two reasons:

    1) Your application doesn't have access to the location the file came from. Your app has direct access only to its app package and app data folders. It cannot directly read or write anywhere else in the file system. When the user picks a file with the FileOpenPicker (or when the app acquires a StorageFile for declared libraries) the file is actually read by an external broker process running with the user's full permissions. This process has access to read the file and then provides a stream with the contents to your app.

    2) There may not be a path to the file at all. The user may pick a file provided from another app which implements the file picker extension contract. This lets the other app provide the data without it necessarily being present on the system. For example, the SkyDrive app can provide "files" from the user's SkyDrive, a Facebook app could provide photos from the user's Facebook stream, etc.

    --Rob

    • Proposed as answer by Leomia800 Tuesday, October 9, 2012 1:56 AM
    • Unproposed as answer by Leomia800 Tuesday, October 9, 2012 1:57 AM
    • Marked as answer by Leonard Tuesday, October 9, 2012 4:03 AM
    Monday, October 8, 2012 5:49 PM
    Owner
  • Thanks Rob.

    I think I've got the answer. But I still don't understand why MS makes devs' life hard by reinventing the wheel and force devs to learn lots of new functions (functions to access StorageFile stream) instead of functions (C file functions and C++ iostream class) we've familiar with.

    Tuesday, October 9, 2012 4:10 AM
  • In the case of files, you could use standard C file functions and C++ iostream functions based on the StorageFile property Path. The thing is that only works if it is actually a file. The WinRT stream APIs can deal with local files, web files, cloud storage, etc.

    If you are trying to use some existing C++ code to parse your data files, what you might want to do is have your Windows Store app look for it's data in Windows::Storage::ApplicationData::Current->LocalFolder path. You can then add an Import option that uses the WinRT APIs to let users pull in data from wherever they have it stored and then you copy that data into your apps LocalFolder isolated path. The WinRT code to do a fetch and copy of the data file should be pretty trivial, and then you can continue to leverage your existing file parsing code assuming it's reasonably modern and portable C or C++ code once you know it's really a 'file' you have access to.

    The complexity here arises mostly from the fact that Windows Store apps are subject to isolated storage to limit the pontential damage malware can do.

    • Marked as answer by Leonard Friday, October 12, 2012 10:49 PM
    Thursday, October 11, 2012 8:39 PM
  • Thanks a lot Chuck.

    Copying user selected file into the app data store is a interesting method though it may have performance issue if the file is very large, say file size >= 10MB.

    Friday, October 12, 2012 10:53 PM