locked
0x80070005 - JavaScript runtime error: Access is denied when trying to overwrite previously-copied local file

    Question

  • When the app I am working on starts for the first time, it copies several images from its application package to the user's local storage. These same files can be updated during web requests, at which point they need to be overwritten with the new data. My problem is, when the app first copies the files and the user tries to overwrite them in the same session, I get the Access Denied error mentioned in the title of this post. Interestingly enough, if I close and re-open the app, I do NOT get the error. My method for storing the files initially is like so:

    //This function compares two lists of images and copies any missing on the local list from the package list to the local image folder.
    function copyMissingImages(packageImages, localImages, destination) {
        //The copies will be defered until all images have been processed.
        //Then they can all be run at once.
        var copyPromises = [];
        var localImageIndex = 0;
        packageImages.forEach(function (packageImage) {
            //If the current local image comes before the current package image, 
            //then we iterate through the list until we come to a local image that matches or comes after the package image.
            while (localImageIndex < localImages.length &&
                    localImages[localImageIndex].name.localeCompare(packageImage.name) < 0) {
                localImageIndex++;
            }
            //If we have reached the end of the list of local images, we can be sure the package image is not already copied.
            if (localImageIndex >= localImages.length) {
                copyPromises.push(packageImage.copyAsync(destination));
            } else if (localImages[localImageIndex].name !== packageImage.name) {
                //If the current local image is not the same as the current package image, 
                //it means the package image has not been copied.
                copyPromises.push(packageImage.copyAsync(destination));
            } else {
                //The package image has already been copied.
                localImageIndex++;
            }
        });
        return WinJS.Promise.join(copyPromises);
    };

    It is a little complicated, but basically it just packs all the copyAsync methods into an array and then joins the promises. The method for storing the images that are downloaded from the web service, which is throwing the error, goes like this:

    function storeImage(imageFolderPath, filename, imageData) {
        localPath.getFolderAsync(imageFolderPath).then(function (folder) {
            var options = Windows.Storage.CreationCollisionOption.replaceExisting;
    
            return folder.createFileAsync(filename, options);
        }).then(function (file) {
            var buffer = Windows.Security.Cryptography.CryptographicBuffer.decodeFromBase64String(imageData);
            var bytes = [];
            bytes = Windows.Security.Cryptography.CryptographicBuffer.copyToByteArray(buffer);
    
            return Windows.Storage.FileIO.writeBytesAsync(file, bytes)
        }).then(function () {
            return WinJS.Promise.as(console.log("Saved image: " + imageFolderPath + "\\" + filename));
        }, function error() {
            throw new Error("Unable to save Image: " + imageFolderPath + "\\" + filename);
        });
    }

    It is failing at the call to ceateFileAsync. The images themselves show up in data-bound elements in the app, in a listview. If I change the listview's images to have no src, then the error does not happen. If I let the listview's images take on the src of the copied images, and then set the src property to "#" while the images are being created, I get the error. Like I mentioned before, though, I have no trouble if the files were not previously copied, regardless of which elements have the images as their src.
    Thursday, December 20, 2012 9:30 PM

All replies

  • make sure that once you copied the files then you should close that file to perform other operations again, generally access denied error occurred in the case of file operations, if that file is in being used by another operations
    Friday, December 21, 2012 5:51 AM
  • Is there a method for closing files that are copied using CopyAsync? I couldn't find anything like that in the StorageFile object, and I don't know how I would close a file that has been set to the src of an image element.
    Friday, December 21, 2012 2:13 PM
  • A little more information that I have discovered: The ListView with the images that are failing is part of a semantic zoom, and is not initially shown when the user navigates to the screen that calls the image downloading function. If I do not use the semantic zoom at all, then the error occurs. However, if I perform the semantic zoom and display the zoomed-out ListView (again, the ListView that contains the images that I am having trouble with,) the error does NOT occur, which is very strange. I would expect the opposite to be true. I'm pretty baffled at this point, but at least this is a clue.
    Friday, December 21, 2012 3:44 PM