diff --git a/ILSpy/AssemblyList.cs b/ILSpy/AssemblyList.cs index a620408f0..c59081bd9 100644 --- a/ILSpy/AssemblyList.cs +++ b/ILSpy/AssemblyList.cs @@ -145,6 +145,29 @@ namespace ICSharpCode.ILSpy } return newAsm; } + + /// + /// Replace the assembly object model from a crafted stream, without disk I/O + /// Returns null if it is not already loaded. + /// + public LoadedAssembly HotReplaceAssembly(string file, Stream stream) + { + App.Current.Dispatcher.VerifyAccess(); + file = Path.GetFullPath(file); + + var target = this.assemblies.FirstOrDefault(asm => file.Equals(asm.FileName, StringComparison.OrdinalIgnoreCase)); + if (target == null) + return null; + + var index = this.assemblies.IndexOf(target); + var newAsm = new LoadedAssembly(this, file, stream); + lock (assemblies) + { + this.assemblies.Remove(target); + this.assemblies.Insert(index, newAsm); + } + return newAsm; + } public void Unload(LoadedAssembly assembly) { diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index 43f2e12b2..c67e06ebe 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.ILSpy readonly string fileName; readonly string shortName; - public LoadedAssembly(AssemblyList assemblyList, string fileName) + public LoadedAssembly(AssemblyList assemblyList, string fileName, Stream stream = null) { if (assemblyList == null) throw new ArgumentNullException("assemblyList"); @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy this.assemblyList = assemblyList; this.fileName = fileName; - this.assemblyTask = Task.Factory.StartNew(LoadAssembly); // requires that this.fileName is set + this.assemblyTask = Task.Factory.StartNew(LoadAssembly, stream); // requires that this.fileName is set this.shortName = Path.GetFileNameWithoutExtension(fileName); } @@ -93,12 +93,26 @@ namespace ICSharpCode.ILSpy get { return assemblyTask.IsFaulted; } } - ModuleDefinition LoadAssembly() + ModuleDefinition LoadAssembly(object state) { + var stream = state as Stream; + ModuleDefinition module; + // runs on background thread ReaderParameters p = new ReaderParameters(); p.AssemblyResolver = new MyAssemblyResolver(this); - ModuleDefinition module = ModuleDefinition.ReadModule(fileName, p); + + if (stream != null) + { + // Read the module from a precrafted stream + module = ModuleDefinition.ReadModule(stream, p); + } + else + { + // Read the module from disk (by default) + module = ModuleDefinition.ReadModule(fileName, p); + } + if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) { try { LoadSymbols(module);