tags:

views:

1519

answers:

2

I'm saving some stuff in an IsolatedStorageFile. It works well and I can retrieve the saved values when calling the saving and retrieving methods in my DAL layer from my GUI layer. However, when I try to retrieve the same settings from another assembly in the same project, it gives me a FileNotFoundException. What do I do wrong? This is the general concept:

    public void Save(int number)
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetMachineStoreForAssembly();
        IsolatedStorageFileStream fileStream =
            new IsolatedStorageFileStream(filename, FileMode.OpenOrCreate, storage);

        StreamWriter writer = new StreamWriter(fileStream);
        writer.WriteLine(number);
        writer.Close();
    }

    public int Retrieve()
    {
        IsolatedStorageFile storage = IsolatedStorageFile.GetMachineStoreForAssembly();
        IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(filename, FileMode.Open, storage);

        StreamReader reader = new StreamReader(fileStream);

        int number;

        try
        {
            string line = reader.ReadLine();
            number = int.Parse(line);
        }
        finally
        {
            reader.Close();
        }

        return number;
    }

I've tried using all the GetMachineStoreFor* scopes.

EDIT: Since I need several assemblies to access the files, it doesn't seem possible to do with isolated storage, unless it's a ClickOnce app.

+3  A: 

When you instantiated the IsolatedStorageFile, did you scope it to IsolatedStorageScope.Machine?

Ok now that you have illustrated your code style and I have gone back to retesting the behaviour of the methods, here is the explanation:

  • GetMachineStoreForAssembly() - scoped to the machine and the assembly identity. Different assemblies in the same application would have their own isolated storage.
  • GetMachineStoreForDomain() - a misnomer in my opinion. scoped to the machine and the domain identity on top of the assembly identity. There should have been an option for just AppDomain alone.
  • GetMachineStoreForApplication() - this is the one you are looking for. I have tested it and different assemblies can pick up the values written in another assembly. The only catch is, the application identity must be verifiable. When running locally, it cannot be properly determined and it will end up with exception "Unable to determine application identity of the caller". It can be verified by deploying the application via Click Once. Only then can this method apply and achieve its desired effect of shared isolated storage.
icelava
I've updated the post now to show all of the code.
Microserf
Answer updated accordingly.
icelava
+1  A: 

When you are saving, you are calling GetMachineStoreForDomain, but when you are retrieving, you are calling GetMachineStoreForAssembly.

GetMachineStoreForAssembly is scoped to the assembly that the code is executing in, while the GetMachineStoreForDomain is scoped to the currently running AppDomain and the assembly where the code is executing. Just change your these calls to GetMachineStoreForApplication, and it should work.

The documentation for IsolatedStorageFile can be found at http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile_members.aspx

Abe Heidebrecht
Sorry, that was a typo. I used the same scope for both the save and the retrieve methods. So the documentation isn't helping me here. As I said, I can successfully save and retrieve from the GUI, but another assembly can't retrieve it.
Microserf
Tried GetMachineStoreForApplication(), but got unhandled IsolatedStorageException: Unable to determin application identity of the caller
PerlDev
can you change it to GetMachineStoreForAssembly ?
Junior Mayhé