Ejemplo n.º 1
0
        public AddinScanner(AddinDatabase database, AddinScanResult scanResult, IProgressStatus monitor)
        {
            this.database = database;
            if (!scanResult.CheckOnly) {

                // If there is a local copy of the cecil reflector, use it instead of the one in the gac
                Type t;
                string asmFile = Path.Combine (Path.GetDirectoryName (GetType().Assembly.Location), "Mono.Addins.CecilReflector.dll");
                if (File.Exists (asmFile)) {
                    Assembly asm = Assembly.LoadFrom (asmFile);
                    t = asm.GetType ("Mono.Addins.CecilReflector.Reflector");
                }
                else {
                    string refName = GetType().Assembly.FullName;
                    int i = refName.IndexOf (',');
                    refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring (i);
                    t = Type.GetType (refName, false);
                }
                if (t != null)
                    reflector = (IAssemblyReflector) Activator.CreateInstance (t);
                else
                    reflector = new DefaultAssemblyReflector ();

                if (monitor.LogLevel > 1)
                    monitor.Log ("Using assembly reflector: " + reflector.GetType ());
                reflector.Initialize (scanResult);
                coreAssembly = reflector.LoadAssembly (GetType().Assembly.Location);
            }
        }
Ejemplo n.º 2
0
        public AddinScanner(AddinDatabase database, AddinScanResult scanResult, IProgressStatus monitor)
        {
            this.database = database;
            if (!scanResult.CheckOnly)
            {
                string refName = GetType().Assembly.FullName;
                int    i       = refName.IndexOf(',');
                refName = "Mono.Addins.CecilReflector.Reflector, Mono.Addins.CecilReflector" + refName.Substring(i);
                Type t = Type.GetType(refName, false);
                if (t != null)
                {
                    reflector = (IAssemblyReflector)Activator.CreateInstance(t);
                }
                else
                {
                    reflector = new DefaultAssemblyReflector();
                }

                if (monitor.LogLevel > 1)
                {
                    monitor.Log("Using assembly reflector: " + reflector.GetType());
                }
                reflector.Initialize(scanResult);
                coreAssembly = reflector.LoadAssembly(GetType().Assembly.Location);
            }
        }
Ejemplo n.º 3
0
        public AddinDescription ScanSingleFile(IProgressStatus monitor, string file, AddinScanResult scanResult)
        {
            AddinDescription config = null;

            if (monitor.LogLevel > 1)
            {
                monitor.Log("Scanning file: " + file);
            }

            monitor.Log("plog:scan:" + file);

            try {
                string ext = Path.GetExtension(file);
                bool   scanSuccessful;

                if (ext == ".dll" || ext == ".exe")
                {
                    scanSuccessful = ScanAssembly(monitor, file, scanResult, out config);
                }
                else
                {
                    scanSuccessful = ScanConfigAssemblies(monitor, file, scanResult, out config);
                }

                if (scanSuccessful && config != null)
                {
                    config.Domain = "global";
                    if (config.Version.Length == 0)
                    {
                        config.Version = "0.0.0.0";
                    }

                    if (config.LocalId.Length == 0)
                    {
                        // Generate an internal id for this add-in
                        config.LocalId = database.GetUniqueAddinId(file, "", config.Namespace, config.Version);
                    }
                }
            }
            catch (Exception ex) {
                monitor.ReportError("Unexpected error while scanning file: " + file, ex);
            } finally {
                monitor.Log("plog:endscan");
            }
            return(config);
        }
Ejemplo n.º 4
0
 public void Log(string msg)
 {
     if (msg.StartsWith("plog:"))
     {
         progessLog.Add(msg.Substring(5));
     }
     else
     {
         local.Log(msg);
     }
 }
Ejemplo n.º 5
0
        void ReportReflectionException(IProgressStatus monitor, Exception ex, AddinDescription config, AddinScanResult scanResult)
        {
            scanResult.AddFileToWithFailure(config.AddinFile);
            if (monitor.LogLevel <= 1)
            {
                return;
            }

            monitor.Log("Could not load some add-in assemblies: " + ex.Message);

            ReflectionTypeLoadException rex = ex as ReflectionTypeLoadException;

            if (rex != null)
            {
                foreach (Exception e in rex.LoaderExceptions)
                {
                    monitor.Log("Load exception: " + e);
                }
            }
        }
Ejemplo n.º 6
0
        void WriteLog(string text)
        {
            int pi = 0;
            int i  = text.IndexOf('\n');

            while (i != -1)
            {
                string line = text.Substring(pi, i - pi);
                if (logBuffer.Length > 0)
                {
                    logBuffer.Append(line);
                    status.Log(logBuffer.ToString());
                    logBuffer.Clear();
                }
                else
                {
                    status.Log(line);
                }
                pi = i + 1;
                i  = text.IndexOf('\n', pi);
            }
            logBuffer.Append(text.Substring(pi));
        }
Ejemplo n.º 7
0
        public void RegisterExtension(AddinDescription description, ModuleDescription module, string path)
        {
            List <RootExtensionPoint> extensions;

            if (!pathHash.TryGetValue(path, out extensions))
            {
                // Root add-in extension points are registered before any other kind of extension,
                // so we should find it now.
                extensions = GetParentExtensionInfo(path);
            }
            if (extensions == null)
            {
                monitor.ReportWarning("The add-in '" + description.AddinId + "' is trying to extend '" + path + "', but there isn't any add-in defining this extension point");
                return;
            }

            bool found = false;

            foreach (RootExtensionPoint einfo in extensions)
            {
                if (IsAddinCompatible(einfo.Description, description, module))
                {
                    if (!einfo.ExtensionPoint.Addins.Contains(description.AddinId))
                    {
                        einfo.ExtensionPoint.Addins.Add(description.AddinId);
                    }
                    found = true;
                    if (monitor.LogLevel > 2)
                    {
                        monitor.Log("  * " + einfo.Description.AddinId + "(" + einfo.Description.Domain + ") <- " + path);
                    }
                }
            }
            if (!found)
            {
                monitor.ReportWarning("The add-in '" + description.AddinId + "' is trying to extend '" + path + "', but there isn't any compatible add-in defining this extension point");
            }
        }
Ejemplo n.º 8
0
        public static void MonitorProcessStatus(IProgressStatus monitor, TextReader reader, StringCollection progessLog)
        {
            string line;
            string exceptionText = null;

            while ((line = reader.ReadLine()) != null)
            {
                int i = line.IndexOf(':');
                if (i != -1)
                {
                    string tag    = line.Substring(0, i);
                    string txt    = line.Substring(i + 1);
                    bool   wasTag = true;

                    switch (tag)
                    {
                    case "process-ps-msg":
                        monitor.SetMessage(Decode(txt));
                        break;

                    case "process-ps-progress":
                        monitor.SetProgress(double.Parse(txt));
                        break;

                    case "process-ps-log":
                        monitor.Log(Decode(txt));
                        break;

                    case "process-ps-warning":
                        monitor.ReportWarning(Decode(txt));
                        break;

                    case "process-ps-exception":
                        exceptionText = Decode(txt);
                        if (exceptionText == string.Empty)
                        {
                            exceptionText = null;
                        }
                        break;

                    case "process-ps-error":
                        string err = Decode(txt);
                        if (err == string.Empty)
                        {
                            err = null;
                        }
                        monitor.ReportError(err, exceptionText != null ? new Exception(exceptionText) : null);
                        break;

                    case "process-ps-cancel":
                        monitor.Cancel();
                        break;

                    case "process-ps-plog":
                        progessLog.Add(Decode(txt));
                        break;

                    default:
                        wasTag = false;
                        break;
                    }
                    if (wasTag)
                    {
                        continue;
                    }
                }
                Console.WriteLine(line);
            }
        }
        bool ScanDescription(IProgressStatus monitor, AddinDescription config, Assembly rootAssembly, AddinScanResult scanResult)
        {
            // First of all scan the main module

            ArrayList assemblies           = new ArrayList();
            ArrayList hostExtensionClasses = new ArrayList();

            try {
                foreach (string s in config.MainModule.Assemblies)
                {
                    string   asmFile = Path.Combine(config.BasePath, s);
                    Assembly asm     = Util.LoadAssemblyForReflection(asmFile);
                    assemblies.Add(asm);
                }

                foreach (Assembly asm in assemblies)
                {
                    ScanAssemblyAddinHeaders(config, asm, scanResult);
                }

                // The add-in id and version must be already assigned at this point

                // Clean host data from the index. New data will be added.
                if (scanResult.HostIndex != null)
                {
                    scanResult.HostIndex.RemoveHostData(config.AddinId, config.AddinFile);
                }

                foreach (Assembly asm in assemblies)
                {
                    ScanAssemblyContents(config, asm, hostExtensionClasses, scanResult);
                }

                if (config.IsRoot && scanResult.HostIndex != null)
                {
                    // If the add-in is a root, register its assemblies
                    foreach (Assembly asm in assemblies)
                    {
                        string asmFile = new Uri(asm.CodeBase).LocalPath;
                        scanResult.HostIndex.RegisterAssembly(asmFile, config.AddinId, config.AddinFile);
                    }
                }
            } catch (Exception ex) {
                if (monitor.VerboseLog)
                {
                    monitor.Log("Could not load some add-in assemblies: " + ex.Message);
                }
                scanResult.AddFileToWithFailure(config.AddinFile);
                return(false);
            }

            foreach (Type t in hostExtensionClasses)
            {
                RegisterHostTypeNode(config, t, assemblies);
            }

            // Extension node types may have child nodes declared as attributes. Find them.

            Hashtable internalNodeSets = new Hashtable();

            foreach (ExtensionNodeSet eset in config.ExtensionNodeSets)
            {
                ScanNodeSet(config, eset, assemblies, internalNodeSets);
            }

            foreach (ExtensionPoint ep in config.ExtensionPoints)
            {
                ScanNodeSet(config, ep.NodeSet, assemblies, internalNodeSets);
            }

            // Now scan all modules

            if (!config.IsRoot)
            {
                foreach (ModuleDescription mod in config.OptionalModules)
                {
                    try {
                        assemblies.Clear();
                        foreach (string s in mod.Assemblies)
                        {
                            string   asmFile = Path.Combine(config.BasePath, s);
                            Assembly asm     = Util.LoadAssemblyForReflection(asmFile);
                            assemblies.Add(asm);
                        }
                        foreach (Assembly asm in assemblies)
                        {
                            ScanAssemblyContents(config, asm, null, scanResult);
                        }

                        if (config.IsRoot && scanResult.HostIndex != null)
                        {
                            // If the add-in is a root, register its assemblies
                            foreach (Assembly asm in assemblies)
                            {
                                string asmFile = new Uri(asm.CodeBase).LocalPath;
                                scanResult.HostIndex.RegisterAssembly(asmFile, config.AddinId, config.AddinFile);
                            }
                        }
                    } catch (Exception ex) {
                        if (monitor.VerboseLog)
                        {
                            monitor.Log("Could not load some add-in assemblies: " + ex.Message);
                        }
                        scanResult.AddFileToWithFailure(config.AddinFile);
                    }
                }
            }

            return(true);
        }
		void GenerateAddinExtensionMapsInternal (IProgressStatus monitor, ArrayList addinsToUpdate, ArrayList removedAddins)
		{
			AddinUpdateData updateData = new AddinUpdateData (this);
			
			// Clear cached data
			cachedAddinSetupInfos.Clear ();
			
			// Collect all information
			
			Hashtable addinHash = new Hashtable ();
			
			relExtensionPoints = 0;
			relExtensions = 0;
			relNodeSetTypes = 0;
			relExtensionNodes = 0;
		
			if (monitor.VerboseLog)
				monitor.Log ("Generating add-in extension maps");
			
			Hashtable changedAddins = null;
			ArrayList descriptionsToSave = new ArrayList ();
			ArrayList files = new ArrayList ();
			
			bool partialGeneration = addinsToUpdate != null;
			
			// Get the files to be updated
			
			if (partialGeneration) {
				changedAddins = new Hashtable ();
				foreach (string s in addinsToUpdate) {
					changedAddins [s] = s;
					string mp = GetDescriptionPath (s);
					if (fileDatabase.Exists (mp))
						files.Add (mp);
					else
						files.AddRange (fileDatabase.GetObjectSharedFiles (this.AddinCachePath, s, ".mroot"));
				}
				foreach (string s in removedAddins)
					changedAddins [s] = s;
			}
			else {
				files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.maddin"));
				files.AddRange (fileDatabase.GetDirectoryFiles (AddinCachePath, "*.mroot"));
			}
			
			// Load the descriptions.
			foreach (string file in files) {
			
				AddinDescription conf;
				if (!ReadAddinDescription (monitor, file, out conf)) {
					SafeDelete (monitor, file);
					continue;
				}

				// If the original file does not exist, the description can be deleted
				if (!File.Exists (conf.AddinFile)) {
					SafeDelete (monitor, file);
					continue;
				}
				
				// Remove old data from the description. If changedAddins==null, removes all data.
				// Otherwise, removes data only from the addins in the table.
				
				conf.UnmergeExternalData (changedAddins);
				descriptionsToSave.Add (conf);
				
				// Register extension points and node sets from root add-ins
				if (conf.IsRoot) {
					foreach (ExtensionPoint ep in conf.ExtensionPoints)
						updateData.RegisterAddinRootExtensionPoint (conf, ep);
					foreach (ExtensionNodeSet ns in conf.ExtensionNodeSets)
						updateData.RegisterAddinRootNodeSet (conf, ns);
				}
				else
					addinHash [conf.AddinId] = conf;
			}
			
			foreach (AddinDescription conf in addinHash.Values) {
				CollectExtensionData (conf, updateData);
			}
			
			updateData.ResolveExtensions (monitor, addinHash);
			
			// Update the extension points defined by this add-in			
			foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionPoints ()) {
				AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
				ExtensionPoint amep = am.ExtensionPoints [ep.Path];
				if (amep != null) {
					amep.MergeWith (am.AddinId, ep);
					amep.RootAddin = ep.RootAddin;
				}
			}

			// Now update the node sets
			foreach (ExtensionPoint ep in updateData.GetUnresolvedExtensionSets ()) {
				AddinDescription am = (AddinDescription) addinHash [ep.RootAddin];
				ExtensionNodeSet nset = am.ExtensionNodeSets [ep.Path];
				if (nset != null)
					nset.MergeWith (am.AddinId, ep.NodeSet);
			}
			
			// Save the maps
			foreach (AddinDescription conf in descriptionsToSave)
				conf.SaveBinary (fileDatabase);
			
			if (monitor.VerboseLog) {
				monitor.Log ("Addin relation map generated.");
				monitor.Log ("  Addins Updated: " + descriptionsToSave.Count);
				monitor.Log ("  Extension points: " + relExtensionPoints);
				monitor.Log ("  Extensions: " + relExtensions);
				monitor.Log ("  Extension nodes: " + relExtensionNodes);
				monitor.Log ("  Node sets: " + relNodeSetTypes);
			}
		}
Ejemplo n.º 11
0
        string BuildPackageInternal(IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath, PackageFormat format)
        {
            AddinDescription conf = registry.GetAddinDescription(monitor, filePath);

            if (conf == null)
            {
                monitor.ReportError("Could not read add-in file: " + filePath, null);
                return(null);
            }

            string basePath = Path.GetDirectoryName(Path.GetFullPath(filePath));

            if (targetDirectory == null)
            {
                targetDirectory = basePath;
            }

            // Generate the file name

            string name;

            if (conf.LocalId.Length == 0)
            {
                name = Path.GetFileNameWithoutExtension(filePath);
            }
            else
            {
                name = conf.LocalId;
            }
            name = Addin.GetFullId(conf.Namespace, name, conf.Version);
            name = name.Replace(',', '_').Replace(".__", ".");

            string outFilePath = Path.Combine(targetDirectory, name);

            switch (format)
            {
            case PackageFormat.Mpack:
                outFilePath += ".mpack";
                break;

            case PackageFormat.Vsix:
                outFilePath += ".vsix";
                break;

            default:
                throw new NotSupportedException(format.ToString());
            }

            ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath));

            s.SetLevel(5);

            if (format == PackageFormat.Vsix)
            {
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = false;
                doc.LoadXml(conf.SaveToVsixXml().OuterXml);
                MemoryStream  ms = new MemoryStream();
                XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
                tw.Formatting = Formatting.Indented;
                doc.WriteTo(tw);
                tw.Flush();
                byte [] data = ms.ToArray();

                var infoEntry = new ZipEntry("extension.vsixmanifest")
                {
                    Size = data.Length
                };
                s.PutNextEntry(infoEntry);
                s.Write(data, 0, data.Length);
                s.CloseEntry();
            }

            // Generate a stripped down description of the add-in in a file, since the complete
            // description may be declared as assembly attributes

            if (format == PackageFormat.Mpack || format == PackageFormat.Vsix)
            {
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = false;
                doc.LoadXml(conf.SaveToXml().OuterXml);
                CleanDescription(doc.DocumentElement);
                MemoryStream  ms = new MemoryStream();
                XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
                tw.Formatting = Formatting.Indented;
                doc.WriteTo(tw);
                tw.Flush();
                byte [] data = ms.ToArray();

                var infoEntry = new ZipEntry("addin.info")
                {
                    Size = data.Length
                };
                s.PutNextEntry(infoEntry);
                s.Write(data, 0, data.Length);
                s.CloseEntry();
            }

            // Now add the add-in files

            var files = new HashSet <string> ();

            files.Add(Path.GetFileName(Util.NormalizePath(filePath)));

            foreach (string f in conf.AllFiles)
            {
                var file = Util.NormalizePath(f);
                files.Add(file);
                if (debugSymbols)
                {
                    if (File.Exists(Path.ChangeExtension(file, ".pdb")))
                    {
                        files.Add(Path.ChangeExtension(file, ".pdb"));
                    }
                    else if (File.Exists(file + ".mdb"))
                    {
                        files.Add(file + ".mdb");
                    }
                }
            }

            foreach (var prop in conf.Properties)
            {
                try {
                    var file = Util.NormalizePath(prop.Value);
                    if (File.Exists(Path.Combine(basePath, file)))
                    {
                        files.Add(file);
                    }
                } catch {
                    // Ignore errors
                }
            }

            //add satellite assemblies for assemblies in the list
            var satelliteFinder = new SatelliteAssemblyFinder();

            foreach (var f in files.ToList())
            {
                foreach (var satellite in satelliteFinder.FindSatellites(Path.Combine(basePath, f)))
                {
                    var relativeSatellite = satellite.Substring(basePath.Length + 1);
                    files.Add(relativeSatellite);
                }
            }

            monitor.Log("Creating package " + Path.GetFileName(outFilePath));

            foreach (string file in files)
            {
                string fp = Path.Combine(basePath, file);
                using (FileStream fs = File.OpenRead(fp)) {
                    byte[] buffer = new byte [fs.Length];
                    fs.Read(buffer, 0, buffer.Length);

                    var fileName = Path.DirectorySeparatorChar == '\\' ? file.Replace('\\', '/') : file;
                    var entry    = new ZipEntry(fileName)
                    {
                        Size = fs.Length
                    };
                    s.PutNextEntry(entry);
                    s.Write(buffer, 0, buffer.Length);
                    s.CloseEntry();
                }
            }

            if (format == PackageFormat.Vsix)
            {
                files.Add("addin.info");
                files.Add("extension.vsixmanifest");
                XmlDocument doc = new XmlDocument();
                doc.PreserveWhitespace = false;
                XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
                XmlElement     root           = doc.DocumentElement;
                doc.InsertBefore(xmlDeclaration, root);
                HashSet <string> alreadyAddedExtensions = new HashSet <string> ();
                var typesEl = doc.CreateElement("Types");
                typesEl.SetAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/content-types");
                foreach (var file in files)
                {
                    var extension = Path.GetExtension(file);
                    if (string.IsNullOrEmpty(extension))
                    {
                        continue;
                    }
                    if (extension.StartsWith(".", StringComparison.Ordinal))
                    {
                        extension = extension.Substring(1);
                    }
                    if (alreadyAddedExtensions.Contains(extension))
                    {
                        continue;
                    }
                    alreadyAddedExtensions.Add(extension);
                    var typeEl = doc.CreateElement("Default");
                    typeEl.SetAttribute("Extension", extension);
                    typeEl.SetAttribute("ContentType", GetContentType(extension));
                    typesEl.AppendChild(typeEl);
                }
                doc.AppendChild(typesEl);
                MemoryStream  ms = new MemoryStream();
                XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
                tw.Formatting = Formatting.Indented;
                doc.WriteTo(tw);
                tw.Flush();
                byte [] data = ms.ToArray();

                var infoEntry = new ZipEntry("[Content_Types].xml")
                {
                    Size = data.Length
                };
                s.PutNextEntry(infoEntry);
                s.Write(data, 0, data.Length);
                s.CloseEntry();
            }

            s.Finish();
            s.Close();
            return(outFilePath);
        }
		void GenerateAddinExtensionMapsInternal (IProgressStatus monitor, ArrayList addinsToUpdate, ArrayList removedAddins)
		{
			AddinUpdateData updateData = new AddinUpdateData (this, monitor);
			
			// Clear cached data
			cachedAddinSetupInfos.Clear ();
			
			// Collect all information
			
			AddinIndex addinHash = new AddinIndex ();
			
			if (monitor.LogLevel > 1)
				monitor.Log ("Generating add-in extension maps");
			
			Hashtable changedAddins = null;
			ArrayList descriptionsToSave = new ArrayList ();
			ArrayList files = new ArrayList ();
			
			bool partialGeneration = addinsToUpdate != null;
			string[] domains = GetDomains ();
			
			// Get the files to be updated
			
			if (partialGeneration) {
				changedAddins = new Hashtable ();
				foreach (string sa in addinsToUpdate) {
					changedAddins [sa] = sa;
					
					// Look for all versions of the add-in, because this id may be the id of a reference,
					// and the exact reference version may not be installed.
					string s = sa;
					int i = s.LastIndexOf (',');
					if (i != -1)
						s = s.Substring (0, i);
					s += ",*";
					
					// Look for the add-in in any of the existing folders
					foreach (string domain in domains) {
						string mp = GetDescriptionPath (domain, s);
						string dir = Path.GetDirectoryName (mp);
						string pat = Path.GetFileName (mp);
						foreach (string fmp in fileDatabase.GetDirectoryFiles (dir, pat)) {
							if (files.Contains (fmp))
								continue;
							files.Add (fmp);
							string an = Path.GetFileNameWithoutExtension (fmp);
							changedAddins [an] = an;
						}
					}
				}
				foreach (string s in removedAddins)
					changedAddins [s] = s;
			}
			else {
				foreach (string dom in domains)
					files.AddRange (fileDatabase.GetDirectoryFiles (Path.Combine (AddinCachePath, dom), "*.maddin"));
			}
			
			// Load the descriptions.
			foreach (string file in files) {
			
				AddinDescription conf;
				if (!ReadAddinDescription (monitor, file, out conf)) {
					SafeDelete (monitor, file);
					continue;
				}

				// If the original file does not exist, the description can be deleted
				if (!File.Exists (conf.AddinFile)) {
					SafeDelete (monitor, file);
					continue;
				}
				
				// Remove old data from the description. If changedAddins==null, removes all data.
				// Otherwise, removes data only from the addins in the table.
				
				conf.UnmergeExternalData (changedAddins);
				descriptionsToSave.Add (conf);
				
				addinHash.Add (conf);
			}

			// Sort the add-ins, to make sure add-ins are processed before
			// all their dependencies
			ArrayList sorted = addinHash.GetSortedAddins ();

			// Register extension points and node sets
			foreach (AddinDescription conf in sorted)
				CollectExtensionPointData (conf, updateData);
			
			// Register extensions
			foreach (AddinDescription conf in sorted)
				CollectExtensionData (conf, updateData);
			
			// Save the maps
			foreach (AddinDescription conf in descriptionsToSave)
				conf.SaveBinary (fileDatabase);
			
			if (monitor.LogLevel > 1) {
				monitor.Log ("Addin relation map generated.");
				monitor.Log ("  Addins Updated: " + descriptionsToSave.Count);
				monitor.Log ("  Extension points: " + updateData.RelExtensionPoints);
				monitor.Log ("  Extensions: " + updateData.RelExtensions);
				monitor.Log ("  Extension nodes: " + updateData.RelExtensionNodes);
				monitor.Log ("  Node sets: " + updateData.RelNodeSetTypes);
			}
		}
Ejemplo n.º 13
0
        void ReportReflectionException(IProgressStatus monitor, Exception ex, AddinDescription config, AddinScanResult scanResult)
        {
            scanResult.AddFileToWithFailure (config.AddinFile);
            monitor.ReportWarning ("[" + config.AddinId + "] Could not load some add-in assemblies: " + ex.Message);
            if (monitor.LogLevel <= 1)
                return;

            ReflectionTypeLoadException rex = ex as ReflectionTypeLoadException;
            if (rex != null) {
                foreach (Exception e in rex.LoaderExceptions)
                    monitor.Log ("Load exception: " + e);
            }
        }
Ejemplo n.º 14
0
        bool RemoveAddinDescriptionFile(IProgressStatus monitor, string file)
        {
            // Removes an add-in description and shifts up alternate instances of the description file
            // (so xxx,1.0.maddin_2 will become xxx,1.0.maddin, xxx,1.0.maddin_3 -> xxx,1.0.maddin_2, etc)

            if (!SafeDelete (monitor, file))
                return false;

            int dversion;
            if (file.EndsWith (".maddin"))
                dversion = 2;
            else {
                int i = file.LastIndexOf ('_');
                dversion = 1 + int.Parse (file.Substring (i + 1));
                file = file.Substring (0, i);
            }

            while (fileDatabase.Exists (file + "_" + dversion)) {
                string newFile = dversion == 2 ? file : file + "_" + (dversion-1);
                try {
                    fileDatabase.Rename (file + "_" + dversion, newFile);
                } catch (Exception ex) {
                    if (monitor.LogLevel > 1) {
                        monitor.Log ("Could not rename file '" + file + "_" + dversion + "' to '" + newFile + "'");
                        monitor.Log (ex.ToString ());
                    }
                }
                dversion++;
            }
            string dir = Path.GetDirectoryName (file);
            if (fileDatabase.DirectoryIsEmpty (dir))
                SafeDeleteDir (monitor, dir);

            if (dversion == 2) {
                // All versions of the add-in removed.
                SafeDeleteDir (monitor, Path.Combine (AddinPrivateDataPath, Path.GetFileNameWithoutExtension (file)));
            }

            return true;
        }
Ejemplo n.º 15
0
        void RunScannerProcess(IProgressStatus monitor)
        {
            ISetupHandler setup = GetSetupHandler ();

            IProgressStatus scanMonitor = monitor;
            ArrayList pparams = new ArrayList ();

            bool retry = false;
            do {
                try {
                    if (monitor.LogLevel > 1)
                        monitor.Log ("Looking for addins");
                    setup.Scan (scanMonitor, registry, null, (string[]) pparams.ToArray (typeof(string)));
                    retry = false;
                }
                catch (Exception ex) {
                    ProcessFailedException pex = ex as ProcessFailedException;
                    if (pex != null) {
                        // Get the last logged operation.
                        if (pex.LastLog.StartsWith ("scan:")) {
                            // It crashed while scanning a file. Add the file to the ignore list and try again.
                            string file = pex.LastLog.Substring (5);
                            pparams.Add (file);
                            monitor.ReportWarning ("Could not scan file: " + file);
                            retry = true;
                            continue;
                        }
                    }
                    fatalDatabseError = true;
                    // If the process has crashed, try to do a new scan, this time using verbose log,
                    // to give the user more information about the origin of the crash.
                    if (pex != null && !retry) {
                        monitor.ReportError ("Add-in scan operation failed. The runtime may have encountered an error while trying to load an assembly.", null);
                        if (monitor.LogLevel <= 1) {
                            // Re-scan again using verbose log, to make it easy to find the origin of the error.
                            retry = true;
                            scanMonitor = new ConsoleProgressStatus (true);
                        }
                    } else
                        retry = false;

                    if (!retry) {
                        var pfex = ex as ProcessFailedException;
                        monitor.ReportError ("Add-in scan operation failed", pfex != null? pfex.InnerException : ex);
                        monitor.Cancel ();
                        return;
                    }
                }
            }
            while (retry);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Packages an add-in
        /// </summary>
        /// <param name="statusMonitor">
        /// Progress monitor where to show progress status
        /// </param>
        /// <param name="targetDirectory">
        /// Directory where to generate the package
        /// </param>
        /// <param name="filePaths">
        /// Paths to the add-ins to be packaged. Paths can be either the main assembly of an add-in, or an add-in
        /// manifest (.addin or .addin.xml).
        /// </param>
        /// <remarks>
        /// This method can be used to create a package for an add-in, which can then be pushed to an on-line
        /// repository. The package will include the main assembly or manifest of the add-in and any external
        /// file declared in the add-in metadata.
        /// </remarks>
        public void BuildPackage(IProgressStatus monitor, string outFilePath, string filePath)
        {
            AddinDescription conf = registry.GetAddinDescription (monitor, filePath);
            if (conf == null) {
                monitor.ReportError ("Could not read add-in file: " + filePath, null);
                return;
            }

            var basePath = Path.GetDirectoryName(outFilePath);

            ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath));
            s.SetLevel(5);

            // Generate a stripped down description of the add-in in a file, since the complete
            // description may be declared as assembly attributes

            XmlDocument doc = new XmlDocument ();
            doc.PreserveWhitespace = false;
            doc.LoadXml (conf.SaveToXml ().OuterXml);
            CleanDescription (doc.DocumentElement);
            MemoryStream ms = new MemoryStream ();
            XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
            tw.Formatting = Formatting.Indented;
            doc.WriteTo (tw);
            tw.Flush ();
            byte[] data = ms.ToArray ();

            ZipEntry infoEntry = new ZipEntry ("addin.info");
            s.PutNextEntry (infoEntry);
            s.Write (data, 0, data.Length);

            // Now add the add-in files

            ArrayList list = new ArrayList ();
            if (!conf.AllFiles.Contains (Path.GetFileName (filePath)))
                list.Add (Path.GetFileName (filePath));
            foreach (string f in conf.AllFiles) {
                list.Add (f);
            }

            foreach (var prop in conf.Properties) {
                try {
                    if (File.Exists (Path.Combine (basePath, prop.Value)))
                        list.Add (prop.Value);
                } catch {
                    // Ignore errors
                }
            }

            monitor.Log ("Creating package " + Path.GetFileName (outFilePath));

            foreach (string file in list) {
                string fp = Path.Combine (basePath, file);
                using (FileStream fs = File.OpenRead (fp)) {
                    byte[] buffer = new byte [fs.Length];
                    fs.Read (buffer, 0, buffer.Length);

                    ZipEntry entry = new ZipEntry (file);
                    s.PutNextEntry (entry);
                    s.Write (buffer, 0, buffer.Length);
                }
            }

            s.Finish();
            s.Close();
        }
Ejemplo n.º 17
0
        string BuildPackageInternal(IProgressStatus monitor, string targetDirectory, string filePath)
        {
            AddinDescription conf = registry.GetAddinDescription(monitor, filePath);

            if (conf == null)
            {
                monitor.ReportError("Could not read add-in file: " + filePath, null);
                return(null);
            }

            string basePath = Path.GetDirectoryName(filePath);

            if (targetDirectory == null)
            {
                targetDirectory = basePath;
            }

            // Generate the file name

            string name;

            if (conf.LocalId.Length == 0)
            {
                name = Path.GetFileNameWithoutExtension(filePath);
            }
            else
            {
                name = conf.LocalId;
            }
            name = Addin.GetFullId(conf.Namespace, name, conf.Version);
            name = name.Replace(',', '_').Replace(".__", ".");

            string outFilePath = Path.Combine(targetDirectory, name) + ".mpack";

            ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath));

            s.SetLevel(5);

            // Generate a stripped down description of the add-in in a file, since the complete
            // description may be declared as assembly attributes

            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = false;
            doc.LoadXml(conf.SaveToXml().OuterXml);
            CleanDescription(doc.DocumentElement);
            MemoryStream  ms = new MemoryStream();
            XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);

            tw.Formatting = Formatting.Indented;
            doc.WriteTo(tw);
            tw.Flush();
            byte[] data = ms.ToArray();

            ZipEntry infoEntry = new ZipEntry("addin.info");

            s.PutNextEntry(infoEntry);
            s.Write(data, 0, data.Length);

            // Now add the add-in files

            ArrayList list = new ArrayList();

            if (!conf.AllFiles.Contains(Path.GetFileName(filePath)))
            {
                list.Add(Path.GetFileName(filePath));
            }
            foreach (string f in conf.AllFiles)
            {
                list.Add(f);
            }

            foreach (var prop in conf.Properties)
            {
                try {
                    if (File.Exists(Path.Combine(basePath, prop.Value)))
                    {
                        list.Add(prop.Value);
                    }
                } catch {
                    // Ignore errors
                }
            }

            monitor.Log("Creating package " + Path.GetFileName(outFilePath));

            foreach (string file in list)
            {
                string fp = Path.Combine(basePath, file);
                using (FileStream fs = File.OpenRead(fp)) {
                    byte[] buffer = new byte [fs.Length];
                    fs.Read(buffer, 0, buffer.Length);

                    ZipEntry entry = new ZipEntry(file);
                    s.PutNextEntry(entry);
                    s.Write(buffer, 0, buffer.Length);
                }
            }

            s.Finish();
            s.Close();
            return(outFilePath);
        }
Ejemplo n.º 18
0
        string BuildPackageInternal(IProgressStatus monitor, bool debugSymbols, string targetDirectory, string filePath)
        {
            AddinDescription conf = registry.GetAddinDescription(monitor, filePath);

            if (conf == null)
            {
                monitor.ReportError("Could not read add-in file: " + filePath, null);
                return(null);
            }

            string basePath = Path.GetDirectoryName(Path.GetFullPath(filePath));

            if (targetDirectory == null)
            {
                targetDirectory = basePath;
            }

            // Generate the file name

            string name;

            if (conf.LocalId.Length == 0)
            {
                name = Path.GetFileNameWithoutExtension(filePath);
            }
            else
            {
                name = conf.LocalId;
            }
            name = Addin.GetFullId(conf.Namespace, name, conf.Version);
            name = name.Replace(',', '_').Replace(".__", ".");

            string outFilePath = Path.Combine(targetDirectory, name) + ".mpack";

            ZipOutputStream s = new ZipOutputStream(File.Create(outFilePath));

            s.SetLevel(5);

            // Generate a stripped down description of the add-in in a file, since the complete
            // description may be declared as assembly attributes

            XmlDocument doc = new XmlDocument();

            doc.PreserveWhitespace = false;
            doc.LoadXml(conf.SaveToXml().OuterXml);
            CleanDescription(doc.DocumentElement);
            MemoryStream  ms = new MemoryStream();
            XmlTextWriter tw = new XmlTextWriter(ms, System.Text.Encoding.UTF8);

            tw.Formatting = Formatting.Indented;
            doc.WriteTo(tw);
            tw.Flush();
            byte[] data = ms.ToArray();

            var infoEntry = new ZipEntry("addin.info")
            {
                Size = data.Length
            };

            s.PutNextEntry(infoEntry);
            s.Write(data, 0, data.Length);
            s.CloseEntry();

            // Now add the add-in files

            var files = new HashSet <string> ();

            files.Add(Path.GetFileName(Util.NormalizePath(filePath)));

            foreach (string f in conf.AllFiles)
            {
                var file = Util.NormalizePath(f);
                files.Add(file);
                if (debugSymbols)
                {
                    if (File.Exists(Path.ChangeExtension(file, ".pdb")))
                    {
                        files.Add(Path.ChangeExtension(file, ".pdb"));
                    }
                    else if (File.Exists(file + ".mdb"))
                    {
                        files.Add(file + ".mdb");
                    }
                }
            }

            foreach (var prop in conf.Properties)
            {
                try {
                    var file = Util.NormalizePath(prop.Value);
                    if (File.Exists(Path.Combine(basePath, file)))
                    {
                        files.Add(file);
                    }
                } catch {
                    // Ignore errors
                }
            }

            //add satellite assemblies for assemblies in the list
            var satelliteFinder = new SatelliteAssemblyFinder();

            foreach (var f in files.ToList())
            {
                foreach (var satellite in satelliteFinder.FindSatellites(Path.Combine(basePath, f)))
                {
                    var relativeSatellite = satellite.Substring(basePath.Length + 1);
                    files.Add(relativeSatellite);
                }
            }

            monitor.Log("Creating package " + Path.GetFileName(outFilePath));

            foreach (string file in files)
            {
                string fp = Path.Combine(basePath, file);
                using (FileStream fs = File.OpenRead(fp)) {
                    byte[] buffer = new byte [fs.Length];
                    fs.Read(buffer, 0, buffer.Length);

                    var fileName = Path.PathSeparator == '\\' ? file.Replace('\\', '/') : file;
                    var entry    = new ZipEntry(fileName)
                    {
                        Size = fs.Length
                    };
                    s.PutNextEntry(entry);
                    s.Write(buffer, 0, buffer.Length);
                    s.CloseEntry();
                }
            }

            s.Finish();
            s.Close();
            return(outFilePath);
        }
 void WriteLog(string text)
 {
     status.Log(text);
 }
Ejemplo n.º 20
0
		public void ScanFolder (IProgressStatus monitor, string path, AddinScanResult scanResult)
		{
			path = Util.GetFullPath (path);
			
			// Avoid folders including each other
			if (!scanResult.VisitFolder (path))
				return;
			
			if (monitor.VerboseLog && !scanResult.LocateAssembliesOnly)
				monitor.Log ("Checking: " + path);
			
			AddinScanFolderInfo folderInfo;
			if (!database.GetFolderInfoForPath (monitor, path, out folderInfo)) {
				// folderInfo file was corrupt.
				// Just in case, we are going to regenerate all relation data.
				if (!Directory.Exists (path))
					scanResult.RegenerateRelationData = true;
			} else {
				if (folderInfo == null && !Directory.Exists (path))
					return;
			}
			
			if (folderInfo == null)
				folderInfo = new AddinScanFolderInfo (path);
			
			if (Directory.Exists (path))
			{
				foreach (string file in Directory.GetFiles (path)) {
					if (file.EndsWith (".addin.xml")) {
						RegisterFileToScan (monitor, file, scanResult, folderInfo);
						continue;
					}
					switch (Path.GetExtension (file)) {
					case ".dll":
					case ".exe":
						RegisterFileToScan (monitor, file, scanResult, folderInfo);
						scanResult.AddAssemblyLocation (file);
						break;
					case ".addin":
						RegisterFileToScan (monitor, file, scanResult, folderInfo);
						break;
					case ".addins":
						ScanAddinsFile (monitor, file, scanResult);
						break;
					}
				}
			}
			else if (!scanResult.LocateAssembliesOnly) {
				// The folder has been deleted. All add-ins defined in that folder should also be deleted.
				scanResult.RegenerateRelationData = true;
				scanResult.ChangesFound = true;
				if (scanResult.CheckOnly)
					return;
				database.DeleteFolderInfo (monitor, folderInfo);
			}
			
			if (scanResult.LocateAssembliesOnly)
				return;
			
			// Look for deleted add-ins.
			
			UpdateDeletedAddins (monitor, folderInfo, scanResult);
		}
Ejemplo n.º 21
0
		bool ScanDescription (IProgressStatus monitor, AddinDescription config, Assembly rootAssembly, AddinScanResult scanResult)
		{
			// First of all scan the main module
			
			ArrayList assemblies = new ArrayList ();
			ArrayList hostExtensionClasses = new ArrayList ();
			
			try {
				foreach (string s in config.MainModule.Assemblies) {
					string asmFile = Path.Combine (config.BasePath, s);
					Assembly asm = Util.LoadAssemblyForReflection (asmFile);
					assemblies.Add (asm);
				}
				
				foreach (Assembly asm in assemblies)
					ScanAssemblyAddinHeaders (config, asm, scanResult);
				
				// The add-in id and version must be already assigned at this point
				
				// Clean host data from the index. New data will be added.
				if (scanResult.HostIndex != null)
					scanResult.HostIndex.RemoveHostData (config.AddinId, config.AddinFile);

				foreach (Assembly asm in assemblies)
					ScanAssemblyContents (config, asm, hostExtensionClasses, scanResult);
				
				if (config.IsRoot && scanResult.HostIndex != null) {
					// If the add-in is a root, register its assemblies
					foreach (Assembly asm in assemblies) {
						string asmFile = new Uri (asm.CodeBase).LocalPath;
						scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile);
					}
				}
				
			} catch (Exception ex) {
				if (monitor.VerboseLog)
					monitor.Log ("Could not load some add-in assemblies: " + ex.Message);
				scanResult.AddFileToWithFailure (config.AddinFile);
				return false;
			}
			
			foreach (Type t in hostExtensionClasses) {
				RegisterHostTypeNode (config, t, assemblies);
			}
			
			// Extension node types may have child nodes declared as attributes. Find them.
			
			Hashtable internalNodeSets = new Hashtable ();
			
			foreach (ExtensionNodeSet eset in config.ExtensionNodeSets)
				ScanNodeSet (config, eset, assemblies, internalNodeSets);
			
			foreach (ExtensionPoint ep in config.ExtensionPoints) {
				ScanNodeSet (config, ep.NodeSet, assemblies, internalNodeSets);
			}
		
			// Now scan all modules
			
			if (!config.IsRoot) {
				foreach (ModuleDescription mod in config.OptionalModules) {
					try {
						assemblies.Clear ();
						foreach (string s in mod.Assemblies) {
							string asmFile = Path.Combine (config.BasePath, s);
							Assembly asm = Util.LoadAssemblyForReflection (asmFile);
							assemblies.Add (asm);
						}
						foreach (Assembly asm in assemblies)
							ScanAssemblyContents (config, asm, null, scanResult);
				
						if (config.IsRoot && scanResult.HostIndex != null) {
							// If the add-in is a root, register its assemblies
							foreach (Assembly asm in assemblies) {
								string asmFile = new Uri (asm.CodeBase).LocalPath;
								scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile);
							}
						}
						
					} catch (Exception ex) {
						if (monitor.VerboseLog)
							monitor.Log ("Could not load some add-in assemblies: " + ex.Message);
						scanResult.AddFileToWithFailure (config.AddinFile);
					}
				}
			}
			
			return true;
		}
Ejemplo n.º 22
0
		public void ScanFile (IProgressStatus monitor, string file, AddinScanFolderInfo folderInfo, AddinScanResult scanResult)
		{
			if (monitor.VerboseLog)
				monitor.Log ("Scanning file: " + file);
				
			string scannedAddinId = null;
			bool scannedIsRoot = false;
			bool scanSuccessful = false;
			
			try {
				string ext = Path.GetExtension (file);
				AddinDescription config = null;
				
				if (ext == ".dll" || ext == ".exe")
					scanSuccessful = ScanAssembly (monitor, file, scanResult, out config);
				else
					scanSuccessful = ScanConfigAssemblies (monitor, file, scanResult, out config);

				if (config != null) {
					
					AddinFileInfo fi = folderInfo.GetAddinFileInfo (file);
					
					// If version is not specified, make up one
					if (config.Version.Length == 0) {
						config.Version = "0.0.0.0";
					}
					
					if (config.LocalId.Length == 0) {
						// Generate an internal id for this add-in
						config.LocalId = database.GetUniqueAddinId (file, (fi != null ? fi.AddinId : null), config.Namespace, config.Version);
						config.HasUserId = false;
					}
					
					// Check errors in the description
					StringCollection errors = config.Verify ();
					
					if (database.IsGlobalRegistry && config.AddinId.IndexOf ('.') == -1) {
						errors.Add ("Add-ins registered in the global registry must have a namespace.");
					}
					    
					if (errors.Count > 0) {
						scanSuccessful = false;
						monitor.ReportError ("Errors found in add-in '" + file + ":", null);
						foreach (string err in errors)
							monitor.ReportError (err, null);
					}
				
					// Make sure all extensions sets are initialized with the correct add-in id
					
					config.SetExtensionsAddinId (config.AddinId);
					
					scanResult.ChangesFound = true;
					
					// If the add-in already existed, try to reuse the relation data it had.
					// Also, the dependencies of the old add-in need to be re-analized
					
					AddinDescription existingDescription = null;
					bool res;
					
					if (config.IsRoot)
						res = database.GetHostDescription (monitor, config.AddinId, config.AddinFile, out existingDescription);
					else
						res = database.GetAddinDescription (monitor, config.AddinId, out existingDescription);
					
					// If we can't get information about the old assembly, just regenerate all relation data
					if (!res)
						scanResult.RegenerateRelationData = true;
					
					string replaceFileName = null;
					
					if (existingDescription != null) {
						// Reuse old relation data
						config.MergeExternalData (existingDescription);
						Util.AddDependencies (existingDescription, scanResult);
						replaceFileName = existingDescription.FileName;
					}
					
					// If the scanned file results in an add-in version different from the one obtained from
					// previous scans, the old add-in needs to be uninstalled.
					if (fi != null && fi.AddinId != null && fi.AddinId != config.AddinId) {
						if (fi.IsRoot)
							database.UninstallRootAddin (monitor, fi.AddinId, file, scanResult);
						else
							database.UninstallAddin (monitor, fi.AddinId, scanResult);
						
						// If the add-in version has changed, regenerate everything again since old data can't be reused
						if (Addin.GetIdName (fi.AddinId) == Addin.GetIdName (config.AddinId))
							scanResult.RegenerateRelationData = true;
					}
					
					// If a description could be generated, save it now (if the scan was successful)
					if (scanSuccessful) {
						if (database.SaveDescription (monitor, config, replaceFileName)) {
							// The new dependencies also have to be updated
							Util.AddDependencies (config, scanResult);
							scanResult.AddAddinToUpdateRelations (config.AddinId);
							scannedAddinId = config.AddinId;
							scannedIsRoot = config.IsRoot;
							return;
						}
					}
				}
			}
			catch (Exception ex) {
				monitor.ReportError ("Unexpected error while scanning file: " + file, ex);
			}
			finally {
				folderInfo.SetLastScanTime (file, scannedAddinId, scannedIsRoot, File.GetLastWriteTime (file), !scanSuccessful);
			}
		}
Ejemplo n.º 23
0
        protected override void OnVisitFolder(IProgressStatus monitor, string path, string domain, bool recursive)
        {
            AddinScanFolderInfo folderInfo;

            if (!database.GetFolderInfoForPath(monitor, path, out folderInfo))
            {
                // folderInfo file was corrupt.
                // Just in case, we are going to regenerate all relation data.
                if (!FileSystem.DirectoryExists(path))
                {
                    scanResult.RegenerateRelationData = true;
                }
            }
            else
            {
                // Directory is included but it doesn't exist. Ignore it.
                if (folderInfo == null && !FileSystem.DirectoryExists(path))
                {
                    return;
                }
            }

            // if domain is null it means that a new domain has to be created.

            // Look for an add-in scan data index file. If it is present, it means the folder has been pre-scanned

            var dirScanDataIndex = AddinScanDataIndex.LoadFromFolder(monitor, path);

            if (dirScanDataIndex != null && scanResult.CleanGeneratedAddinScanDataFiles)
            {
                // Remove any existing dir.addindata if data is being generated
                dirScanDataIndex.Delete();
                dirScanDataIndex = null;
            }

            bool sharedFolder   = domain == AddinDatabase.GlobalDomain;
            bool isNewFolder    = folderInfo == null;
            bool folderHasIndex = dirScanDataIndex != null;

            if (isNewFolder)
            {
                // No folder info. It is the first time this folder is scanned.
                // There is no need to store this object if the folder does not
                // contain add-ins.
                folderInfo = new AddinScanFolderInfo(path);
                folderInfo.FolderHasScanDataIndex = folderHasIndex;
            }
            else if (folderInfo.FolderHasScanDataIndex != folderHasIndex)
            {
                // A scan data index appeared or disappeared. The information in folderInfo is not reliable.
                // Update the folder info and regenerate everything.
                scanResult.RegenerateRelationData = true;
                folderInfo.Reset();
                scanResult.RegisterModifiedFolderInfo(folderInfo);
                folderInfo.FolderHasScanDataIndex = folderHasIndex;
            }

            if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain))
            {
                // If the folder already has a domain, reuse it
                if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
                {
                    domain = folderInfo.RootsDomain;
                }
                else if (domain == null)
                {
                    folderInfo.Domain = domain = database.GetUniqueDomainId();
                    scanResult.RegenerateRelationData = true;
                }
                else
                {
                    folderInfo.Domain = domain;
                    if (!isNewFolder)
                    {
                        // Domain has changed. Update the folder info and regenerate everything.
                        scanResult.RegenerateRelationData = true;
                        scanResult.RegisterModifiedFolderInfo(folderInfo);
                    }
                }
            }
            else if (!folderInfo.SharedFolder && sharedFolder)
            {
                scanResult.RegenerateRelationData = true;
            }

            folderInfo.SharedFolder = sharedFolder;

            // If there is no domain assigned to the host, get one now
            if (scanResult.Domain == AddinDatabase.UnknownDomain)
            {
                scanResult.Domain = domain;
            }

            // Discard folders not belonging to the required domain
            if (scanResult.Domain != null && domain != scanResult.Domain && domain != AddinDatabase.GlobalDomain)
            {
                return;
            }

            if (monitor.LogLevel > 1)
            {
                monitor.Log("Checking: " + path);
            }

            if (dirScanDataIndex != null)
            {
                // Instead of scanning the folder, just register the files in the index
                foreach (var file in dirScanDataIndex.Files)
                {
                    RegisterFileToScan(monitor, file.FileName, folderInfo, file);
                }
                foreach (var file in dirScanDataIndex.Assemblies)
                {
                    scanResult.AssemblyIndex.AddAssemblyLocation(file);
                }
            }
            else
            {
                currentFolderInfo = folderInfo;

                base.OnVisitFolder(monitor, path, domain, recursive);

                if (!FileSystem.DirectoryExists(path))
                {
                    // The folder has been deleted. All add-ins defined in that folder should also be deleted.
                    scanResult.RegenerateRelationData = true;
                    scanResult.ChangesFound           = true;
                    if (scanResult.CheckOnly)
                    {
                        return;
                    }
                    database.DeleteFolderInfo(monitor, folderInfo);
                }
            }

            // Look for deleted add-ins.

            UpdateDeletedAddins(monitor, folderInfo);
        }
Ejemplo n.º 24
0
        public void ScanFile(IProgressStatus monitor, string file, AddinScanFolderInfo folderInfo, AddinScanResult scanResult)
        {
            if (scanResult.IgnorePath(file))
            {
                // The file must be ignored. Maybe it caused a crash in a previous scan, or it
                // might be included by a .addin file (in which case it will be scanned when processing
                // the .addin file).
                folderInfo.SetLastScanTime(file, null, false, File.GetLastWriteTime(file), true);
                return;
            }

            if (monitor.LogLevel > 1)
            {
                monitor.Log("Scanning file: " + file);
            }

            // Log the file to be scanned, so in case of a process crash the main process
            // will know what crashed
            monitor.Log("plog:scan:" + file);

            string           scannedAddinId = null;
            bool             scannedIsRoot  = false;
            bool             scanSuccessful = false;
            AddinDescription config         = null;

            try {
                string ext = Path.GetExtension(file);

                if (ext == ".dll" || ext == ".exe")
                {
                    scanSuccessful = ScanAssembly(monitor, file, scanResult, out config);
                }
                else
                {
                    scanSuccessful = ScanConfigAssemblies(monitor, file, scanResult, out config);
                }

                if (config != null)
                {
                    AddinFileInfo fi = folderInfo.GetAddinFileInfo(file);

                    // If version is not specified, make up one
                    if (config.Version.Length == 0)
                    {
                        config.Version = "0.0.0.0";
                    }

                    if (config.LocalId.Length == 0)
                    {
                        // Generate an internal id for this add-in
                        config.LocalId   = database.GetUniqueAddinId(file, (fi != null ? fi.AddinId : null), config.Namespace, config.Version);
                        config.HasUserId = false;
                    }

                    // Check errors in the description
                    StringCollection errors = config.Verify();

                    if (database.IsGlobalRegistry && config.AddinId.IndexOf('.') == -1)
                    {
                        errors.Add("Add-ins registered in the global registry must have a namespace.");
                    }

                    if (errors.Count > 0)
                    {
                        scanSuccessful = false;
                        monitor.ReportError("Errors found in add-in '" + file + ":", null);
                        foreach (string err in errors)
                        {
                            monitor.ReportError(err, null);
                        }
                    }

                    // Make sure all extensions sets are initialized with the correct add-in id

                    config.SetExtensionsAddinId(config.AddinId);

                    scanResult.ChangesFound = true;

                    // If the add-in already existed, try to reuse the relation data it had.
                    // Also, the dependencies of the old add-in need to be re-analized

                    AddinDescription existingDescription = null;
                    bool             res = database.GetAddinDescription(monitor, folderInfo.Domain, config.AddinId, out existingDescription);

                    // If we can't get information about the old assembly, just regenerate all relation data
                    if (!res)
                    {
                        scanResult.RegenerateRelationData = true;
                    }

                    string replaceFileName = null;

                    if (existingDescription != null)
                    {
                        // Reuse old relation data
                        config.MergeExternalData(existingDescription);
                        Util.AddDependencies(existingDescription, scanResult);
                        replaceFileName = existingDescription.FileName;
                    }

                    // If the scanned file results in an add-in version different from the one obtained from
                    // previous scans, the old add-in needs to be uninstalled.
                    if (fi != null && fi.IsAddin && fi.AddinId != config.AddinId)
                    {
                        database.UninstallAddin(monitor, folderInfo.Domain, fi.AddinId, scanResult);

                        // If the add-in version has changed, regenerate everything again since old data can't be reused
                        if (Addin.GetIdName(fi.AddinId) == Addin.GetIdName(config.AddinId))
                        {
                            scanResult.RegenerateRelationData = true;
                        }
                    }

                    // If a description could be generated, save it now (if the scan was successful)
                    if (scanSuccessful)
                    {
                        // Assign the domain
                        if (config.IsRoot)
                        {
                            if (folderInfo.RootsDomain == null)
                            {
                                if (scanResult.Domain != null && scanResult.Domain != AddinDatabase.UnknownDomain && scanResult.Domain != AddinDatabase.GlobalDomain)
                                {
                                    folderInfo.RootsDomain = scanResult.Domain;
                                }
                                else
                                {
                                    folderInfo.RootsDomain = database.GetUniqueDomainId();
                                }
                            }
                            config.Domain = folderInfo.RootsDomain;
                        }
                        else
                        {
                            config.Domain = folderInfo.Domain;
                        }

                        if (config.IsRoot && scanResult.HostIndex != null)
                        {
                            // If the add-in is a root, register its assemblies
                            foreach (string f in config.MainModule.Assemblies)
                            {
                                string asmFile = Path.Combine(config.BasePath, f);
                                scanResult.HostIndex.RegisterAssembly(asmFile, config.AddinId, config.AddinFile, config.Domain);
                            }
                        }

                        // Finally save

                        if (database.SaveDescription(monitor, config, replaceFileName))
                        {
                            // The new dependencies also have to be updated
                            Util.AddDependencies(config, scanResult);
                            scanResult.AddAddinToUpdateRelations(config.AddinId);
                            scannedAddinId = config.AddinId;
                            scannedIsRoot  = config.IsRoot;
                            return;
                        }
                    }
                }
            }
            catch (Exception ex) {
                monitor.ReportError("Unexpected error while scanning file: " + file, ex);
            }
            finally {
                AddinFileInfo ainfo = folderInfo.SetLastScanTime(file, scannedAddinId, scannedIsRoot, File.GetLastWriteTime(file), !scanSuccessful);

                if (scanSuccessful && config != null)
                {
                    // Update the ignore list in the folder info object. To be used in the next scan
                    foreach (string df in config.AllIgnorePaths)
                    {
                        string path = Path.Combine(config.BasePath, df);
                        ainfo.AddPathToIgnore(Util.GetFullPath(path));
                    }
                }

                monitor.Log("plog:endscan");
            }
        }
Ejemplo n.º 25
0
        void GenerateAddinExtensionMapsInternal(IProgressStatus monitor, string domain, List<string> addinsToUpdate, List<string> addinsToUpdateRelations, List<string> removedAddins)
        {
            AddinUpdateData updateData = new AddinUpdateData (this, monitor);

            // Clear cached data
            cachedAddinSetupInfos.Clear ();

            // Collect all information

            AddinIndex addinHash = new AddinIndex ();

            if (monitor.LogLevel > 1)
                monitor.Log ("Generating add-in extension maps");

            Hashtable changedAddins = null;
            ArrayList descriptionsToSave = new ArrayList ();
            ArrayList files = new ArrayList ();

            bool partialGeneration = addinsToUpdate != null;
            string[] domains = GetDomains ().Where (d => d == domain || d == GlobalDomain).ToArray ();

            // Get the files to be updated

            if (partialGeneration) {
                changedAddins = new Hashtable ();

                if (monitor.LogLevel > 2)
                    monitor.Log ("Doing a partial registry update.\nAdd-ins to be updated:");
                // Get the files and ids of all add-ins that have to be updated
                // Include removed add-ins: if there are several instances of the same add-in, removing one of
                // them will make other instances to show up. If there is a single instance, its files are
                // already removed.
                foreach (string sa in addinsToUpdate.Union (removedAddins)) {
                    changedAddins [sa] = sa;
                    if (monitor.LogLevel > 2)
                        monitor.Log (" - " + sa);
                    foreach (string file in GetAddinFiles (sa, domains)) {
                        if (!files.Contains (file)) {
                            files.Add (file);
                            string an = Path.GetFileNameWithoutExtension (file);
                            changedAddins [an] = an;
                            if (monitor.LogLevel > 2 && an != sa)
                                monitor.Log (" - " + an);
                        }
                    }
                }

                if (monitor.LogLevel > 2)
                    monitor.Log ("Add-ins whose relations have to be updated:");

                // Get the files and ids of all add-ins whose relations have to be updated
                foreach (string sa in addinsToUpdateRelations) {
                    foreach (string file in GetAddinFiles (sa, domains)) {
                        if (!files.Contains (file)) {
                            if (monitor.LogLevel > 2) {
                                string an = Path.GetFileNameWithoutExtension (file);
                                monitor.Log (" - " + an);
                            }
                            files.Add (file);
                        }
                    }
                }
            }
            else {
                foreach (var dom in domains)
                    files.AddRange (fileDatabase.GetDirectoryFiles (Path.Combine (AddinCachePath, dom), "*.maddin"));
            }

            // Load the descriptions.
            foreach (string file in files) {

                AddinDescription conf;
                if (!ReadAddinDescription (monitor, file, out conf)) {
                    SafeDelete (monitor, file);
                    continue;
                }

                // If the original file does not exist, the description can be deleted
                if (!fs.FileExists (conf.AddinFile)) {
                    SafeDelete (monitor, file);
                    continue;
                }

                // Remove old data from the description. Remove the data of the add-ins that
                // have changed. This data will be re-added later.

                conf.UnmergeExternalData (changedAddins);
                descriptionsToSave.Add (conf);

                addinHash.Add (conf);
            }

            // Sort the add-ins, to make sure add-ins are processed before
            // all their dependencies

            var sorted = addinHash.GetSortedAddins ();

            // Register extension points and node sets
            foreach (AddinDescription conf in sorted)
                CollectExtensionPointData (conf, updateData);

            if (monitor.LogLevel > 2)
                monitor.Log ("Registering new extensions:");

            // Register extensions
            foreach (AddinDescription conf in sorted) {
                if (changedAddins == null || changedAddins.ContainsKey (conf.AddinId)) {
                    if (monitor.LogLevel > 2)
                        monitor.Log ("- " + conf.AddinId + " (" + conf.Domain + ")");
                    CollectExtensionData (monitor, addinHash, conf, updateData);
                }
            }

            // Save the maps
            foreach (AddinDescription conf in descriptionsToSave) {
                ConsolidateExtensions (conf);
                conf.SaveBinary (fileDatabase);
            }

            if (monitor.LogLevel > 1) {
                monitor.Log ("Addin relation map generated.");
                monitor.Log ("  Addins Updated: " + descriptionsToSave.Count);
                monitor.Log ("  Extension points: " + updateData.RelExtensionPoints);
                monitor.Log ("  Extensions: " + updateData.RelExtensions);
                monitor.Log ("  Extension nodes: " + updateData.RelExtensionNodes);
                monitor.Log ("  Node sets: " + updateData.RelNodeSetTypes);
            }
        }
Ejemplo n.º 26
0
        public void ScanFile(IProgressStatus monitor, string file, AddinScanFolderInfo folderInfo, AddinScanResult scanResult)
        {
            if (scanResult.IgnorePath (file)) {
                // The file must be ignored. Maybe it caused a crash in a previous scan, or it
                // might be included by a .addin file (in which case it will be scanned when processing
                // the .addin file).
                folderInfo.SetLastScanTime (file, null, false, fs.GetLastWriteTime (file), true);
                return;
            }

            if (monitor.LogLevel > 1)
                monitor.Log ("Scanning file: " + file);

            // Log the file to be scanned, so in case of a process crash the main process
            // will know what crashed
            monitor.Log ("plog:scan:" + file);

            string scannedAddinId = null;
            bool scannedIsRoot = false;
            bool scanSuccessful = false;
            AddinDescription config = null;

            try {
                string ext = Path.GetExtension (file).ToLower ();

                if (ext == ".dll" || ext == ".exe")
                    scanSuccessful = ScanAssembly (monitor, file, scanResult, out config);
                else
                    scanSuccessful = ScanConfigAssemblies (monitor, file, scanResult, out config);

                if (config != null) {

                    AddinFileInfo fi = folderInfo.GetAddinFileInfo (file);

                    // If version is not specified, make up one
                    if (config.Version.Length == 0) {
                        config.Version = "0.0.0.0";
                    }

                    if (config.LocalId.Length == 0) {
                        // Generate an internal id for this add-in
                        config.LocalId = database.GetUniqueAddinId (file, (fi != null ? fi.AddinId : null), config.Namespace, config.Version);
                        config.HasUserId = false;
                    }

                    // Check errors in the description
                    StringCollection errors = config.Verify (fs);

                    if (database.IsGlobalRegistry && config.AddinId.IndexOf ('.') == -1) {
                        errors.Add ("Add-ins registered in the global registry must have a namespace.");
                    }

                    if (errors.Count > 0) {
                        scanSuccessful = false;
                        monitor.ReportError ("Errors found in add-in '" + file + ":", null);
                        foreach (string err in errors)
                            monitor.ReportError (err, null);
                    }

                    // Make sure all extensions sets are initialized with the correct add-in id

                    config.SetExtensionsAddinId (config.AddinId);

                    scanResult.ChangesFound = true;

                    // If the add-in already existed, try to reuse the relation data it had.
                    // Also, the dependencies of the old add-in need to be re-analized

                    AddinDescription existingDescription = null;
                    bool res = database.GetAddinDescription (monitor, folderInfo.Domain, config.AddinId, config.AddinFile, out existingDescription);

                    // If we can't get information about the old assembly, just regenerate all relation data
                    if (!res)
                        scanResult.RegenerateRelationData = true;

                    string replaceFileName = null;

                    if (existingDescription != null) {
                        // Reuse old relation data
                        config.MergeExternalData (existingDescription);
                        Util.AddDependencies (existingDescription, scanResult);
                        replaceFileName = existingDescription.FileName;
                    }

                    // If the scanned file results in an add-in version different from the one obtained from
                    // previous scans, the old add-in needs to be uninstalled.
                    if (fi != null && fi.IsAddin && fi.AddinId != config.AddinId) {
                        database.UninstallAddin (monitor, folderInfo.Domain, fi.AddinId, fi.File, scanResult);

                        // If the add-in version has changed, regenerate everything again since old data can't be reused
                        if (Addin.GetIdName (fi.AddinId) == Addin.GetIdName (config.AddinId))
                            scanResult.RegenerateRelationData = true;
                    }

                    // If a description could be generated, save it now (if the scan was successful)
                    if (scanSuccessful) {

                        // Assign the domain
                        if (config.IsRoot) {
                            if (folderInfo.RootsDomain == null) {
                                if (scanResult.Domain != null && scanResult.Domain != AddinDatabase.UnknownDomain && scanResult.Domain != AddinDatabase.GlobalDomain)
                                    folderInfo.RootsDomain = scanResult.Domain;
                                else
                                    folderInfo.RootsDomain = database.GetUniqueDomainId ();
                            }
                            config.Domain = folderInfo.RootsDomain;
                        } else
                            config.Domain = folderInfo.Domain;

                        if (config.IsRoot && scanResult.HostIndex != null) {
                            // If the add-in is a root, register its assemblies
                            foreach (string f in config.MainModule.Assemblies) {
                                string asmFile = Path.Combine (config.BasePath, f);
                                scanResult.HostIndex.RegisterAssembly (asmFile, config.AddinId, config.AddinFile, config.Domain);
                            }
                        }

                        // Finally save

                        if (database.SaveDescription (monitor, config, replaceFileName)) {
                            // The new dependencies also have to be updated
                            Util.AddDependencies (config, scanResult);
                            scanResult.AddAddinToUpdate (config.AddinId);
                            scannedAddinId = config.AddinId;
                            scannedIsRoot = config.IsRoot;
                            return;
                        }
                    }
                }
            }
            catch (Exception ex) {
                monitor.ReportError ("Unexpected error while scanning file: " + file, ex);
            }
            finally {
                AddinFileInfo ainfo = folderInfo.SetLastScanTime (file, scannedAddinId, scannedIsRoot, fs.GetLastWriteTime (file), !scanSuccessful);

                if (scanSuccessful && config != null) {
                    // Update the ignore list in the folder info object. To be used in the next scan
                    foreach (string df in config.AllIgnorePaths) {
                        string path = Path.Combine (config.BasePath, df);
                        ainfo.AddPathToIgnore (Path.GetFullPath (path));
                    }
                }

                monitor.Log ("plog:endscan");
            }
        }
Ejemplo n.º 27
0
        void RunPendingUninstalls(IProgressStatus monitor)
        {
            bool changesDone = false;

            foreach (var adn in Configuration.GetPendingUninstalls ()) {
                HashSet<string> files = new HashSet<string> (adn.Files);
                if (AddinManager.CheckAssembliesLoaded (files))
                    continue;

                if (monitor.LogLevel > 1)
                    monitor.Log ("Uninstalling " + adn.AddinId);

                // Make sure all files can be deleted before doing so
                bool canUninstall = true;
                foreach (string f in adn.Files) {
                    if (!File.Exists (f))
                        continue;
                    try {
                        File.OpenWrite (f).Close ();
                    } catch {
                        canUninstall = false;
                        break;
                    }
                }

                if (!canUninstall)
                    continue;

                foreach (string f in adn.Files) {
                    try {
                        if (File.Exists (f))
                            File.Delete (f);
                    } catch {
                        canUninstall = false;
                    }
                }

                if (canUninstall) {
                    Configuration.UnregisterForUninstall (adn.AddinId);
                    changesDone = true;
                }
            }
            if (changesDone)
                SaveConfiguration ();
        }
Ejemplo n.º 28
0
        public AddinDescription ScanSingleFile(IProgressStatus monitor, string file, AddinScanResult scanResult)
        {
            AddinDescription config = null;

            if (monitor.LogLevel > 1)
                monitor.Log ("Scanning file: " + file);

            monitor.Log ("plog:scan:" + file);

            try {
                string ext = Path.GetExtension (file).ToLower ();
                bool scanSuccessful;

                if (ext == ".dll" || ext == ".exe")
                    scanSuccessful = ScanAssembly (monitor, file, scanResult, out config);
                else
                    scanSuccessful = ScanConfigAssemblies (monitor, file, scanResult, out config);

                if (scanSuccessful && config != null) {

                    config.Domain = "global";
                    if (config.Version.Length == 0)
                        config.Version = "0.0.0.0";

                    if (config.LocalId.Length == 0) {
                        // Generate an internal id for this add-in
                        config.LocalId = database.GetUniqueAddinId (file, "", config.Namespace, config.Version);
                    }
                }
            }
            catch (Exception ex) {
                monitor.ReportError ("Unexpected error while scanning file: " + file, ex);
            } finally {
                monitor.Log ("plog:endscan");
            }
            return config;
        }
Ejemplo n.º 29
0
 public bool SafeDeleteDir(IProgressStatus monitor, string dir)
 {
     try {
         fileDatabase.DeleteDir (dir);
         return true;
     }
     catch (Exception ex) {
         if (monitor.LogLevel > 1) {
             monitor.Log ("Could not delete directory: " + dir);
             monitor.Log (ex.ToString ());
         }
         return false;
     }
 }
		public void ScanFolder (IProgressStatus monitor, string path, string domain, AddinScanResult scanResult)
		{
			path = Util.GetFullPath (path);
			
			// Avoid folders including each other
			if (!scanResult.VisitFolder (path))
				return;
			
			if (monitor.LogLevel > 1 && !scanResult.LocateAssembliesOnly)
				monitor.Log ("Checking: " + path);
			
			AddinScanFolderInfo folderInfo;
			if (!database.GetFolderInfoForPath (monitor, path, out folderInfo)) {
				// folderInfo file was corrupt.
				// Just in case, we are going to regenerate all relation data.
				if (!Directory.Exists (path))
					scanResult.RegenerateRelationData = true;
			} else {
				if (folderInfo == null && !Directory.Exists (path))
					return;
			}
			
			// if domain is null it means that a new domain has to be created.
			
			bool sharedFolder = domain == AddinDatabase.GlobalDomain;
			
			if (folderInfo == null)
				folderInfo = new AddinScanFolderInfo (path);
			
			if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain)) {
				// If the folder already has a domain, reuse it
				if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
					domain = folderInfo.RootsDomain;
				else if (domain == null) {
					folderInfo.Domain = domain = database.GetUniqueDomainId ();
					scanResult.RegenerateRelationData = true;
				}
				else {
					folderInfo.Domain = domain;
					scanResult.RegenerateRelationData = true;
				}
			}
			else if (!folderInfo.SharedFolder && sharedFolder) {
				scanResult.RegenerateRelationData = true;
			}
			
			folderInfo.SharedFolder = sharedFolder;
			
			if (Directory.Exists (path))
			{
				string[] files = Directory.GetFiles (path);
				
				// First of all, look for .addin files. Addin files must be processed before
				// assemblies, because they may add files to the ignore list (i.e., assemblies
				// included in .addin files won't be scanned twice).
				foreach (string file in files) {
					if (file.EndsWith (".addin.xml") || file.EndsWith (".addin")) {
						RegisterFileToScan (monitor, file, scanResult, folderInfo);
					}
				}
				
				foreach (string file in files) {
					switch (Path.GetExtension (file)) {
					case ".dll":
					case ".exe":
						RegisterFileToScan (monitor, file, scanResult, folderInfo);
						scanResult.AddAssemblyLocation (file);
						break;
					case ".addins":
						ScanAddinsFile (monitor, file, domain, scanResult);
						break;
					}
				}
			}
			else if (!scanResult.LocateAssembliesOnly) {
				// The folder has been deleted. All add-ins defined in that folder should also be deleted.
				scanResult.RegenerateRelationData = true;
				scanResult.ChangesFound = true;
				if (scanResult.CheckOnly)
					return;
				database.DeleteFolderInfo (monitor, folderInfo);
			}
			
			if (scanResult.LocateAssembliesOnly)
				return;
			
			// Look for deleted add-ins.
			
			UpdateDeletedAddins (monitor, folderInfo, scanResult);
		}
Ejemplo n.º 31
0
        public void ScanFolder(IProgressStatus monitor, string path, string domain, AddinScanResult scanResult)
        {
            path = Path.GetFullPath (path);

            // Avoid folders including each other
            if (!scanResult.VisitFolder (path))
                return;

            AddinScanFolderInfo folderInfo;
            if (!database.GetFolderInfoForPath (monitor, path, out folderInfo)) {
                // folderInfo file was corrupt.
                // Just in case, we are going to regenerate all relation data.
                if (!fs.DirectoryExists (path))
                    scanResult.RegenerateRelationData = true;
            } else {
                // Directory is included but it doesn't exist. Ignore it.
                if (folderInfo == null && !fs.DirectoryExists (path))
                    return;
            }

            // if domain is null it means that a new domain has to be created.

            bool sharedFolder = domain == AddinDatabase.GlobalDomain;
            bool isNewFolder = folderInfo == null;

            if (isNewFolder) {
                // No folder info. It is the first time this folder is scanned.
                // There is no need to store this object if the folder does not
                // contain add-ins.
                folderInfo = new AddinScanFolderInfo (path);
            }

            if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain)) {
                // If the folder already has a domain, reuse it
                if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
                    domain = folderInfo.RootsDomain;
                else if (domain == null) {
                    folderInfo.Domain = domain = database.GetUniqueDomainId ();
                    scanResult.RegenerateRelationData = true;
                }
                else {
                    folderInfo.Domain = domain;
                    if (!isNewFolder) {
                        // Domain has changed. Update the folder info and regenerate everything.
                        scanResult.RegenerateRelationData = true;
                        scanResult.RegisterModifiedFolderInfo (folderInfo);
                    }
                }
            }
            else if (!folderInfo.SharedFolder && sharedFolder) {
                scanResult.RegenerateRelationData = true;
            }

            folderInfo.SharedFolder = sharedFolder;

            // If there is no domain assigned to the host, get one now
            if (scanResult.Domain == AddinDatabase.UnknownDomain)
                scanResult.Domain = domain;

            // Discard folders not belonging to the required domain
            if (scanResult.Domain != null && domain != scanResult.Domain && domain != AddinDatabase.GlobalDomain) {
                return;
            }

            if (monitor.LogLevel > 1 && !scanResult.LocateAssembliesOnly)
                monitor.Log ("Checking: " + path);

            if (fs.DirectoryExists (path))
            {
                IEnumerable<string> files = fs.GetFiles (path);

                // First of all, look for .addin files. Addin files must be processed before
                // assemblies, because they may add files to the ignore list (i.e., assemblies
                // included in .addin files won't be scanned twice).
                foreach (string file in files) {
                    if (file.EndsWith (".addin.xml") || file.EndsWith (".addin")) {
                        RegisterFileToScan (monitor, file, scanResult, folderInfo);
                    }
                }

                // Now scan assemblies. They can also add files to the ignore list.

                foreach (string file in files) {
                    string ext = Path.GetExtension (file).ToLower ();
                    if (ext == ".dll" || ext == ".exe") {
                        RegisterFileToScan (monitor, file, scanResult, folderInfo);
                        scanResult.AddAssemblyLocation (file);
                    }
                }

                // Finally scan .addins files

                foreach (string file in files) {
                    if (Path.GetExtension (file).EndsWith (".addins")) {
                        ScanAddinsFile (monitor, file, domain, scanResult);
                    }
                }
            }
            else if (!scanResult.LocateAssembliesOnly) {
                // The folder has been deleted. All add-ins defined in that folder should also be deleted.
                scanResult.RegenerateRelationData = true;
                scanResult.ChangesFound = true;
                if (scanResult.CheckOnly)
                    return;
                database.DeleteFolderInfo (monitor, folderInfo);
            }

            if (scanResult.LocateAssembliesOnly)
                return;

            // Look for deleted add-ins.

            UpdateDeletedAddins (monitor, folderInfo, scanResult);
        }
Ejemplo n.º 32
0
        public void ScanFolder(IProgressStatus monitor, string path, string domain, AddinScanResult scanResult)
        {
            path = Util.GetFullPath(path);

            // Avoid folders including each other
            if (!scanResult.VisitFolder(path))
            {
                return;
            }

            AddinScanFolderInfo folderInfo;

            if (!database.GetFolderInfoForPath(monitor, path, out folderInfo))
            {
                // folderInfo file was corrupt.
                // Just in case, we are going to regenerate all relation data.
                if (!Directory.Exists(path))
                {
                    scanResult.RegenerateRelationData = true;
                }
            }
            else
            {
                // Directory is included but it doesn't exist. Ignore it.
                if (folderInfo == null && !Directory.Exists(path))
                {
                    return;
                }
            }

            // if domain is null it means that a new domain has to be created.

            bool sharedFolder = domain == AddinDatabase.GlobalDomain;
            bool isNewFolder  = folderInfo == null;

            if (isNewFolder)
            {
                // No folder info. It is the first time this folder is scanned.
                // There is no need to store this object if the folder does not
                // contain add-ins.
                folderInfo = new AddinScanFolderInfo(path);
            }

            if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain))
            {
                // If the folder already has a domain, reuse it
                if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
                {
                    domain = folderInfo.RootsDomain;
                }
                else if (domain == null)
                {
                    folderInfo.Domain = domain = database.GetUniqueDomainId();
                    scanResult.RegenerateRelationData = true;
                }
                else
                {
                    folderInfo.Domain = domain;
                    if (!isNewFolder)
                    {
                        // Domain has changed. Update the folder info and regenerate everything.
                        scanResult.RegenerateRelationData = true;
                        scanResult.RegisterModifiedFolderInfo(folderInfo);
                    }
                }
            }
            else if (!folderInfo.SharedFolder && sharedFolder)
            {
                scanResult.RegenerateRelationData = true;
            }

            folderInfo.SharedFolder = sharedFolder;

            // If there is no domain assigned to the host, get one now
            if (scanResult.Domain == AddinDatabase.UnknownDomain)
            {
                scanResult.Domain = domain;
            }

            // Discard folders not belonging to the required domain
            if (scanResult.Domain != null && domain != scanResult.Domain && domain != AddinDatabase.GlobalDomain)
            {
                return;
            }

            if (monitor.LogLevel > 1 && !scanResult.LocateAssembliesOnly)
            {
                monitor.Log("Checking: " + path);
            }

            if (Directory.Exists(path))
            {
                string[] files = Directory.GetFiles(path);

                // First of all, look for .addin files. Addin files must be processed before
                // assemblies, because they may add files to the ignore list (i.e., assemblies
                // included in .addin files won't be scanned twice).
                foreach (string file in files)
                {
                    if (file.EndsWith(".addin.xml") || file.EndsWith(".addin"))
                    {
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                    }
                }

                // Now scan assemblies. They can also add files to the ignore list.

                foreach (string file in files)
                {
                    string ext = Path.GetExtension(file).ToLower();
                    if (ext == ".dll" || ext == ".exe")
                    {
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                        scanResult.AddAssemblyLocation(file);
                    }
                }

                // Finally scan .addins files

                foreach (string file in files)
                {
                    if (Path.GetExtension(file).EndsWith(".addins"))
                    {
                        ScanAddinsFile(monitor, file, domain, scanResult);
                    }
                }
            }
            else if (!scanResult.LocateAssembliesOnly)
            {
                // The folder has been deleted. All add-ins defined in that folder should also be deleted.
                scanResult.RegenerateRelationData = true;
                scanResult.ChangesFound           = true;
                if (scanResult.CheckOnly)
                {
                    return;
                }
                database.DeleteFolderInfo(monitor, folderInfo);
            }

            if (scanResult.LocateAssembliesOnly)
            {
                return;
            }

            // Look for deleted add-ins.

            UpdateDeletedAddins(monitor, folderInfo, scanResult);
        }
Ejemplo n.º 33
0
 IAssemblyReflector GetReflector(IProgressStatus monitor, AddinScanResult scanResult, string filePath)
 {
     IAssemblyReflector reflector = fs.GetReflectorForFile (scanResult, filePath);
     object coreAssembly;
     if (!coreAssemblies.TryGetValue (reflector, out coreAssembly)) {
         if (monitor.LogLevel > 1)
             monitor.Log ("Using assembly reflector: " + reflector.GetType ());
         coreAssemblies [reflector] = coreAssembly = reflector.LoadAssembly (GetType().Assembly.Location);
     }
     return reflector;
 }
Ejemplo n.º 34
0
		public static void MonitorProcessStatus (IProgressStatus monitor, TextReader reader, StringCollection progessLog)
		{
			string line;
			string exceptionText = null;
			while ((line = reader.ReadLine ()) != null) {
				int i = line.IndexOf (':');
				if (i != -1) {
					string tag = line.Substring (0, i);
					string txt = line.Substring (i+1);
					bool wasTag = true;
					
					switch (tag) {
						case "process-ps-msg":
							monitor.SetMessage (Decode (txt));
							break;
						case "process-ps-progress":
							monitor.SetProgress (double.Parse (txt));
							break;
						case "process-ps-log":
							monitor.Log (Decode (txt));
							break;
						case "process-ps-warning":
							monitor.ReportWarning (Decode (txt));
							break;
						case "process-ps-exception":
							exceptionText = Decode (txt);
							if (exceptionText == string.Empty)
								exceptionText = null;
							break;
						case "process-ps-error":
							string err = Decode (txt);
							if (err == string.Empty) err = null;
							monitor.ReportError (err, exceptionText != null ? new Exception (exceptionText) : null);
							break;
						case "process-ps-cancel":
							monitor.Cancel ();
							break;
						case "process-ps-plog":
							progessLog.Add (Decode (txt));
							break;
						default:
							wasTag = false;
							break;
					}
					if (wasTag)
						continue;
				}
				Console.WriteLine (line);
			}
		}
		public bool SafeDelete (IProgressStatus monitor, string file)
		{
			try {
				fileDatabase.Delete (file);
				return true;
			}
			catch (Exception ex) {
				if (monitor.VerboseLog) {
					monitor.Log ("Could not delete file: " + file);
					monitor.Log (ex.ToString ());
				}
				return false;
			}
		}
        public void ScanFile(IProgressStatus monitor, string file, AddinScanFolderInfo folderInfo, AddinScanResult scanResult)
        {
            if (monitor.VerboseLog)
            {
                monitor.Log("Scanning file: " + file);
            }

            string scannedAddinId = null;
            bool   scannedIsRoot  = false;
            bool   scanSuccessful = false;

            try {
                string           ext    = Path.GetExtension(file);
                AddinDescription config = null;

                if (ext == ".dll" || ext == ".exe")
                {
                    scanSuccessful = ScanAssembly(monitor, file, scanResult, out config);
                }
                else
                {
                    scanSuccessful = ScanConfigAssemblies(monitor, file, scanResult, out config);
                }

                if (config != null)
                {
                    AddinFileInfo fi = folderInfo.GetAddinFileInfo(file);

                    // If version is not specified, make up one
                    if (config.Version.Length == 0)
                    {
                        config.Version = "0.0.0.0";
                    }

                    if (config.LocalId.Length == 0)
                    {
                        // Generate an internal id for this add-in
                        config.LocalId   = database.GetUniqueAddinId(file, (fi != null ? fi.AddinId : null), config.Namespace, config.Version);
                        config.HasUserId = false;
                    }

                    // Check errors in the description
                    StringCollection errors = config.Verify();

                    if (database.IsGlobalRegistry && config.AddinId.IndexOf('.') == -1)
                    {
                        errors.Add("Add-ins registered in the global registry must have a namespace.");
                    }

                    if (errors.Count > 0)
                    {
                        scanSuccessful = false;
                        monitor.ReportError("Errors found in add-in '" + file + ":", null);
                        foreach (string err in errors)
                        {
                            monitor.ReportError(err, null);
                        }
                    }

                    // Make sure all extensions sets are initialized with the correct add-in id

                    config.SetExtensionsAddinId(config.AddinId);

                    scanResult.ChangesFound = true;

                    // If the add-in already existed, try to reuse the relation data it had.
                    // Also, the dependencies of the old add-in need to be re-analized

                    AddinDescription existingDescription = null;
                    bool             res;

                    if (config.IsRoot)
                    {
                        res = database.GetHostDescription(monitor, config.AddinId, config.AddinFile, out existingDescription);
                    }
                    else
                    {
                        res = database.GetAddinDescription(monitor, config.AddinId, out existingDescription);
                    }

                    // If we can't get information about the old assembly, just regenerate all relation data
                    if (!res)
                    {
                        scanResult.RegenerateRelationData = true;
                    }

                    string replaceFileName = null;

                    if (existingDescription != null)
                    {
                        // Reuse old relation data
                        config.MergeExternalData(existingDescription);
                        Util.AddDependencies(existingDescription, scanResult);
                        replaceFileName = existingDescription.FileName;
                    }

                    // If the scanned file results in an add-in version different from the one obtained from
                    // previous scans, the old add-in needs to be uninstalled.
                    if (fi != null && fi.AddinId != null && fi.AddinId != config.AddinId)
                    {
                        if (fi.IsRoot)
                        {
                            database.UninstallRootAddin(monitor, fi.AddinId, file, scanResult);
                        }
                        else
                        {
                            database.UninstallAddin(monitor, fi.AddinId, scanResult);
                        }

                        // If the add-in version has changed, regenerate everything again since old data can't be reused
                        if (Addin.GetIdName(fi.AddinId) == Addin.GetIdName(config.AddinId))
                        {
                            scanResult.RegenerateRelationData = true;
                        }
                    }

                    // If a description could be generated, save it now (if the scan was successful)
                    if (scanSuccessful)
                    {
                        if (database.SaveDescription(monitor, config, replaceFileName))
                        {
                            // The new dependencies also have to be updated
                            Util.AddDependencies(config, scanResult);
                            scanResult.AddAddinToUpdateRelations(config.AddinId);
                            scannedAddinId = config.AddinId;
                            scannedIsRoot  = config.IsRoot;
                            return;
                        }
                    }
                }
            }
            catch (Exception ex) {
                monitor.ReportError("Unexpected error while scanning file: " + file, ex);
            }
            finally {
                folderInfo.SetLastScanTime(file, scannedAddinId, scannedIsRoot, File.GetLastWriteTime(file), !scanSuccessful);
            }
        }
		void InternalScanFolders (IProgressStatus monitor, AddinScanResult scanResult)
		{
			DateTime tim = DateTime.Now;
			
			DatabaseInfrastructureCheck (monitor);
			if (monitor.IsCanceled)
				return;
			
			try {
				scanResult.HostIndex = GetAddinHostIndex ();
			}
			catch (Exception ex) {
				if (scanResult.CheckOnly) {
					scanResult.ChangesFound = true;
					return;
				}
				monitor.ReportError ("Add-in root index is corrupt. The add-in database will be regenerated.", ex);
				scanResult.RegenerateAllData = true;
			}
			
			AddinScanner scanner = new AddinScanner (this);
			
			// Check if any of the previously scanned folders has been deleted
			
			foreach (string file in Directory.GetFiles (AddinFolderCachePath, "*.data")) {
				AddinScanFolderInfo folderInfo;
				bool res = ReadFolderInfo (monitor, file, out folderInfo);
				if (!res || !Directory.Exists (folderInfo.Folder)) {
					if (res) {
						// Folder has been deleted. Remove the add-ins it had.
						scanner.UpdateDeletedAddins (monitor, folderInfo, scanResult);
					}
					else {
						// Folder info file corrupt. Regenerate all.
						scanResult.ChangesFound = true;
						scanResult.RegenerateRelationData = true;
					}
					
					if (!scanResult.CheckOnly)
						SafeDelete (monitor, file);
					else
						return;
				}
			}
			
			// Look for changes in the add-in folders
			
			foreach (string dir in registry.AddinDirectories) {
				if (dir == registry.DefaultAddinsFolder)
					scanner.ScanFolderRec (monitor, dir, scanResult);
				else
					scanner.ScanFolder (monitor, dir, scanResult);
				if (scanResult.CheckOnly) {
					if (scanResult.ChangesFound || monitor.IsCanceled)
						return;
				}
			}
			
			if (scanResult.CheckOnly)
				return;
			
			// Scan the files which have been modified
			
			currentScanResult = scanResult;

			foreach (FileToScan file in scanResult.FilesToScan)
				scanner.ScanFile (monitor, file.File, file.AddinScanFolderInfo, scanResult);

			// Save folder info
			
			foreach (AddinScanFolderInfo finfo in scanResult.ModifiedFolderInfos)
				SaveFolderInfo (monitor, finfo);

			if (monitor.VerboseLog)
				monitor.Log ("Folders scan completed (" + (int) (DateTime.Now - tim).TotalMilliseconds + " ms)");

			SaveAddinHostIndex ();
			ResetCachedData ();
			
			if (!scanResult.ChangesFound) {
				if (monitor.VerboseLog)
					monitor.Log ("No changes found");
				return;
			}
			
			tim = DateTime.Now;
			try {
				if (scanResult.RegenerateRelationData)
					scanResult.AddinsToUpdateRelations = null;
				
				GenerateAddinExtensionMapsInternal (monitor, scanResult.AddinsToUpdateRelations, scanResult.RemovedAddins);
			}
			catch (Exception ex) {
				fatalDatabseError = true;
				monitor.ReportError ("The add-in database could not be updated. It may be due to file corruption. Try running the setup repair utility", ex);
			}
			
			if (monitor.VerboseLog)
				monitor.Log ("Add-in relations analyzed (" + (int) (DateTime.Now - tim).TotalMilliseconds + " ms)");
			
			SaveAddinHostIndex ();
		}
        public void ScanFolder(IProgressStatus monitor, string path, AddinScanResult scanResult)
        {
            path = Util.GetFullPath(path);

            // Avoid folders including each other
            if (!scanResult.VisitFolder(path))
            {
                return;
            }

            if (monitor.VerboseLog && !scanResult.LocateAssembliesOnly)
            {
                monitor.Log("Checking: " + path);
            }

            AddinScanFolderInfo folderInfo;

            if (!database.GetFolderInfoForPath(monitor, path, out folderInfo))
            {
                // folderInfo file was corrupt.
                // Just in case, we are going to regenerate all relation data.
                if (!Directory.Exists(path))
                {
                    scanResult.RegenerateRelationData = true;
                }
            }
            else
            {
                if (folderInfo == null && !Directory.Exists(path))
                {
                    return;
                }
            }

            if (folderInfo == null)
            {
                folderInfo = new AddinScanFolderInfo(path);
            }

            if (Directory.Exists(path))
            {
                foreach (string file in Directory.GetFiles(path))
                {
                    if (file.EndsWith(".addin.xml"))
                    {
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                        continue;
                    }
                    switch (Path.GetExtension(file))
                    {
                    case ".dll":
                    case ".exe":
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                        scanResult.AddAssemblyLocation(file);
                        break;

                    case ".addin":
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                        break;

                    case ".addins":
                        ScanAddinsFile(monitor, file, scanResult);
                        break;
                    }
                }
            }
            else if (!scanResult.LocateAssembliesOnly)
            {
                // The folder has been deleted. All add-ins defined in that folder should also be deleted.
                scanResult.RegenerateRelationData = true;
                scanResult.ChangesFound           = true;
                if (scanResult.CheckOnly)
                {
                    return;
                }
                database.DeleteFolderInfo(monitor, folderInfo);
            }

            if (scanResult.LocateAssembliesOnly)
            {
                return;
            }

            // Look for deleted add-ins.

            UpdateDeletedAddins(monitor, folderInfo, scanResult);
        }
Ejemplo n.º 39
0
        void BuildPackageInternal(IProgressStatus monitor, string targetDirectory, string filePath)
        {
            AddinDescription conf = registry.GetAddinDescription (monitor, filePath);
            if (conf == null) {
                monitor.ReportError ("Could not read add-in file: " + filePath, null);
                return;
            }

            string basePath = Path.GetDirectoryName (filePath);

            if (targetDirectory == null)
                targetDirectory = basePath;

            // Generate the file name

            string name;
            if (conf.LocalId.Length == 0)
                name = Path.GetFileNameWithoutExtension (filePath);
            else
                name = conf.LocalId;
            name = Addin.GetFullId (conf.Namespace, name, conf.Version);
            name = name.Replace (',','_').Replace (".__", ".");

            string outFilePath = Path.Combine (targetDirectory, name) + ".mpack";

            ZipOutputStream s = new ZipOutputStream (File.Create (outFilePath));
            s.SetLevel(5);

            // Generate a stripped down description of the add-in in a file, since the complete
            // description may be declared as assembly attributes

            XmlDocument doc = new XmlDocument ();
            doc.PreserveWhitespace = false;
            doc.LoadXml (conf.SaveToXml ().OuterXml);
            CleanDescription (doc.DocumentElement);
            MemoryStream ms = new MemoryStream ();
            XmlTextWriter tw = new XmlTextWriter (ms, System.Text.Encoding.UTF8);
            tw.Formatting = Formatting.Indented;
            doc.WriteTo (tw);
            tw.Flush ();
            byte[] data = ms.ToArray ();

            ZipEntry infoEntry = new ZipEntry ("addin.info");
            s.PutNextEntry (infoEntry);
            s.Write (data, 0, data.Length);

            // Now add the add-in files

            ArrayList list = new ArrayList ();
            if (!conf.AllFiles.Contains (Path.GetFileName (filePath)))
                list.Add (Path.GetFileName (filePath));
            foreach (string f in conf.AllFiles) {
                list.Add (f);
            }

            monitor.Log ("Creating package " + Path.GetFileName (outFilePath));

            foreach (string file in list) {
                string fp = Path.Combine (basePath, file);
                using (FileStream fs = File.OpenRead (fp)) {
                    byte[] buffer = new byte [fs.Length];
                    fs.Read (buffer, 0, buffer.Length);

                    ZipEntry entry = new ZipEntry (file);
                    s.PutNextEntry (entry);
                    s.Write (buffer, 0, buffer.Length);
                }
            }

            s.Finish();
            s.Close();
        }
Ejemplo n.º 40
0
        public void ScanFolder(IProgressStatus monitor, string path, string domain, AddinScanResult scanResult)
        {
            path = Util.GetFullPath(path);

            // Avoid folders including each other
            if (!scanResult.VisitFolder(path))
            {
                return;
            }

            if (monitor.LogLevel > 1 && !scanResult.LocateAssembliesOnly)
            {
                monitor.Log("Checking: " + path);
            }

            AddinScanFolderInfo folderInfo;

            if (!database.GetFolderInfoForPath(monitor, path, out folderInfo))
            {
                // folderInfo file was corrupt.
                // Just in case, we are going to regenerate all relation data.
                if (!Directory.Exists(path))
                {
                    scanResult.RegenerateRelationData = true;
                }
            }
            else
            {
                if (folderInfo == null && !Directory.Exists(path))
                {
                    return;
                }
            }

            // if domain is null it means that a new domain has to be created.

            bool sharedFolder = domain == AddinDatabase.GlobalDomain;

            if (folderInfo == null)
            {
                folderInfo = new AddinScanFolderInfo(path);
            }

            if (!sharedFolder && (folderInfo.SharedFolder || folderInfo.Domain != domain))
            {
                // If the folder already has a domain, reuse it
                if (domain == null && folderInfo.RootsDomain != null && folderInfo.RootsDomain != AddinDatabase.GlobalDomain)
                {
                    domain = folderInfo.RootsDomain;
                }
                else if (domain == null)
                {
                    folderInfo.Domain = domain = database.GetUniqueDomainId();
                    scanResult.RegenerateRelationData = true;
                }
                else
                {
                    folderInfo.Domain = domain;
                    scanResult.RegenerateRelationData = true;
                }
            }
            else if (!folderInfo.SharedFolder && sharedFolder)
            {
                scanResult.RegenerateRelationData = true;
            }

            folderInfo.SharedFolder = sharedFolder;

            if (Directory.Exists(path))
            {
                string[] files = Directory.GetFiles(path);

                // First of all, look for .addin files. Addin files must be processed before
                // assemblies, because they may add files to the ignore list (i.e., assemblies
                // included in .addin files won't be scanned twice).
                foreach (string file in files)
                {
                    if (file.EndsWith(".addin.xml") || file.EndsWith(".addin"))
                    {
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                    }
                }

                foreach (string file in files)
                {
                    switch (Path.GetExtension(file))
                    {
                    case ".dll":
                    case ".exe":
                        RegisterFileToScan(monitor, file, scanResult, folderInfo);
                        scanResult.AddAssemblyLocation(file);
                        break;

                    case ".addins":
                        ScanAddinsFile(monitor, file, domain, scanResult);
                        break;
                    }
                }
            }
            else if (!scanResult.LocateAssembliesOnly)
            {
                // The folder has been deleted. All add-ins defined in that folder should also be deleted.
                scanResult.RegenerateRelationData = true;
                scanResult.ChangesFound           = true;
                if (scanResult.CheckOnly)
                {
                    return;
                }
                database.DeleteFolderInfo(monitor, folderInfo);
            }

            if (scanResult.LocateAssembliesOnly)
            {
                return;
            }

            // Look for deleted add-ins.

            UpdateDeletedAddins(monitor, folderInfo, scanResult);
        }