public String Load(String assembly) { String domainBase = "unknown"; try { if (_currentDomain != null) { AppDomain.Unload(_currentDomain); } _currentDomain = null; // The assembly is expected to be in the ModelMod installation directory. // (Unlike this app domain assembly, which must be copied into the game dir). // Setting appbase to this modelmod install dir allows the references // (fsharp, monogame, etc) to be loaded // without requiring them to be copied to the game dir. var ads = new AppDomainSetup(); ads.ApplicationBase = Path.GetDirectoryName(assembly); ads.DisallowBindingRedirects = false; ads.DisallowCodeDownload = true; // use the configuration file property to specify the name of the assembly that must be loaded. // can't use a static field; the sandbox domain has a separate copy of all the statics. ads.ConfigurationFile = assembly; // this loader callback is needed so that we can hot-swap the assembly. // http://stackoverflow.com/questions/425077/how-to-delete-the-pluginassembly-after-appdomain-unloaddomain var d = base.CreateDomain("ImSoFriendly", null, ads); _currentDomain = d; domainBase = d.BaseDirectory; d.DoCallBack(new CrossAppDomainDelegate(LoaderCB)); return ""; // empty string means no error, otherwise, its an error message } catch (Exception e) { return "Error during load. " + Environment.NewLine + "Root app domain: " + AppDomain.CurrentDomain.GetHashCode() + Environment.NewLine + "Sandbox domain: " + _currentDomain.GetHashCode() + Environment.NewLine + "Sandbox domain base: " + domainBase + Environment.NewLine + "Exception: " + e.ToString(); } }
public virtual void Run() { this.TryObtainLock(); try { this.Preconditions(Pre.SiteSet | Pre.RootNamespaceSet | Pre.RootMonikerSet | Pre.EngineNotRunning | Pre.EngineNotClosed); System.AppDomain currentDomain = System.AppDomain.CurrentDomain; if (this.haveCompiledState) { if (this.rootNamespace != this.compiledRootNamespace) { throw new JSVsaException(JSVsaError.RootNamespaceInvalid); } this.loadedAssembly = this.LoadCompiledState(); currentDomain.SetData(this.engineMoniker, this.loadedAssembly); } else { if (this.failedCompilation) { throw new JSVsaException(JSVsaError.EngineNotCompiled); } this.startupClass = null; this.loadedAssembly = currentDomain.GetData(this.engineMoniker) as System.Reflection.Assembly; if (this.loadedAssembly == null) { string name = this.engineMoniker + "/" + currentDomain.GetHashCode().ToString(CultureInfo.InvariantCulture); Mutex mutex = new Mutex(false, name); if (mutex.WaitOne()) { try { this.loadedAssembly = currentDomain.GetData(this.engineMoniker) as System.Reflection.Assembly; if (this.loadedAssembly == null) { byte[] buffer; byte[] buffer2; this.engineSite.GetCompiledState(out buffer, out buffer2); if (buffer == null) { throw new JSVsaException(JSVsaError.GetCompiledStateFailed); } this.loadedAssembly = System.Reflection.Assembly.Load(buffer, buffer2, this.executionEvidence); currentDomain.SetData(this.engineMoniker, this.loadedAssembly); } } finally { mutex.ReleaseMutex(); mutex.Close(); } } } } try { if (this.startupClass == null) { this.startupClass = this.loadedAssembly.GetType(this.rootNamespace + "._Startup", true); } } catch (Exception exception) { throw new JSVsaException(JSVsaError.BadAssembly, exception.ToString(), exception); } try { this.startupInstance = (BaseVsaStartup)Activator.CreateInstance(this.startupClass); this.isEngineRunning = true; this.startupInstance.SetSite(this.engineSite); this.startupInstance.Startup(); } catch (Exception exception2) { throw new JSVsaException(JSVsaError.UnknownError, exception2.ToString(), exception2); } } finally { this.ReleaseLock(); } }