Mag Roader
Mag Roader

Reputation: 7170

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?

Upvotes: 2

Views: 5592

Answers (3)

ScottyMacDev
ScottyMacDev

Reputation: 182

The easiest way I found to get the Saved Games path was to read the Registry value likes this:

var defaultPath = Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), "Saved Games");
var regKey = "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders";
var regKeyValue = "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}";
var regValue = (string) Registry.GetValue(regKey, regKeyValue, defaultPath);

I changed the location of my Saved Games via the Shell multiple times and the value of this key changed each time. I use the USERPROFILE/Saved Games as a default because I think that will work for the default circumstance where someone has never changed the location.

Upvotes: 0

rism
rism

Reputation: 12142

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.

Upvotes: 1

Nicolas Webb
Nicolas Webb

Reputation: 1322

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.

Upvotes: 2

Related Questions