locked
Access Denied exception when trying to work with files

Answers

  • Found the problem myself. Seems that Metro style apps cannot access files without letting the user interactively pick the file. For those of you who want to have a sample how to run the picker and read the selected file I include the following few lines of code:
    	auto picker = ref new FileOpenPicker();
    	picker->FileTypeFilter->Append(".txt");
    	auto pickerOp = picker->PickSingleFileAsync();
    	pickerOp->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(
    	[](IAsyncOperation<StorageFile^> ^operation)
    	{
    		auto file = operation->GetResults();
    		auto fileOpenOp = file->OpenForReadAsync();
    		fileOpenOp->Completed = ref new AsyncOperationCompletedHandler<IInputStream^>(
    			[file](IAsyncOperation<IInputStream^> ^operation2)
    		{
    			auto stream = operation2->GetResults();
    			auto reader = ref new DataReader(stream);
    			auto loadOp = reader->LoadAsync(file->Size);
    			loadOp->Completed = ref new AsyncOperationCompletedHandler<unsigned int>(
    				[reader](IAsyncOperation<unsigned int> ^bytesRead)
    			{
    				auto result = reader->ReadString(bytesRead->GetResults());
    				// Do something with result
    			});
    			loadOp->Start();
    		});
    		fileOpenOp->Start();
    	});
    	pickerOp->Start();
    

    Rainer
    Saturday, September 17, 2011 5:15 AM
  • Found the problem myself. Seems that Metro style apps cannot access files without letting the user interactively pick the file.
    Presumably this goes for writing files also?
     
    So this means that I cannot have an application that automatically saves itself to disk every time the user makes a change?
     
    Or am I supposed to be saving to the cloud?
     

    David Wilkinson | Visual C++ MVP

    Hello, David.

    Your application does not automatically get access to _user data_ (e.g. a Documents Library) as you have correctly surmised. However, this is not where you should be storing your application's internal state anyway. Instead, your Metro application should be leveraging application data (not user data) for this purpose.

    See: Windows.Storage.ApplicationData (http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata(v=VS.85).aspx)

    Regards, Chris (AppX team)

    Sunday, September 18, 2011 10:22 PM

All replies

  • Found the problem myself. Seems that Metro style apps cannot access files without letting the user interactively pick the file. For those of you who want to have a sample how to run the picker and read the selected file I include the following few lines of code:
    	auto picker = ref new FileOpenPicker();
    	picker->FileTypeFilter->Append(".txt");
    	auto pickerOp = picker->PickSingleFileAsync();
    	pickerOp->Completed = ref new AsyncOperationCompletedHandler<StorageFile^>(
    	[](IAsyncOperation<StorageFile^> ^operation)
    	{
    		auto file = operation->GetResults();
    		auto fileOpenOp = file->OpenForReadAsync();
    		fileOpenOp->Completed = ref new AsyncOperationCompletedHandler<IInputStream^>(
    			[file](IAsyncOperation<IInputStream^> ^operation2)
    		{
    			auto stream = operation2->GetResults();
    			auto reader = ref new DataReader(stream);
    			auto loadOp = reader->LoadAsync(file->Size);
    			loadOp->Completed = ref new AsyncOperationCompletedHandler<unsigned int>(
    				[reader](IAsyncOperation<unsigned int> ^bytesRead)
    			{
    				auto result = reader->ReadString(bytesRead->GetResults());
    				// Do something with result
    			});
    			loadOp->Start();
    		});
    		fileOpenOp->Start();
    	});
    	pickerOp->Start();
    

    Rainer
    Saturday, September 17, 2011 5:15 AM
  • Found the problem myself. Seems that Metro style apps cannot access files without letting the user interactively pick the file.
    Presumably this goes for writing files also?
     
    So this means that I cannot have an application that automatically saves itself to disk every time the user makes a change?
     
    Or am I supposed to be saving to the cloud?
     

    David Wilkinson | Visual C++ MVP
    Saturday, September 17, 2011 10:46 AM
  • Perhaps you need to specify in the manifest the type of file you need.  But perhaps Microsoft has not finished a GUI to let you select all the details needed to do this yet.   So you might have to edit the manifest yourself.   The syntax is unclear to me, and I have not tried this.  Just consider it a suggestion.

     

    Some clues I found:

    Document Library Access documentsLibrary Allows your app to access the user's Document Library, and to add, change, or delete files. Your app can access only file types that it has declared in the manifest. Your app cannot access Document Libraries on HomeGroup computers.

     

    Package manifest schema reference

    http://msdn.microsoft.com/en-us/library/windows/apps/br211473(v=vs.85).aspx

    FileType (in type: CT_FTASupportedFileTypes)

    A supported file type specified as its file type extension.

    FileType (type: ST_FileType)

    A file type specified as its file type extension.

    FileTypeAssociation

    Declares an app extensibility point of type windows.fileTypeAssociation. A file type association indicates that the app is registered to handle files of the specified types.

    Saturday, September 17, 2011 2:03 PM
  • Found the problem myself. Seems that Metro style apps cannot access files without letting the user interactively pick the file.
    Presumably this goes for writing files also?
     
    So this means that I cannot have an application that automatically saves itself to disk every time the user makes a change?
     
    Or am I supposed to be saving to the cloud?
     

    David Wilkinson | Visual C++ MVP

    Hello, David.

    Your application does not automatically get access to _user data_ (e.g. a Documents Library) as you have correctly surmised. However, this is not where you should be storing your application's internal state anyway. Instead, your Metro application should be leveraging application data (not user data) for this purpose.

    See: Windows.Storage.ApplicationData (http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata(v=VS.85).aspx)

    Regards, Chris (AppX team)

    Sunday, September 18, 2011 10:22 PM
  • Your application does not automatically get access to _user data_ (e.g. a Documents Library) as you have correctly surmised. However, this is not where you should be storing your application's internal state anyway. Instead, your Metro application should be leveraging application data (not user data) for this purpose.
    Thanks, Chris.
     
    A lot to learn. And unlearn.
     

    David Wilkinson | Visual C++ MVP
    Monday, September 19, 2011 1:37 AM
  • Ok, suppose I want to write a FTP utility that can copy any file on any drive on the system up to a remote site.  Suppose I have admin rights.

    Is this possible in a Metro style application?

    Monday, September 19, 2011 1:41 AM
  • Perhaps we'll need something like 'trusted mode' in Silverlight to do this.

    Monday, September 19, 2011 5:30 AM
  • But the document said: http://msdn.microsoft.com/en-us/library/windows/apps/hh464936%28v=vs.85%29.aspx#documents_library

    [quote]

    The documentsLibrary capability provides programmatic access to the user's Documents library, filtered to the file type associations declared in the package manifest. For example, if a PDF reader app declared a .pdf file type association, it can open .pdf files in the Documents library, but not other types of files.

    Alternatively, apps can use the file picker to access specific files in the Documents library if they do not require programmatic access.

    [/quote]

    So, file picker is a 'alternative' solution, then what is THE solution that 'documentsLibrary' capability enables ??

    plus, how I use CreateFile2 function to access these files ? http://msdn.microsoft.com/en-us/library/windows/desktop/hh449422%28v=vs.85%29.aspx

    I have documentsLibrary enabled and FileTypeAssociation extension set, can I use CreateFile2 without file pickers ?? or, how exactly can I use CreateFile2 API at all ???

          <Extensions>
            <Extension Category="windows.fileTypeAssociation">
              <FileTypeAssociation Name="txtfiles">
                <InfoTip>Text Files</InfoTip>
                <EditFlags OpenIsSafe="true" AlwaysUnsafe="false" />
                <SupportedFileTypes>
                  <FileType>.txt</FileType>
                </SupportedFileTypes>
              </FileTypeAssociation>
            </Extension>
          </Extensions>


    • Edited by TheCat666 Monday, September 19, 2011 6:40 PM
    Monday, September 19, 2011 6:15 PM
  • The capability defined in the manifest gives you programmatic access, but only through the WinRT APIs - not the legacy Win32 APIs. You need to use something like KnownFolders.documentsLibrary.createFileAsync().
    Wednesday, September 21, 2011 4:09 PM
  • well, but CreateFile2 is not a 'legacy' Win32 API, it is listed in the 'Win32 and COM for Metro style apps' list:

    http://msdn.microsoft.com/en-us/library/windows/apps/br205753%28v=VS.85%29.aspx

    And its actually a new API in this WDP release, how could I use that ?

    Wednesday, September 21, 2011 8:43 PM
  • You're right, CreateFile2 can be used from a metro-style app, but not for capability-backed locations. CreateFile2 is for accessing your app's local data storage locations. Libraries can only be accessed via WinRT.

    Thursday, September 22, 2011 6:25 PM
  • Not directly related to this subject, but I think it would be nice if we could get the user the control of "where a particular app should store its data". For example, if I build a metro version of Adobe Premiere or this kind of software, I don't want it to use my 60 GB SSD on which Windows is installed, but my big 1TB secondary drive. And that's not possible for metro apps that need unbrokered file access.
    Friday, June 15, 2012 9:16 AM