/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (this.referencesEvents != null) { this.referencesEvents.ReferenceAdded -= this.ReferencesUpdated; this.referencesEvents.ReferenceChanged -= this.ReferencesUpdated; this.referencesEvents.ReferenceRemoved -= this.ReferencesUpdated; this.referencesEvents = null; } if (this.importsEvents != null) { this.importsEvents.ImportAdded -= this.ImportsUpdated; this.importsEvents.ImportRemoved -= this.ImportsUpdated; this.importsEvents = null; } if (this.watchers != null) { foreach (var watcher in this.watchers) { watcher.Changed -= this.FileChanged; watcher.Renamed -= this.FileChanged; watcher.Deleted -= this.FileChanged; watcher.Created -= this.FileChanged; watcher.Dispose(); } this.watchers.Clear(); this.watchers = null; } if (this.intellisenseSession != null) { if (this.handler != null) { this.intellisenseSession.DocumentUpdated -= this.handler.Handler; this.handler = null; } this.intellisenseSession = null; } if (this.appDomain != null) { AppDomain.Unload(this.appDomain); } this.appDomain = null; }
/// <summary> /// Initializes the proxy. /// </summary> /// <param name="projectId"> /// The project id. /// </param> private void Init(string projectId) { Task.Run(() => { try { var visualStudioProject = IntellisenseProxy.GetVisualStudioProjectByUniqueName(projectId); var projectName = "Unknown project"; var configFile = (string)null; var assemblies = new string[0]; if (visualStudioProject != null) { projectName = visualStudioProject.Project.Name; try { this.referencesEvents = visualStudioProject.Events.ReferencesEvents; this.referencesEvents.ReferenceAdded += this.ReferencesUpdated; this.referencesEvents.ReferenceChanged += this.ReferencesUpdated; this.referencesEvents.ReferenceRemoved += this.ReferencesUpdated; } catch (NotImplementedException) { //// CPS does not have reference events. } try { this.importsEvents = visualStudioProject.Events.ImportsEvents; this.importsEvents.ImportAdded += this.ImportsUpdated; this.importsEvents.ImportRemoved += this.ImportsUpdated; } catch (NotImplementedException) { //// CPS does not have import events. } configFile = visualStudioProject.Project.ProjectItems.OfType <ProjectItem>().FirstOrDefault(i => i.Name.EndsWith(".config", StringComparison.OrdinalIgnoreCase))?.FileNames[0]; assemblies = visualStudioProject.References.Cast <Reference>() .Where(r => { try { return(!string.IsNullOrEmpty(r.Path)); } catch { return(false); } }) .Select(r => r.Path) .ToArray(); } var setupInfomation = AppDomain.CurrentDomain.SetupInformation; setupInfomation.ApplicationBase = string.Empty; setupInfomation.ConfigurationFile = configFile; setupInfomation.LoaderOptimization = LoaderOptimization.SingleDomain; AppDomain.CurrentDomain.AssemblyResolve += IntellisenseProxy.AppDomainFix; this.appDomain = AppDomain.CreateDomain($"Intellisense project {projectName} domain", null, setupInfomation); object[] arguments = { assemblies, typeof(ConnectQlContext).Assembly.Location }; this.watchPaths = assemblies .Concat(new[] { configFile }).ToArray(); this.WatchPaths(this.watchPaths); this.handler = new RemoteEventHandler <byte[]>(this.IntellisenseSessionOnDocumentUpdated); this.intellisenseSession = (AppDomainIntellisenseSession)this.appDomain.CreateInstanceFromAndUnwrap( typeof(AppDomainIntellisenseSession).Assembly.Location, typeof(AppDomainIntellisenseSession).FullName ?? string.Empty, false, BindingFlags.CreateInstance, null, arguments, CultureInfo.CurrentCulture, null); this.intellisenseSession.DocumentUpdated += this.handler.Handler; this.Initialized?.Invoke(this, EventArgs.Empty); } catch (Exception) { this.Dispose(); Task.Run(async() => { await Task.Delay(TimeSpan.FromSeconds(1)); this.Init(projectId); }); } finally { AppDomain.CurrentDomain.AssemblyResolve -= IntellisenseProxy.AppDomainFix; } }); }