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; }
/** Migrates config files from a previous version of the engine. Does nothing on non-installed versions */ void MigratePreviousEngineInis() { if (!FPaths::ShouldSaveToUserDir() && !FApp::IsEngineInstalled()) { // We can't do this in non-installed engines or where we haven't saved to a user directory return; } int32 MinorVersion = GEngineVersion.GetMinor() - 1; IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile(); while(MinorVersion >= 0) { const FEngineVersion PreviousVersion(GEngineVersion.GetMajor(), MinorVersion--, 0, 0, FString()); const FString Directory = FString(FPlatformProcess::UserSettingsDir()) / ENGINE_VERSION_TEXT(EPIC_PRODUCT_IDENTIFIER) / PreviousVersion.ToString(EVersionComponent::Minor) / TEXT("Saved") / TEXT("Config") / ANSI_TO_TCHAR(FPlatformProperties::PlatformName()); if (FPaths::DirectoryExists(Directory)) { const FString DestDir = ProjectAgnosticIniPath(TEXT("")); if (PlatformFile.CreateDirectoryTree(*DestDir)) { PlatformFile.CopyDirectoryTree(*DestDir, *Directory, false); } // If we failed to create the directory tree anyway we don't want to allow the possibility of upgrading from even older versions, so early return regardless return; } } }
bool ICrashDebugHelper::Init() { bInitialized = true; // Check if we have a valid EngineVersion, if so use it. FString CmdEngineVersion; const bool bHasEngineVersion = FParse::Value( FCommandLine::Get(), TEXT( "EngineVersion=" ), CmdEngineVersion ); if( bHasEngineVersion ) { FEngineVersion EngineVersion; FEngineVersion::Parse( CmdEngineVersion, EngineVersion ); // Clean branch name. CrashInfo.DepotName = EngineVersion.GetBranch(); CrashInfo.BuiltFromCL = (int32)EngineVersion.GetChangelist(); CrashInfo.EngineVersion = CmdEngineVersion; } else { // Look up the depot name // Try to use the command line param FString DepotName; FString CmdLineBranchName; if( FParse::Value( FCommandLine::Get(), TEXT( "BranchName=" ), CmdLineBranchName ) ) { DepotName = FString::Printf( TEXT( "%s%s" ), P4_DEPOT_PREFIX, *CmdLineBranchName ); } // Default to BRANCH_NAME else { DepotName = FString::Printf( TEXT( "%s" ), TEXT( BRANCH_NAME ) ); } CrashInfo.DepotName = DepotName.Replace( TEXT( "+" ), TEXT( "/" ) ); // Try to get the BuiltFromCL from command line to use this instead of attempting to locate the CL in the minidump FString CmdLineBuiltFromCL; int32 BuiltFromCL = -1; if( FParse::Value( FCommandLine::Get(), TEXT( "BuiltFromCL=" ), CmdLineBuiltFromCL ) ) { if( !CmdLineBuiltFromCL.IsEmpty() ) { BuiltFromCL = FCString::Atoi( *CmdLineBuiltFromCL ); } } // Default to BUILT_FROM_CHANGELIST. else { BuiltFromCL = int32( BUILT_FROM_CHANGELIST ); } CrashInfo.BuiltFromCL = BuiltFromCL; } UE_LOG( LogCrashDebugHelper, Log, TEXT( "DepotName: %s" ), *CrashInfo.DepotName ); UE_LOG( LogCrashDebugHelper, Log, TEXT( "BuiltFromCL: %i" ), CrashInfo.BuiltFromCL ); UE_LOG( LogCrashDebugHelper, Log, TEXT( "EngineVersion: %s" ), *CrashInfo.EngineVersion ); GConfig->GetString( TEXT( "Engine.CrashDebugHelper" ), TEXT( "SourceControlBuildLabelPattern" ), SourceControlBuildLabelPattern, GEngineIni ); GConfig->GetArray( TEXT( "Engine.CrashDebugHelper" ), TEXT( "ExecutablePathPattern" ), ExecutablePathPatterns, GEngineIni ); GConfig->GetArray( TEXT( "Engine.CrashDebugHelper" ), TEXT( "SymbolPathPattern" ), SymbolPathPatterns, GEngineIni ); GConfig->GetArray( TEXT( "Engine.CrashDebugHelper" ), TEXT( "Branch" ), Branches, GEngineIni ); const bool bCanUseSearchPatterns = Branches.Num() == ExecutablePathPatterns.Num() && ExecutablePathPatterns.Num() == SymbolPathPatterns.Num() && Branches.Num() > 0; UE_CLOG( !bCanUseSearchPatterns, LogCrashDebugHelper, Warning, TEXT( "Search patterns don't match" ) ); if (bCanUseSearchPatterns) { FPDBCache::Get().Init(); } else { UE_LOG( LogCrashDebugHelper, Warning, TEXT( "PDB Cache disabled" ) ); } return bInitialized; }