bool FDesktopPlatformBase::GetEngineIdentifierForProject(const FString& ProjectFileName, FString& OutIdentifier) { OutIdentifier.Empty(); // Load the project file TSharedPtr<FJsonObject> ProjectFile = LoadProjectFile(ProjectFileName); if(!ProjectFile.IsValid()) { return false; } // Try to read the identifier from it TSharedPtr<FJsonValue> Value = ProjectFile->TryGetField(TEXT("EngineAssociation")); if(Value.IsValid() && Value->Type == EJson::String) { OutIdentifier = Value->AsString(); if(OutIdentifier.Len() > 0) { // If it's a path, convert it into an engine identifier if(OutIdentifier.Contains(TEXT("/")) || OutIdentifier.Contains("\\")) { FString EngineRootDir = FPaths::ConvertRelativePathToFull(FPaths::GetPath(ProjectFileName), OutIdentifier); if(!GetEngineIdentifierFromRootDir(EngineRootDir, OutIdentifier)) { return false; } } return true; } } // Otherwise scan up through the directory hierarchy to find an installation FString ParentDir = FPaths::GetPath(ProjectFileName); FPaths::NormalizeDirectoryName(ParentDir); // Keep going until we reach the root int32 SeparatorIdx; while(ParentDir.FindLastChar(TEXT('/'), SeparatorIdx)) { ParentDir.RemoveAt(SeparatorIdx, ParentDir.Len() - SeparatorIdx); if(IsValidRootDirectory(ParentDir) && GetEngineIdentifierFromRootDir(ParentDir, OutIdentifier)) { return true; } } // Otherwise check the engine version string for 4.0, in case this project existed before the engine association stuff went in FString EngineVersionString = ProjectFile->GetStringField(TEXT("EngineVersion")); if(EngineVersionString.Len() > 0) { FEngineVersion EngineVersion; if(FEngineVersion::Parse(EngineVersionString, EngineVersion) && EngineVersion.HasChangelist() && EngineVersion.ToString(EVersionComponent::Minor) == TEXT("4.0")) { OutIdentifier = TEXT("4.0"); return true; } } return false; }
void FDesktopPlatformWindows::EnumerateEngineInstallations(TMap<FString, FString> &OutInstallations) { // Enumerate the binary installations EnumerateLauncherEngineInstallations(OutInstallations); // Enumerate the per-user installations HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, InstallationsSubKey, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { // Get a list of all the directories TArray<FString> UniqueDirectories; OutInstallations.GenerateValueArray(UniqueDirectories); // Enumerate all the installations TArray<FString> InvalidKeys; for (::DWORD Index = 0;; Index++) { TCHAR ValueName[256]; TCHAR ValueData[MAX_PATH]; ::DWORD ValueType = 0; ::DWORD ValueNameLength = sizeof(ValueName) / sizeof(ValueName[0]); ::DWORD ValueDataSize = sizeof(ValueData); LRESULT Result = RegEnumValue(hKey, Index, ValueName, &ValueNameLength, NULL, &ValueType, (BYTE*)&ValueData[0], &ValueDataSize); if(Result == ERROR_SUCCESS) { int32 ValueDataLength = ValueDataSize / sizeof(TCHAR); if(ValueDataLength > 0 && ValueData[ValueDataLength - 1] == 0) ValueDataLength--; FString NormalizedInstalledDirectory(ValueDataLength, ValueData); FPaths::NormalizeDirectoryName(NormalizedInstalledDirectory); FPaths::CollapseRelativeDirectories(NormalizedInstalledDirectory); if(IsValidRootDirectory(NormalizedInstalledDirectory) && !UniqueDirectories.Contains(NormalizedInstalledDirectory)) { OutInstallations.Add(ValueName, NormalizedInstalledDirectory); UniqueDirectories.Add(NormalizedInstalledDirectory); } else { InvalidKeys.Add(ValueName); } } else if(Result == ERROR_NO_MORE_ITEMS) { break; } } // Remove all the keys which weren't valid for(const FString InvalidKey: InvalidKeys) { RegDeleteValue(hKey, *InvalidKey); } RegCloseKey(hKey); } }
void FDesktopPlatformWindows::EnumerateEngineInstallations(TMap<FString, FString> &OutInstallations) { // Enumerate the binary installations EnumerateLauncherEngineInstallations(OutInstallations); // Enumerate the per-user installations HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, InstallationsSubKey, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { // Enumerate all the installations for (::DWORD Index = 0;; Index++) { TCHAR ValueName[256]; TCHAR ValueData[MAX_PATH]; ::DWORD ValueType = 0; ::DWORD ValueNameLength = sizeof(ValueName) / sizeof(ValueName[0]); ::DWORD ValueDataSize = sizeof(ValueData); LRESULT Result = RegEnumValue(hKey, Index, ValueName, &ValueNameLength, NULL, &ValueType, (BYTE*)&ValueData[0], &ValueDataSize); if(Result == ERROR_SUCCESS) { int32 ValueDataLength = ValueDataSize / sizeof(TCHAR); if(ValueDataLength > 0 && ValueData[ValueDataLength - 1] == 0) ValueDataLength--; FString NormalizedInstalledDirectory(ValueDataLength, ValueData); FPaths::NormalizeDirectoryName(NormalizedInstalledDirectory); OutInstallations.Add(ValueName, NormalizedInstalledDirectory); } else if(Result == ERROR_NO_MORE_ITEMS) { break; } } // Trim the list to everything that's valid for(TMap<FString, FString>::TIterator Iter(OutInstallations); Iter; ++Iter) { if (!IsValidRootDirectory(Iter.Value())) { RegDeleteValue(hKey, *Iter.Key()); Iter.RemoveCurrent(); } } RegCloseKey(hKey); } }
bool FDesktopPlatformLinux::RegisterEngineInstallation(const FString &RootDir, FString &OutIdentifier) { bool bRes = false; if (IsValidRootDirectory(RootDir)) { FConfigFile ConfigFile; FString ConfigPath = FString(FPlatformProcess::ApplicationSettingsDir()) / FString(TEXT("UnrealEngine")) / FString(TEXT("Install.ini")); ConfigFile.Read(ConfigPath); FConfigSection &Section = ConfigFile.FindOrAdd(TEXT("Installations")); OutIdentifier = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphens); Section.AddUnique(*OutIdentifier, RootDir); ConfigFile.Dirty = true; ConfigFile.Write(ConfigPath); } return bRes; }
bool FDesktopPlatformWindows::RegisterEngineInstallation(const FString &RootDir, FString &OutIdentifier) { bool bRes = false; if(IsValidRootDirectory(RootDir)) { HKEY hRootKey; if(RegCreateKeyEx(HKEY_CURRENT_USER, InstallationsSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRootKey, NULL) == ERROR_SUCCESS) { FString NewIdentifier = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphensInBraces); LRESULT SetResult = RegSetValueEx(hRootKey, *NewIdentifier, 0, REG_SZ, (const BYTE*)*RootDir, (RootDir.Len() + 1) * sizeof(TCHAR)); RegCloseKey(hRootKey); if(SetResult == ERROR_SUCCESS) { OutIdentifier = NewIdentifier; bRes = true; } } } return bRes; }