Wednesday, April 20, 2011

How do you programatically find Vista's "Saved Games" folder?

I am using XNA and I want to save files to Vista's "Saved Games" folder.

I can get similar special folders like My Documents with Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) but I cannot find an equivalent for the Saved Games folder. How do I get to this folder?

From stackoverflow
  • There is no special folder const for it so just use System Variables. According to this Wikipedia article Special Folders, the saved games folder is just:

    Saved Games %USERPROFILE%\saved games Vista

    So the code would be:

     string sgPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "saved games"));
    

    ...

    EDIT: If, as per the comments, localization is an issue and as per your question you still want access to the Saved Games folder directly rather than using the API, then the following may be helpful.

    Using RedGate reflector we can see that GetFolderPath is implemented as follows:

    public static string GetFolderPath(SpecialFolder folder)
    {
        if (!Enum.IsDefined(typeof(SpecialFolder), folder))
        {
            throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, GetResourceString("Arg_EnumIllegalVal"), new object[] { (int) folder }));
        }
        StringBuilder lpszPath = new StringBuilder(260);
        Win32Native.SHGetFolderPath(IntPtr.Zero, (int) folder, IntPtr.Zero, 0, lpszPath);
        string path = lpszPath.ToString();
        new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();
        return path;
    }
    

    So maybe you think all i need is to create my own version of this method and pass it the folder id for Saved Games. That wont work. Those folder ids pre-Vista were actually CSIDLs. A list of them can be found here. Note the Note: however.

    In releasing Vista, Microsoft replaced CLSIDLs with KNOWNFOLDERIDs. A list of KNOWNFOLDERIDs can be found here. And the Saved Games KNOWNFOLDERID is FOLDERID_SavedGames.

    But you don't just pass the new const to the old, CLSIDL based, SHGetFolderPath Win32 function. As per this article, Known Folders, and as you might expect, there is a new function called SHGetKnownFolderPath to which you pass the new FOLDERID_SavedGames constant and that will return the path to the Saved Games folder in a localized form.

    Samuel : And when the game is run on a system that's not English? Kaboom!
    Craig : To be fair, the wikipedia article says the 'saved games' should be localised.
    Samuel : @Craig: And you know what Microsoft uses for each language they support? Why even attempt to learn that when you can use the provided API?
  • http://msdn.microsoft.com/en-us/library/bb200105.aspx#ID2EWD

    Looks like you'll need to use Microsoft.Xna.Framework.Storage and the StorageLocation class to do what you need to.

    Currently, the title location on a PC is the folder where the executable resides when it is run. Use the TitleLocation property to access the path.

    User storage is in the My Documents folder of the user who is currently logged in, in the SavedGames folder. A subfolder is created for each game according to the titleName passed to the OpenContainer method. When no PlayerIndex is specified, content is saved in the AllPlayers folder. When a PlayerIndex is specified, the content is saved in the Player1, Player2, Player3, or Player4 folder, depending on which PlayerIndex was passed to BeginShowStorageDeviceSelector.

0 comments:

Post a Comment