Exception when saving using Application.PersistentDataPath on Windows Phone

Hello,

When saving on WP8 (Nokia 520, Unity 4.5.3f3), I get the following exception:

A first chance exception of type ‘System.Exception’ occurred in WinRTLegacy.DLL
Exception: Unsupported uri: c:/data/users/defapps/appdata/{c133a4f8-83a8-4125-a749-a6480c9068c2}/local\autosave.litdsavedgame
at WinRTLegacy.UnityFileStreams.OpenFile(String uri, FileMode mode)
at WinRTLegacy.UnityFileStreams.OpenFileForWriting(String uri)
at System.Xml.XmlTextWriter…ctor(String filename, Encoding encoding)
at System.Xml.XmlDocument.Save(String filename)

The file path is generated as follows:

var path = System.IO.Path.Combine(Application.persistentDataPath, filename);

var doc = new XmlDocument();

doc.Save(path);

I tried changing the "" in the file path to “/” - same result. Anyone have any ideas? This code works fine on Windows / Android / iOS.

What is the value of the “filename” variable?

Hi, this might be a bug in our XML implementation. Could you try changing all ‘/’ path separators to '' ones? If that doesn’t work, could you try replacing Application.persistentDataPath with “ms-appdata:///local/”?

The present implementation of XML classes on Windows Phone/Windows Store Apps only supports URIs, not paths.
This will be improved in 5.0.
For now use isostore:/ on WP and ms-appdata:/// uris.

Thanks for your replies.

Replacing ‘/’ with '' didn’t work. I am trying to use the alternate path prefixes but no success so far. I don’t get the “unsupported uri” exception any more but the game acts like no data has been saved. Just to be 100% clear: Should I be replacing:

var path = System.IO.Path.Combine(Application.persistentDataPath, filename);

with

var path = "ms-appdata:///local/" + filename;

on WP8?

If it’s WP8, not WP8.1, then use isostore:/ uri. Note, that there’s only one slash here, rather than 3.

So… I tried but was not able to get a save game saving using the isostore:/ uri (no errors but the code acted like the save game wasn’t there - quite possibly I was doing something wrong). I ended up adding some ifdef’d code that followed the example outlined here on how to access isolated storage with xml: How to: Save to and Load from Isolated Storage with LINQ to XML | Microsoft Learn. That worked for me!

Can you show an example of your code? I tmight be a bug in our XML implementation.

@Aurimas-Cernius
this is my code, and I get the same behaviour as @Marzipan

private string filePath = "ms-appdata:///local/GameData.dat";

XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
            XmlTextWriter xmlWriter = new XmlTextWriter(filePath, Encoding.UTF8);
            serializer.Serialize(xmlWriter, playerData);
            xmlWriter.Close();

bool fileExists = System.IO.File.Exists(filePath);
  Debug.Log(fileExists); // This is false!!!!

No errors. It seems that the file just doesn’t get saved.

konsnos, are you targeting WP8 or WP8.1? As Aurimas suggested, what happens if you change line 2 in your example to this:

private string filePath = "isostore:///local/GameData.dat"; //isostore instead of ms-appdata

I’m targetting WP8.1. Did the change you said. File path is “isostore:///local/GameData.dat”, and got error.

An exception of type 'System.IO.IsolatedStorage.IsolatedStorageException' occurred in mscorlib.ni.dll but was not handled in user code
Additional information: Operation not permitted on IsolatedStorageFileStream.

well, if it’s 8.1 then it will be ms-appdata. Try this:

var path = @"ms-appdata:///local/";
var exists = System.IO.Directory.Exists(path);
Debug.Log(exists);

Result if false :-S . I didn’t expect that. I don’t have anything to think of right now. What do you make of this Dustin?

This though

var path = Application.persistentDataPath;
            var exists = System.IO.Directory.Exists(path);
            Debug.Log(exists);

results to true.
Path is : “C:/Data/Users/DefApps/AppData/{72217BDD-B7FC-45F4-8749-FD3C292BE37B}/local”

Solved it

XmlSerializer serializer = new XmlSerializer(typeof(NAMEOFCLASSHERE));
Stream writer = new FileStream(Application.persistentDataPath + "/GameData.dat", FileMode.Create);
serializer.Serialize(writer, YOURCLASSHERE);
writer.Close();

This works :slight_smile:

fileExists = System.IO.File.Exists(Application.persistentDataPath + "/GameData.dat");

This also works.

And to load it

XmlSerializer serializer = new XmlSerializer(typeof(NAMEOFCLASSHERE));
TextReader textReader = new StreamReader(Application.persistentDataPath + "/GameData.dat");
YOURCLASSHERE= serializer.Deserialize(textReader) as NAMEOFCLASSHERE;
textReader.Close();

good :slight_smile:

Use UnityEngine.Windows.File for all file operations where possible.

Also when working with paths, sometimes prefixing “file:///” helps

I can’t seem to be able to use that for some reason. Does it need any compiler arguments? Also in the documentation it says “This is an alternative for System.IO.File class.” so they must be alike.

Can you show the code? And attach Editor.log please

What do you mean Tomas? I just have to add the using inside the cs file and I get this error in Unity Editor:

Assets/Scripts/blabla.cs(9,19): error CS0234: The type or namespace name `Windows' does not exist in the namespace `UnityEngine'. Are you missing an assembly reference?