A direct solution. WINDOWS ONLY. In my static helper blueprint class…
---- .h -----
UFUNCTION(BlueprintCallable, Category = TDLHelpers)
static TArray<FString> GetAllSaveGameSlotNames();
---- .cpp -----
#include "PlatformFeatures.h"
#include "GameFramework/SaveGame.h"
...
TArray<FString> UtdlBlueprintHelpers::GetAllSaveGameSlotNames()
{
TArray<FString> ret;
ISaveGameSystem* SaveSystem = IPlatformFeaturesModule::Get().GetSaveGameSystem();
// If we have a save system and a valid name..
if (SaveSystem)
{
// From SaveGameSystem.h in the Unreal source code base.
FString saveGamePath = FString::Printf(TEXT("%s/SaveGames/*"), *FPaths::GameSavedDir());
UE_LOG(TDLLog, Log, TEXT("Search path %s"), *saveGamePath);
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(*saveGamePath, &fd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
UE_LOG(TDLLog, Log, TEXT(" test name: %s"), fd.cFileName);
// Disallow empty names and . and .. and don't get all tied up in WCHAR issues.
if (fd.cFileName[0] == '\0'||
fd.cFileName[0] == '.' && fd.cFileName[1] == '\0' ||
fd.cFileName[0] == '.' && fd.cFileName[1] == '.' && fd.cFileName[2] == '\0')
{ }
else if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && fd.cFileName[0] != '.') {
ret.Add(FString(fd.cFileName));
}
} while (::FindNextFile(hFind, &fd));
::FindClose(hFind);
}
}
return ret;
}