private static Assembly OnAssemblyResolve(string assemblyName) { if (!string.IsNullOrEmpty(UnrealTypes.GameAssemblyDirectory)) { // Strip down the full assembly name down to a name which could be used as the file name // "UnrealEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" for (int i = 0; i < 3; i++) { int index = assemblyName.LastIndexOf(','); if (index >= 0) { assemblyName = assemblyName.Substring(0, index); } } assemblyName += ".dll"; string assemblyPath = Path.Combine(UnrealTypes.GameAssemblyDirectory, assemblyName); if (File.Exists(assemblyPath)) { // Need to use LoadFrom instead of LoadFile to for shadow copying to work properly Assembly assembly = CurrentAssemblyContext.LoadFrom(assemblyPath); return(assembly); } } return(null); }
private static void LoadAssemblies() { string gameAssemblyFileName = null; const string gameAssemblySuffix = ".Managed.dll"; // Add to assemblyPaths for each possible location the main managed assembly can be. // If a managed assembly is found just use the found assembly path (and its references). HashSet <string> assemblyPaths = new HashSet <string>(); EPlatform platform = FPlatformProperties.GetPlatform(); if (platform == EPlatform.Android) { string externalFilePath = FGlobals.AndroidFile.ExternalFilePath; string managedBinDir = Path.Combine(externalFilePath, "USharp", "Managed"); string projectName; string projectFileName = FPaths.ProjectFilePath; if (!string.IsNullOrEmpty(projectFileName)) { projectName = Path.GetFileNameWithoutExtension(projectFileName); } string assemblyPath = Path.GetFullPath(Path.Combine(managedBinDir, projectFileName + gameAssemblySuffix)); assemblyPaths.Add(assemblyPath); if (!File.Exists(assemblyPath)) { assemblyPath = Path.GetFullPath(Path.Combine(managedBinDir, FGlobals.InternalProjectName + gameAssemblySuffix)); assemblyPaths.Add(assemblyPath); } if (File.Exists(assemblyPath)) { gameAssemblyFileName = assemblyPath; } } else { string projectFileName = FPaths.ProjectFilePath; if (!string.IsNullOrEmpty(projectFileName)) { projectFileName = Path.GetFileNameWithoutExtension(projectFileName); string projectManagedBinDir = Path.Combine(FPaths.ProjectDir, "Binaries", "Managed"); if (FBuild.WithEditor && !Directory.Exists(projectManagedBinDir)) { Directory.CreateDirectory(projectManagedBinDir); } string assemblyPath = Path.GetFullPath(Path.Combine(projectManagedBinDir, projectFileName + gameAssemblySuffix)); if (File.Exists(assemblyPath)) { gameAssemblyFileName = assemblyPath; } assemblyPaths.Add(assemblyPath); } string projectName = FGlobals.InternalProjectName; if (string.IsNullOrEmpty(gameAssemblyFileName) && !string.IsNullOrEmpty(projectName)) { string path = Path.GetFullPath(projectName + gameAssemblySuffix); assemblyPaths.Add(path); if (!File.Exists(path)) { path = Path.GetFullPath(Path.Combine("../", "Managed", projectName + gameAssemblySuffix)); } if (File.Exists(path)) { gameAssemblyFileName = path; } assemblyPaths.Add(path); } } // We either need to load all unreal assemblies or hold some metadata to know what modules to load dynamically // as GCHelper needs to resolve types. Resolving all assemblies is tricky without forcefully loading all dependencies // which may be undesirable. if (!string.IsNullOrEmpty(gameAssemblyFileName) && File.Exists(gameAssemblyFileName)) { // Clear the assembly paths as we have found a concrete target game assembly assemblyPaths.Clear(); assemblyPaths.Add(gameAssemblyFileName); UnrealTypes.GameAssemblyPath = Path.GetFullPath(gameAssemblyFileName); UnrealTypes.GameAssemblyDirectory = Path.GetDirectoryName(UnrealTypes.GameAssemblyPath); //string pdbFileName = Path.ChangeExtension(gameAssemblyFileName, ".pdb"); //byte[] assemblyBuffer = File.ReadAllBytes(gameAssemblyFileName); //byte[] pdbBuffer = File.Exists(pdbFileName) ? File.ReadAllBytes(pdbFileName) : null; //Assembly assembly = Assembly.Load(assemblyBuffer, pdbBuffer); // Need to use LoadFrom instead of LoadFile to for shadow copying to work properly Assembly assembly = CurrentAssemblyContext.LoadFrom(gameAssemblyFileName); string[] dependencies = ResolveAssemblyDependencies(assembly); foreach (string assemblyPath in dependencies) { assemblyPaths.Add(assemblyPath); } } EntryPoint.HotReloadAssemblyPaths = assemblyPaths.ToArray(); }
public static int DllMain(string arg) { try { Args args = new Args(arg); if (!SharedRuntimeState.Initialized) { SharedRuntimeState.Initialize((IntPtr)args.GetInt64("RuntimeState")); AssemblyContextRef currentContext; AssemblyContextRef.TryParse(args.GetString("AssemblyContext"), out currentContext); AssemblyContext.Initialize(currentContext); CurrentAssemblyContext.Initialize(currentContext); } if (args.GetBool("Preloading")) { Preloading = true; IntPtr address = (IntPtr)args.GetInt64("RegisterFuncs"); if (address != IntPtr.Zero) { NativeFunctions.RegisterFunctions(address); Preloaded = true; } Preloading = false; return(0); } else { unsafe { SharedRuntimeState.Instance->ActiveRuntime = SharedRuntimeState.CurrentRuntime; } DateTime beginUnload = default(DateTime); TimeSpan beginReload = DateTime.Now.TimeOfDay; bool isReloading = false; using (var timing = HotReload.Timing.Create(HotReload.Timing.TotalLoadTime)) { using (var subTiming = HotReload.Timing.Create(HotReload.Timing.DataStore_Load)) { // If this is a hot-reload then set up the data store HotReload.Data = HotReload.DataStore.Load(SharedRuntimeState.GetHotReloadData()); beginUnload = HotReload.Data.BeginUnloadTime; } HotReload.IsReloading = args.GetBool("Reloading"); isReloading = HotReload.IsReloading; IntPtr address = (IntPtr)args.GetInt64("RegisterFuncs"); if (address != IntPtr.Zero) { NativeFunctions.RegisterFunctions(address); } } SharedRuntimeState.SetHotReloadAssemblyPaths(HotReloadAssemblyPaths); TimeSpan endTime = DateTime.Now.TimeOfDay; FMessage.Log("BeginReload: " + beginReload + " (BeginUnload-BeginReload: " + (beginReload - beginUnload.TimeOfDay) + ")"); FMessage.Log("EndReload: " + endTime + " (BeginUnload-EndReload: " + (endTime - beginUnload.TimeOfDay) + ")"); HotReload.Timing.Print(isReloading); HotReload.Timing.PrintAll(); return(0); } } catch (Exception e) { string exceptionStr = "Entry point exception (UnrealEngine.Runtime): " + e; if (SharedRuntimeState.Initialized) { SharedRuntimeState.LogError(exceptionStr); SharedRuntimeState.MessageBox(exceptionStr, "Error"); } return(1005);// AssemblyLoaderError.Exception } }