Ejemplo n.º 1
0
        void CheckHostAssembly(Assembly asm)
        {
            if (AddinDatabase.RunningSetupProcess || asm is System.Reflection.Emit.AssemblyBuilder || asm.IsDynamic)
            {
                return;
            }
            string codeBase;

            try {
                codeBase = asm.CodeBase;
            } catch {
                return;
            }

            Uri u;

            if (!Uri.TryCreate(codeBase, UriKind.Absolute, out u))
            {
                return;
            }

            string asmFile = u.LocalPath;
            Addin  ainfo;

            try {
                ainfo = Registry.GetAddinForHostAssembly(asmFile);
            } catch (Exception ex) {
                // GetAddinForHostAssembly may crash if the add-in db has been corrupted. In this case, update the db
                // and try getting the add-in info again. If it crashes again, then this is a bug.
                defaultProgressStatus.ReportError("Add-in description could not be loaded.", ex);
                Registry.Update(null);
                ainfo = Registry.GetAddinForHostAssembly(asmFile);
            }

            if (ainfo != null && !IsAddinLoaded(ainfo.Id))
            {
                AddinDescription adesc = null;
                try {
                    adesc = ainfo.Description;
                } catch (Exception ex) {
                    defaultProgressStatus.ReportError("Add-in description could not be loaded.", ex);
                }
                if (adesc == null || adesc.FilesChanged())
                {
                    // If the add-in has changed, update the add-in database.
                    // We do it here because once loaded, add-in roots can't be
                    // reloaded like regular add-ins.
                    Registry.Update(null);
                    ainfo = Registry.GetAddinForHostAssembly(asmFile);
                    if (ainfo == null)
                    {
                        return;
                    }
                }
                LoadAddin(null, ainfo.Id, false);
            }
        }
Ejemplo n.º 2
0
        public static AddinScanDataIndex LoadFromFolder(IProgressStatus monitor, string path)
        {
            var file = Path.Combine(path, "dir.addindata");

            if (File.Exists(file))
            {
                try {
                    using (Stream s = File.OpenRead(file)) {
                        BinaryXmlReader reader = new BinaryXmlReader(s, typeMap);
                        reader.ContextData = file;
                        return((AddinScanDataIndex)reader.ReadValue("data"));
                    }
                } catch (Exception ex) {
                    if (monitor != null)
                    {
                        monitor.ReportError("Could not load dir.addindata file", ex);
                    }
                    // The addindata file is corrupted or changed format.
                    // It is not useful anymore, so remove it
                    try {
                        File.Delete(file);
                    } catch {
                        // Ignore error deleting. Maybe there is a permission issue.
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Updates the add-in index of the provided repository
        /// </summary>
        /// <param name="statusMonitor">
        /// Progress monitor where to show progress status and log
        /// </param>
        /// <param name="url">
        /// URL of the repository
        /// </param>
        public void UpdateRepository(IProgressStatus statusMonitor, string url)
        {
            repoList = null;

            IProgressMonitor monitor = ProgressStatusMonitor.GetProgressMonitor(statusMonitor);

            monitor.BeginTask("Updating repositories", service.Configuration.Repositories.Count);
            try {
                int num = service.Configuration.Repositories.Count;
                for (int n = 0; n < num; n++)
                {
                    RepositoryRecord rr = (RepositoryRecord)service.Configuration.Repositories [n];
                    if (((url == null && rr.Enabled) || rr.Url == url) && !rr.IsReference)
                    {
                        UpdateRepository(monitor, new Uri(rr.Url), rr);
                    }
                    monitor.Step(1);
                }
            } catch (Exception ex) {
                statusMonitor.ReportError("Could not get information from repository", ex);
                return;
            } finally {
                monitor.EndTask();
            }

            PurgeUnusedRepositories();
            service.SaveConfiguration();
        }
		public AddinRepository RegisterRepository (IProgressStatus monitor, string url, bool updateNow)
		{
			if (!url.EndsWith (".mrep"))
				url = url + "/main.mrep";
			
			RepositoryRecord rr = FindRepositoryRecord (url);
			if (rr != null)
				return rr;

			RegisterRepository (url, false);
			
			try {
				if (updateNow) {
					UpdateRepository (monitor, url);
					rr = FindRepositoryRecord (url);
					Repository rep = rr.GetCachedRepository ();
					rr.Name = rep.Name;
				}
				service.SaveConfiguration ();
				return rr;
			} catch (Exception ex) {
				if (monitor != null)
					monitor.ReportError ("The repository could not be registered", ex);
				if (ContainsRepository (url))
					RemoveRepository (url);
				return null;
			}
		}
        bool ScanAssembly(IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
        {
            config = null;

            try {
                Assembly asm = Util.LoadAssemblyForReflection(filePath);

                // Get the config file from the resources, if there is one

                string configFile = null;
                foreach (string res in asm.GetManifestResourceNames())
                {
                    if (res.EndsWith(".addin") || res.EndsWith(".addin.xml"))
                    {
                        configFile = res;
                        break;
                    }
                }

                if (configFile != null)
                {
                    using (Stream s = asm.GetManifestResourceStream(configFile)) {
                        string asmFile = new Uri(asm.CodeBase).LocalPath;
                        config = AddinDescription.Read(s, Path.GetDirectoryName(asmFile));
                    }
                }
                else
                {
                    // On this case, only scan the assembly if it has the Addin attribute.
                    AddinAttribute att = (AddinAttribute)Attribute.GetCustomAttribute(asm, typeof(AddinAttribute), false);
                    if (att == null)
                    {
                        config = null;
                        return(true);
                    }
                    config = new AddinDescription();
                }

                config.BasePath  = Path.GetDirectoryName(filePath);
                config.AddinFile = filePath;

                string rasmFile = Path.GetFileName(filePath);
                if (!config.MainModule.Assemblies.Contains(rasmFile))
                {
                    config.MainModule.Assemblies.Add(rasmFile);
                }

                return(ScanDescription(monitor, config, asm, scanResult));
            }
            catch (Exception ex) {
                // Something went wrong while scanning the assembly. We'll ignore it for now.
                monitor.ReportError("There was an error while scanning assembly: " + filePath, ex);
                return(false);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Subscribes to an on-line repository
        /// </summary>
        /// <param name="monitor">
        /// Progress monitor where to show progress status and log
        /// </param>
        /// <param name="url">
        /// URL of the repository
        /// </param>
        /// <param name="updateNow">
        /// When set to True, the repository index will be downloaded.
        /// </param>
        /// <returns>
        /// A repository reference
        /// </returns>
        public AddinRepository RegisterRepository(IProgressStatus monitor, string url, bool updateNow)
        {
            if (string.IsNullOrEmpty(url))
            {
                throw new ArgumentException("Emtpy url");
            }

            if (!url.EndsWith(".mrep"))
            {
                if (url [url.Length - 1] != '/')
                {
                    url += "/";
                }
                url = url + "main.mrep";
            }

            RepositoryRecord rr = FindRepositoryRecord(url);

            if (rr != null)
            {
                return(rr);
            }

            rr = RegisterRepository(url, false);

            try
            {
                if (updateNow)
                {
                    UpdateRepository(monitor, url);
                    rr = FindRepositoryRecord(url);
                    Repository rep = rr.GetCachedRepository();
                    if (rep != null)
                    {
                        rr.Name = rep.Name;
                    }
                }
                service.SaveConfiguration();
                return(rr);
            }
            catch (Exception ex)
            {
                if (monitor != null)
                {
                    monitor.ReportError("The repository could not be registered", ex);
                }
                if (ContainsRepository(url))
                {
                    RemoveRepository(url);
                }
                return(null);
            }
        }
Ejemplo n.º 7
0
        bool InsertAddin(IProgressStatus statusMonitor, Addin iad)
        {
            try {
                RuntimeAddin p = new RuntimeAddin();

                // Read the config file and load the add-in assemblies
                AddinDescription description = p.Load(iad);

                // Register the add-in
                loadedAddins [Addin.GetIdName(p.Id)] = p;

                if (!AddinDatabase.RunningSetupProcess)
                {
                    // Load the extension points and other addin data

                    foreach (ExtensionNodeSet rel in description.ExtensionNodeSets)
                    {
                        RegisterNodeSet(rel);
                    }

                    foreach (ConditionTypeDescription cond in description.ConditionTypes)
                    {
                        Type ctype = p.GetType(cond.TypeName, true);
                        defaultContext.RegisterCondition(cond.Id, ctype);
                    }
                }

                foreach (ExtensionPoint ep in description.ExtensionPoints)
                {
                    InsertExtensionPoint(p, ep);
                }

                foreach (Assembly asm in p.Assemblies)
                {
                    loadedAssemblies [asm] = p;
                }

                // Fire loaded event
                defaultContext.NotifyAddinLoaded(p);
                AddinManager.ReportAddinLoad(p.Id);
                return(true);
            }
            catch (Exception ex) {
                AddinManager.ReportError("Extension could not be loaded", iad.Id, ex, false);
                if (statusMonitor != null)
                {
                    statusMonitor.ReportError("Extension '" + iad.Id + "' could not be loaded.", ex);
                }
                return(false);
            }
        }
Ejemplo n.º 8
0
        bool InsertAddin(IProgressStatus statusMonitor, Addin iad)
        {
            try {
                RuntimeAddin p = new RuntimeAddin(this);

                RegisterAssemblyResolvePaths(p, iad.Description.MainModule);

                // Read the config file and load the add-in assemblies
                AddinDescription description = p.Load(iad);

                // Register the add-in
                var loadedAddinsCopy = new Dictionary <string, RuntimeAddin> (loadedAddins);
                loadedAddinsCopy [Addin.GetIdName(p.Id)] = p;
                loadedAddins = loadedAddinsCopy;

                if (!AddinDatabase.RunningSetupProcess)
                {
                    // Load the extension points and other addin data

                    RegisterNodeSets(iad.Id, description.ExtensionNodeSets);

                    foreach (ConditionTypeDescription cond in description.ConditionTypes)
                    {
                        Type ctype = p.GetType(cond.TypeName, true);
                        RegisterCondition(cond.Id, ctype);
                    }
                }

                foreach (ExtensionPoint ep in description.ExtensionPoints)
                {
                    InsertExtensionPoint(p, ep);
                }

                // Fire loaded event
                NotifyAddinLoaded(p);
                ReportAddinLoad(p.Id);
                return(true);
            }
            catch (Exception ex) {
                ReportError("Add-in could not be loaded", iad.Id, ex, false);
                if (statusMonitor != null)
                {
                    statusMonitor.ReportError("Add-in '" + iad.Id + "' could not be loaded.", ex);
                }
                return(false);
            }
        }
Ejemplo n.º 9
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);
        }
        bool ScanConfigAssemblies(IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
        {
            config = null;

            try {
                string basePath = Path.GetDirectoryName(filePath);

                config           = AddinDescription.Read(filePath);
                config.BasePath  = basePath;
                config.AddinFile = filePath;

                return(ScanDescription(monitor, config, null, scanResult));
            }
            catch (Exception ex) {
                // Something went wrong while scanning the assembly. We'll ignore it for now.
                monitor.ReportError("There was an error while scanning add-in: " + filePath, ex);
                return(false);
            }
        }
Ejemplo n.º 11
0
 public bool FindExtensionPathByType(IProgressStatus monitor, Type type, string nodeName, out string path, out string pathNodeName)
 {
     if (extensionPoint != null)
     {
         foreach (ExtensionNodeType nt in extensionPoint.NodeSet.NodeTypes)
         {
             if (nt.ObjectTypeName.Length > 0 && (nodeName.Length == 0 || nodeName == nt.Id))
             {
                 RuntimeAddin addin = AddinManager.SessionService.GetAddin(extensionPoint.RootAddin);
                 Type         ot    = addin.GetType(nt.ObjectTypeName);
                 if (ot != null)
                 {
                     if (ot.IsAssignableFrom(type))
                     {
                         path         = extensionPoint.Path;
                         pathNodeName = nt.Id;
                         return(true);
                     }
                 }
                 else
                 {
                     monitor.ReportError("Type '" + nt.ObjectTypeName + "' not found in add-in '" + Id + "'", null);
                 }
             }
         }
     }
     else
     {
         foreach (TreeNode node in Children)
         {
             if (node.FindExtensionPathByType(monitor, type, nodeName, out path, out pathNodeName))
             {
                 return(true);
             }
         }
     }
     path         = null;
     pathNodeName = null;
     return(false);
 }
        public AddinRepository RegisterRepository(IProgressStatus monitor, string url, bool updateNow)
        {
            if (!url.EndsWith(".mrep"))
            {
                url = url + "/main.mrep";
            }

            RepositoryRecord rr = FindRepositoryRecord(url);

            if (rr != null)
            {
                return(rr);
            }

            rr = RegisterRepository(url, false);

            try {
                if (updateNow)
                {
                    UpdateRepository(monitor, url);
                    rr = FindRepositoryRecord(url);
                    Repository rep = rr.GetCachedRepository();
                    rr.Name = rep.Name;
                }
                service.SaveConfiguration();
                return(rr);
            } catch (Exception ex) {
                if (monitor != null)
                {
                    monitor.ReportError("The repository could not be registered", ex);
                }
                if (ContainsRepository(url))
                {
                    RemoveRepository(url);
                }
                return(null);
            }
        }
Ejemplo n.º 13
0
        bool ScanConfigAssemblies(IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
        {
            config = null;

            try {
                IAssemblyReflector reflector = GetReflector (monitor, scanResult, filePath);

                string basePath = Path.GetDirectoryName (filePath);

                using (var s = fs.OpenFile (filePath)) {
                    config = AddinDescription.Read (s, basePath);
                }
                config.FileName = filePath;
                config.SetBasePath (basePath);
                config.AddinFile = filePath;

                return ScanDescription (monitor, reflector, config, null, scanResult);
            }
            catch (Exception ex) {
                // Something went wrong while scanning the assembly. We'll ignore it for now.
                monitor.ReportError ("There was an error while scanning add-in: " + filePath, ex);
                return false;
            }
        }
		public bool SaveDescription (IProgressStatus monitor, AddinDescription desc, string replaceFileName)
		{
			try {
				if (replaceFileName != null)
					desc.SaveBinary (fileDatabase, replaceFileName);
				else if (desc.IsRoot)
					desc.SaveHostBinary (fileDatabase, AddinCachePath);
				else
					desc.SaveBinary (fileDatabase, GetDescriptionPath (desc.AddinId));
				return true;
			}
			catch (Exception ex) {
				monitor.ReportError ("Add-in info file could not be saved", ex);
				return false;
			}
		}
Ejemplo n.º 15
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.º 16
0
        bool ScanAssembly(IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
        {
            config = null;

            try {
                IAssemblyReflector reflector = GetReflector (monitor, scanResult, filePath);
                object asm = reflector.LoadAssembly (filePath);
                if (asm == null)
                    throw new Exception ("Could not load assembly: " + filePath);

                // Get the config file from the resources, if there is one

                foreach (string res in reflector.GetResourceNames (asm)) {
                    if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) {
                        using (Stream s = reflector.GetResourceStream (asm, res)) {
                            AddinDescription ad = AddinDescription.Read (s, Path.GetDirectoryName (filePath));
                            if (config != null) {
                                if (!config.IsExtensionModel && !ad.IsExtensionModel) {
                                    // There is more than one add-in definition
                                    monitor.ReportError ("Duplicate add-in definition found in assembly: " + filePath, null);
                                    return false;
                                }
                                config = AddinDescription.Merge (config, ad);
                            } else
                                config = ad;
                        }
                    }
                }

                if (config == null) {
                    // In this case, only scan the assembly if it has the Addin attribute.
                    AddinAttribute att = (AddinAttribute) reflector.GetCustomAttribute (asm, typeof(AddinAttribute), false);
                    if (att == null)
                        return true;

                    config = new AddinDescription ();
                }

                config.SetBasePath (Path.GetDirectoryName (filePath));
                config.AddinFile = filePath;

                string rasmFile = Path.GetFileName (filePath);
                if (!config.MainModule.Assemblies.Contains (rasmFile))
                    config.MainModule.Assemblies.Add (rasmFile);

                return ScanDescription (monitor, reflector, config, asm, scanResult);
            }
            catch (Exception ex) {
                // Something went wrong while scanning the assembly. We'll ignore it for now.
                monitor.ReportError ("There was an error while scanning assembly: " + filePath, ex);
                return false;
            }
        }
Ejemplo n.º 17
0
		/// <summary>
		/// Updates the add-in index of the provided repository
		/// </summary>
		/// <param name="statusMonitor">
		/// Progress monitor where to show progress status and log
		/// </param>
		/// <param name="url">
		/// URL of the repository
		/// </param>
		public void UpdateRepository (IProgressStatus statusMonitor, string url)
		{
			repoList = null;
			
			IProgressMonitor monitor = ProgressStatusMonitor.GetProgressMonitor (statusMonitor);
		
			monitor.BeginTask ("Updating repositories", service.Configuration.Repositories.Count);
			try {
				int num = service.Configuration.Repositories.Count;
				for (int n=0; n<num; n++) {
					RepositoryRecord rr = (RepositoryRecord) service.Configuration.Repositories [n];
					if (((url == null && rr.Enabled) || rr.Url == url) && !rr.IsReference)
						UpdateRepository (monitor, new Uri (rr.Url), rr);
					monitor.Step (1);
				}
			} catch (Exception ex) {
				statusMonitor.ReportError ("Could not get information from repository", ex);
				return;
			} finally {
				monitor.EndTask ();
			}
			service.SaveConfiguration ();
		}
Ejemplo n.º 18
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);
        }
        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 ();
		}
Ejemplo n.º 21
0
        internal bool LoadAddin(IProgressStatus statusMonitor, string id, bool throwExceptions)
        {
            try {
                if (IsAddinLoaded (id))
                    return true;

                if (!Registry.IsAddinEnabled (id)) {
                    string msg = GettextCatalog.GetString ("Disabled add-ins can't be loaded.");
                    ReportError (msg, id, null, false);
                    if (throwExceptions)
                        throw new InvalidOperationException (msg);
                    return false;
                }

                ArrayList addins = new ArrayList ();
                Stack depCheck = new Stack ();
                ResolveLoadDependencies (addins, depCheck, id, false);
                addins.Reverse ();

                if (statusMonitor != null)
                    statusMonitor.SetMessage ("Loading Addins");

                for (int n=0; n<addins.Count; n++) {

                    if (statusMonitor != null)
                        statusMonitor.SetProgress ((double) n / (double)addins.Count);

                    Addin iad = (Addin) addins [n];
                    if (IsAddinLoaded (iad.Id))
                        continue;

                    if (statusMonitor != null)
                        statusMonitor.SetMessage (string.Format(GettextCatalog.GetString("Loading {0} add-in"), iad.Id));

                    if (!InsertAddin (statusMonitor, iad))
                        return false;
                }
                return true;
            }
            catch (Exception ex) {
                ReportError ("Add-in could not be loaded: " + ex.Message, id, ex, false);
                if (statusMonitor != null)
                    statusMonitor.ReportError ("Add-in '" + id + "' could not be loaded.", ex);
                if (throwExceptions)
                    throw;
                return false;
            }
        }
Ejemplo n.º 22
0
        bool InsertAddin(IProgressStatus statusMonitor, Addin iad)
        {
            try {
                RuntimeAddin p = new RuntimeAddin (this);

                // Read the config file and load the add-in assemblies
                AddinDescription description = p.Load (iad);

                // Register the add-in
                loadedAddins [Addin.GetIdName (p.Id)] = p;

                if (!AddinDatabase.RunningSetupProcess) {
                    // Load the extension points and other addin data

                    foreach (ExtensionNodeSet rel in description.ExtensionNodeSets) {
                        RegisterNodeSet (rel);
                    }

                    foreach (ConditionTypeDescription cond in description.ConditionTypes) {
                        Type ctype = p.GetType (cond.TypeName, true);
                        RegisterCondition (cond.Id, ctype);
                    }
                }

                foreach (ExtensionPoint ep in description.ExtensionPoints)
                    InsertExtensionPoint (p, ep);

                // Fire loaded event
                NotifyAddinLoaded (p);
                ReportAddinLoad (p.Id);
                return true;
            }
            catch (Exception ex) {
                ReportError ("Add-in could not be loaded", iad.Id, ex, false);
                if (statusMonitor != null)
                    statusMonitor.ReportError ("Add-in '" + iad.Id + "' could not be loaded.", ex);
                return false;
            }
        }
Ejemplo n.º 23
0
		/// <summary>
		/// Subscribes to an on-line repository
		/// </summary>
		/// <param name="monitor">
		/// Progress monitor where to show progress status and log
		/// </param>
		/// <param name="url">
		/// URL of the repository
		/// </param>
		/// <param name="updateNow">
		/// When set to True, the repository index will be downloaded.
		/// </param>
		/// <returns>
		/// A repository reference
		/// </returns>
		public AddinRepository RegisterRepository (IProgressStatus monitor, string url, bool updateNow)
		{
			if (string.IsNullOrEmpty (url))
				throw new ArgumentException ("Emtpy url");
			
			if (!url.EndsWith (".mrep")) {
				if (url [url.Length - 1] != '/')
					url += "/";
				url = url + "main.mrep";
			}
			
			RepositoryRecord rr = FindRepositoryRecord (url);
			if (rr != null)
				return rr;

			rr = RegisterRepository (url, false);
			
			try {
				if (updateNow) {
					UpdateRepository (monitor, url);
					rr = FindRepositoryRecord (url);
					Repository rep = rr.GetCachedRepository ();
					if (rep != null)
						rr.Name = rep.Name;
				}
				service.SaveConfiguration ();
				return rr;
			} catch (Exception ex) {
				if (monitor != null)
					monitor.ReportError ("The repository could not be registered", ex);
				if (ContainsRepository (url))
					RemoveRepository (url);
				return null;
			}
		}
Ejemplo n.º 24
0
        List <AddinsEntry> ParseAddinsFile(IProgressStatus monitor, string file, string domain)
        {
            List <AddinsEntry> entries  = new List <AddinsEntry>();
            XmlTextReader      r        = null;
            string             basePath = Path.GetDirectoryName(file);

            try {
                r = new XmlTextReader(FileSystem.OpenTextFile(file));
                r.MoveToContent();
                if (r.IsEmptyElement)
                {
                    return(entries);
                }
                r.ReadStartElement();
                r.MoveToContent();
                while (r.NodeType != XmlNodeType.EndElement)
                {
                    if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory")
                    {
                        bool.TryParse(r.GetAttribute("include-subdirs"), out var subs);
                        string sdom;
                        string share = r.GetAttribute("shared");
                        if (share == "true")
                        {
                            sdom = AddinDatabase.GlobalDomain;
                        }
                        else if (share == "false")
                        {
                            sdom = null;
                        }
                        else
                        {
                            sdom = domain;                             // Inherit the domain
                        }
                        string path = r.ReadElementString().Trim();
                        if (path.Length > 0)
                        {
                            path = Util.NormalizePath(path);
                            entries.Add(new AddinsEntry {
                                Folder = path, Domain = sdom, Recursive = subs
                            });
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "GacAssembly")
                    {
                        string aname = r.ReadElementString().Trim();
                        if (aname.Length > 0)
                        {
                            aname = Util.NormalizePath(aname);
                            aname = Util.GetGacPath(aname);
                            if (aname != null)
                            {
                                // Gac assemblies always use the global domain
                                entries.Add(new AddinsEntry {
                                    Folder = aname, Domain = AddinDatabase.GlobalDomain
                                });
                            }
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "Exclude")
                    {
                        string path = r.ReadElementString().Trim();
                        if (path.Length > 0)
                        {
                            path = Util.NormalizePath(path);
                            if (!Path.IsPathRooted(path))
                            {
                                path = Path.Combine(basePath, path);
                            }
                            ScanContext.AddPathToIgnore(Path.GetFullPath(path));
                        }
                    }
                    else
                    {
                        r.Skip();
                    }
                    r.MoveToContent();
                }
            } catch (Exception ex) {
                if (monitor != null)
                {
                    monitor.ReportError("Could not process addins file: " + file, ex);
                }
            } finally {
                if (r != null)
                {
                    r.Close();
                }
            }
            return(entries);
        }
Ejemplo n.º 25
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 GetFolderInfoForPath (IProgressStatus monitor, string path, out AddinScanFolderInfo folderInfo)
		{
			try {
				folderInfo = AddinScanFolderInfo.Read (fileDatabase, AddinFolderCachePath, path);
				return true;
			}
			catch (Exception ex) {
				folderInfo = null;
				monitor.ReportError ("Could not read folder info file", ex);
				return false;
			}
		}
        public void ScanAddinsFile(IProgressStatus monitor, string file, AddinScanResult scanResult)
        {
            XmlTextReader    r                      = null;
            StringCollection directories            = new StringCollection();
            StringCollection directoriesWithSubdirs = new StringCollection();

            try {
                r = new XmlTextReader(new StreamReader(file));
                r.MoveToContent();
                if (r.IsEmptyElement)
                {
                    return;
                }
                r.ReadStartElement();
                r.MoveToContent();
                while (r.NodeType != XmlNodeType.EndElement)
                {
                    if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory")
                    {
                        string subs = r.GetAttribute("include-subdirs");
                        string path = r.ReadElementString().Trim();
                        if (path.Length > 0)
                        {
                            if (subs == "true")
                            {
                                directoriesWithSubdirs.Add(path);
                            }
                            else
                            {
                                directories.Add(path);
                            }
                        }
                    }
                    else
                    {
                        r.Skip();
                    }
                    r.MoveToContent();
                }
            } catch (Exception ex) {
                monitor.ReportError("Could not process addins file: " + file, ex);
                return;
            } finally {
                if (r != null)
                {
                    r.Close();
                }
            }
            foreach (string d in directories)
            {
                string dir = d;
                if (!Path.IsPathRooted(dir))
                {
                    dir = Path.Combine(Path.GetDirectoryName(file), dir);
                }
                ScanFolder(monitor, dir, scanResult);
            }
            foreach (string d in directoriesWithSubdirs)
            {
                string dir = d;
                if (!Path.IsPathRooted(dir))
                {
                    dir = Path.Combine(Path.GetDirectoryName(file), dir);
                }
                ScanFolderRec(monitor, dir, scanResult);
            }
        }
		public void Repair (IProgressStatus monitor)
		{
			using (fileDatabase.LockWrite ()) {
				try {
					if (Directory.Exists (AddinCachePath))
						Directory.Delete (AddinCachePath, true);
					if (Directory.Exists (AddinFolderCachePath))
						Directory.Delete (AddinFolderCachePath, true);
					if (File.Exists (HostIndexFile))
						File.Delete (HostIndexFile);
				}
				catch (Exception ex) {
					monitor.ReportError ("The add-in registry could not be rebuilt. It may be due to lack of write permissions to the directory: " + AddinDbDir, ex);
				}
			}
			Update (monitor);
		}
Ejemplo n.º 29
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);
        }
Ejemplo n.º 30
0
        public void ScanAddinsFile(IProgressStatus monitor, string file, string domain, AddinScanResult scanResult)
        {
            XmlTextReader r                      = null;
            ArrayList     directories            = new ArrayList();
            ArrayList     directoriesWithSubdirs = new ArrayList();
            string        basePath               = Path.GetDirectoryName(file);

            try {
                r = new XmlTextReader(new StreamReader(file));
                r.MoveToContent();
                if (r.IsEmptyElement)
                {
                    return;
                }
                r.ReadStartElement();
                r.MoveToContent();
                while (r.NodeType != XmlNodeType.EndElement)
                {
                    if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory")
                    {
                        string subs = r.GetAttribute("include-subdirs");
                        string sdom;
                        string share = r.GetAttribute("shared");
                        if (share == "true")
                        {
                            sdom = AddinDatabase.GlobalDomain;
                        }
                        else if (share == "false")
                        {
                            sdom = null;
                        }
                        else
                        {
                            sdom = domain;                             // Inherit the domain
                        }
                        string path = r.ReadElementString().Trim();
                        if (path.Length > 0)
                        {
                            path = Util.NormalizePath(path);
                            if (subs == "true")
                            {
                                directoriesWithSubdirs.Add(new string[] { path, sdom });
                            }
                            else
                            {
                                directories.Add(new string[] { path, sdom });
                            }
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "GacAssembly")
                    {
                        string aname = r.ReadElementString().Trim();
                        if (aname.Length > 0)
                        {
                            aname = Util.NormalizePath(aname);
                            aname = Util.GetGacPath(aname);
                            if (aname != null)
                            {
                                // Gac assemblies always use the global domain
                                directories.Add(new string[] { aname, AddinDatabase.GlobalDomain });
                            }
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "Exclude")
                    {
                        string path = r.ReadElementString().Trim();
                        if (path.Length > 0)
                        {
                            path = Util.NormalizePath(path);
                            if (!Path.IsPathRooted(path))
                            {
                                path = Path.Combine(basePath, path);
                            }
                            scanResult.AddPathToIgnore(Util.GetFullPath(path));
                        }
                    }
                    else
                    {
                        r.Skip();
                    }
                    r.MoveToContent();
                }
            } catch (Exception ex) {
                monitor.ReportError("Could not process addins file: " + file, ex);
                return;
            } finally {
                if (r != null)
                {
                    r.Close();
                }
            }

            foreach (string[] d in directories)
            {
                string dir = d[0];
                if (!Path.IsPathRooted(dir))
                {
                    dir = Path.Combine(basePath, dir);
                }
                ScanFolder(monitor, dir, d[1], scanResult);
            }
            foreach (string[] d in directoriesWithSubdirs)
            {
                string dir = d[0];
                if (!Path.IsPathRooted(dir))
                {
                    dir = Path.Combine(basePath, dir);
                }
                ScanFolderRec(monitor, dir, d[1], scanResult);
            }
        }
 public void ReportError(string message, Exception ex)
 {
     status.ReportError(message, ex);
 }
Ejemplo n.º 32
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.º 33
0
		bool ScanAssembly (IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
		{
			config = null;
				
			try {
				Assembly asm = Util.LoadAssemblyForReflection (filePath);
				
				// Get the config file from the resources, if there is one
				
				string configFile = null;
				foreach (string res in asm.GetManifestResourceNames ()) {
					if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) {
						configFile = res;
						break;
					}
				}
				
				if (configFile != null) {
					using (Stream s = asm.GetManifestResourceStream (configFile)) {
						string asmFile = new Uri (asm.CodeBase).LocalPath;
						config = AddinDescription.Read (s, Path.GetDirectoryName (asmFile));
					}
				}
				else {
					// On this case, only scan the assembly if it has the Addin attribute.
					AddinAttribute att = (AddinAttribute) Attribute.GetCustomAttribute (asm, typeof(AddinAttribute), false);
					if (att == null) {
						config = null;
						return true;
					}
					config = new AddinDescription ();
				}
				
				config.BasePath = Path.GetDirectoryName (filePath);
				config.AddinFile = filePath;
				
				string rasmFile = Path.GetFileName (filePath);
				if (!config.MainModule.Assemblies.Contains (rasmFile))
					config.MainModule.Assemblies.Add (rasmFile);
				
				return ScanDescription (monitor, config, asm, scanResult);
			}
			catch (Exception ex) {
				// Something went wrong while scanning the assembly. We'll ignore it for now.
				monitor.ReportError ("There was an error while scanning assembly: " + filePath, ex);
				return false;
			}
		}
Ejemplo n.º 34
0
 public bool SaveDescription(IProgressStatus monitor, AddinDescription desc, string replaceFileName)
 {
     try {
         if (replaceFileName != null)
             desc.SaveBinary (fileDatabase, replaceFileName);
         else {
             string file = GetDescriptionPath (desc.Domain, desc.AddinId);
             string dir = Path.GetDirectoryName (file);
             if (!fileDatabase.DirExists (dir))
                 fileDatabase.CreateDir (dir);
             if (fileDatabase.Exists (file)) {
                 // Another AddinDescription already exists with the same name.
                 // Create an alternate AddinDescription file
                 int altNum = 2;
                 while (fileDatabase.Exists (file + "_" + altNum))
                     altNum++;
                 file = file + "_" + altNum;
             }
             desc.SaveBinary (fileDatabase, file);
         }
         return true;
     }
     catch (Exception ex) {
         monitor.ReportError ("Add-in info file could not be saved", ex);
         return false;
     }
 }
Ejemplo n.º 35
0
		public void ScanAddinsFile (IProgressStatus monitor, string file, AddinScanResult scanResult)
		{
			XmlTextReader r = null;
			StringCollection directories = new StringCollection ();
			StringCollection directoriesWithSubdirs = new StringCollection ();
			try {
				r = new XmlTextReader (new StreamReader (file));
				r.MoveToContent ();
				if (r.IsEmptyElement)
					return;
				r.ReadStartElement ();
				r.MoveToContent ();
				while (r.NodeType != XmlNodeType.EndElement) {
					if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory") {
						string subs = r.GetAttribute ("include-subdirs");
						string path = r.ReadElementString ().Trim ();
						if (path.Length > 0) {
							if (subs == "true")
								directoriesWithSubdirs.Add (path);
							else
								directories.Add (path);
						}
					}
					else
						r.Skip ();
					r.MoveToContent ();
				}
			} catch (Exception ex) {
				monitor.ReportError ("Could not process addins file: " + file, ex);
				return;
			} finally {
				if (r != null)
					r.Close ();
			}
			foreach (string d in directories) {
				string dir = d;
				if (!Path.IsPathRooted (dir))
					dir = Path.Combine (Path.GetDirectoryName (file), dir);
				ScanFolder (monitor, dir, scanResult);
			}
			foreach (string d in directoriesWithSubdirs) {
				string dir = d;
				if (!Path.IsPathRooted (dir))
					dir = Path.Combine (Path.GetDirectoryName (file), dir);
				ScanFolderRec (monitor, dir, scanResult);
			}
		}
Ejemplo n.º 36
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.º 37
0
 public void ReportError(string message, Exception exception)
 {
     local.ReportError(message, exception);
 }
Ejemplo n.º 38
0
        public void ScanAddinsFile(IProgressStatus monitor, string file, string domain, AddinScanResult scanResult)
        {
            XmlTextReader r = null;
            ArrayList directories = new ArrayList ();
            ArrayList directoriesWithSubdirs = new ArrayList ();
            string basePath = Path.GetDirectoryName (file);

            try {
                r = new XmlTextReader (fs.OpenTextFile (file));
                r.MoveToContent ();
                if (r.IsEmptyElement)
                    return;
                r.ReadStartElement ();
                r.MoveToContent ();
                while (r.NodeType != XmlNodeType.EndElement) {
                    if (r.NodeType == XmlNodeType.Element && r.LocalName == "Directory") {
                        string subs = r.GetAttribute ("include-subdirs");
                        string sdom;
                        string share = r.GetAttribute ("shared");
                        if (share == "true")
                            sdom = AddinDatabase.GlobalDomain;
                        else if (share == "false")
                            sdom = null;
                        else
                            sdom = domain; // Inherit the domain

                        string path = r.ReadElementString ().Trim ();
                        if (path.Length > 0) {
                            path = Util.NormalizePath (path);
                            if (subs == "true")
                                directoriesWithSubdirs.Add (new string[] {path, sdom});
                            else
                                directories.Add (new string[] {path, sdom});
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "GacAssembly") {
                        string aname = r.ReadElementString ().Trim ();
                        if (aname.Length > 0) {
                            aname = Util.NormalizePath (aname);
                            aname = Util.GetGacPath (aname);
                            if (aname != null) {
                                // Gac assemblies always use the global domain
                                directories.Add (new string[] {aname, AddinDatabase.GlobalDomain});
                            }
                        }
                    }
                    else if (r.NodeType == XmlNodeType.Element && r.LocalName == "Exclude") {
                        string path = r.ReadElementString ().Trim ();
                        if (path.Length > 0) {
                            path = Util.NormalizePath (path);
                            if (!Path.IsPathRooted (path))
                                path = Path.Combine (basePath, path);
                            scanResult.AddPathToIgnore (Path.GetFullPath (path));
                        }
                    }
                    else
                        r.Skip ();
                    r.MoveToContent ();
                }
            } catch (Exception ex) {
                monitor.ReportError ("Could not process addins file: " + file, ex);
                return;
            } finally {
                if (r != null)
                    r.Close ();
            }

            foreach (string[] d in directories) {
                string dir = d[0];
                if (!Path.IsPathRooted (dir))
                    dir = Path.Combine (basePath, dir);
                ScanFolder (monitor, dir, d[1], scanResult);
            }
            foreach (string[] d in directoriesWithSubdirs) {
                string dir = d[0];
                if (!Path.IsPathRooted (dir))
                    dir = Path.Combine (basePath, dir);
                ScanFolderRec (monitor, dir, d[1], scanResult);
            }
        }
Ejemplo n.º 39
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);
        }
		public bool ReadAddinDescription (IProgressStatus monitor, string file, out AddinDescription description)
		{
			try {
				description = AddinDescription.ReadBinary (fileDatabase, file);
				if (description != null)
					description.OwnerDatabase = this;
				return true;
			}
			catch (Exception ex) {
				if (monitor == null)
					throw;
				description = null;
				monitor.ReportError ("Could not read folder info file", ex);
				return false;
			}
		}
Ejemplo n.º 41
0
		bool ScanAssembly (IProgressStatus monitor, string filePath, AddinScanResult scanResult, out AddinDescription config)
		{
			config = null;
				
			try {
				IAssemblyReflector reflector = GetReflector (monitor, scanResult, filePath);
				object asm = reflector.LoadAssembly (filePath);
				if (asm == null)
					throw new Exception ("Could not load assembly: " + filePath);
				
				// Get the config file from the resources, if there is one
				
				if (!ScanEmbeddedDescription (monitor, filePath, reflector, asm, out config))
					return false;
				
				if (config == null || config.IsExtensionModel) {
					// In this case, only scan the assembly if it has the Addin attribute.
					AddinAttribute att = (AddinAttribute) reflector.GetCustomAttribute (asm, typeof(AddinAttribute), false);
					if (att == null) {
						config = null;
						return true;
					}

					if (config == null)
						config = new AddinDescription ();
				}
				
				config.SetBasePath (Path.GetDirectoryName (filePath));
				config.AddinFile = filePath;
				
				string rasmFile = Path.GetFileName (filePath);
				if (!config.MainModule.Assemblies.Contains (rasmFile))
					config.MainModule.Assemblies.Add (rasmFile);
				
				return ScanDescription (monitor, reflector, config, asm, scanResult);
			}
			catch (Exception ex) {
				// Something went wrong while scanning the assembly. We'll ignore it for now.
				monitor.ReportError ("There was an error while scanning assembly: " + filePath, ex);
				return false;
			}
		}
		public bool ReadFolderInfo (IProgressStatus monitor, string file, out AddinScanFolderInfo folderInfo)
		{
			try {
				folderInfo = AddinScanFolderInfo.Read (fileDatabase, file);
				return true;
			}
			catch (Exception ex) {
				folderInfo = null;
				monitor.ReportError ("Could not read folder info file", ex);
				return false;
			}
		}
Ejemplo n.º 43
0
		static bool ScanEmbeddedDescription (IProgressStatus monitor, string filePath, IAssemblyReflector reflector, object asm, out AddinDescription config)
		{
			config = null;
			foreach (string res in reflector.GetResourceNames (asm)) {
				if (res.EndsWith (".addin") || res.EndsWith (".addin.xml")) {
					using (Stream s = reflector.GetResourceStream (asm, res)) {
						AddinDescription ad = AddinDescription.Read (s, Path.GetDirectoryName (filePath));
						if (config != null) {
							if (!config.IsExtensionModel && !ad.IsExtensionModel) {
								// There is more than one add-in definition
								monitor.ReportError ("Duplicate add-in definition found in assembly: " + filePath, null);
								return false;
							}
							config = AddinDescription.Merge (config, ad);
						}
						else
							config = ad;
					}
				}
			}
			return true;
		}
		public bool SaveFolderInfo (IProgressStatus monitor, AddinScanFolderInfo folderInfo)
		{
			try {
				folderInfo.Write (fileDatabase, AddinFolderCachePath);
				return true;
			}
			catch (Exception ex) {
				monitor.ReportError ("Could not write folder info file", ex);
				return false;
			}
		}
Ejemplo n.º 45
0
		bool ScanSubmodule (IProgressStatus monitor, ModuleDescription mod, IAssemblyReflector reflector, AddinDescription config, AddinScanResult scanResult, string assemblyName, object asm)
		{
			AddinDescription mconfig;
			ScanEmbeddedDescription (monitor, assemblyName, reflector, asm, out mconfig);
			if (mconfig != null) {
				if (!mconfig.IsExtensionModel) {
					monitor.ReportError ("Submodules can't define new add-ins: " + assemblyName, null);
					return false;
				}
				if (mconfig.OptionalModules.Count != 0) {
					monitor.ReportError ("Submodules can't define nested submodules: " + assemblyName, null);
					return false;
				}
				if (mconfig.ConditionTypes.Count != 0) {
					monitor.ReportError ("Submodules can't define condition types: " + assemblyName, null);
					return false;
				}
				if (mconfig.ExtensionNodeSets.Count != 0) {
					monitor.ReportError ("Submodules can't define extension node sets: " + assemblyName, null);
					return false;
				}
				if (mconfig.ExtensionPoints.Count != 0) {
					monitor.ReportError ("Submodules can't define extension points sets: " + assemblyName, null);
					return false;
				}
				mod.MergeWith (mconfig.MainModule);
			}
			ScanAssemblyContents (reflector, config, mod, asm, scanResult);
			return true;
		}
		bool DatabaseInfrastructureCheck (IProgressStatus monitor)
		{
			// Do some sanity check, to make sure the basic database infrastructure can be created
			
			bool hasChanges = false;
			
			try {
			
				if (!Directory.Exists (AddinCachePath)) {
					Directory.CreateDirectory (AddinCachePath);
					hasChanges = true;
				}
			
				if (!Directory.Exists (AddinFolderCachePath)) {
					Directory.CreateDirectory (AddinFolderCachePath);
					hasChanges = true;
				}
			
				// Make sure we can write in those folders

				Util.CheckWrittableFloder (AddinCachePath);
				Util.CheckWrittableFloder (AddinFolderCachePath);
				
				fatalDatabseError = false;
			}
			catch (Exception ex) {
				monitor.ReportError ("Add-in cache directory could not be created", ex);
				fatalDatabseError = true;
				monitor.Cancel ();
			}
			return hasChanges;
		}
Ejemplo n.º 47
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.º 48
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.º 49
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.º 50
0
        internal bool LoadAddin(IProgressStatus statusMonitor, string id, bool throwExceptions)
        {
            try {
                lock (LocalLock) {
                    if (IsAddinLoaded(id))
                    {
                        return(true);
                    }

                    if (!Registry.IsAddinEnabled(id))
                    {
                        string msg = GettextCatalog.GetString("Disabled add-ins can't be loaded.");
                        ReportError(msg, id, null, false);
                        if (throwExceptions)
                        {
                            throw new InvalidOperationException(msg);
                        }
                        return(false);
                    }

                    ArrayList addins   = new ArrayList();
                    Stack     depCheck = new Stack();
                    ResolveLoadDependencies(addins, depCheck, id, false);
                    addins.Reverse();

                    if (statusMonitor != null)
                    {
                        statusMonitor.SetMessage("Loading Addins");
                    }

                    for (int n = 0; n < addins.Count; n++)
                    {
                        if (statusMonitor != null)
                        {
                            statusMonitor.SetProgress((double)n / (double)addins.Count);
                        }

                        Addin iad = (Addin)addins [n];
                        if (IsAddinLoaded(iad.Id))
                        {
                            continue;
                        }

                        if (statusMonitor != null)
                        {
                            statusMonitor.SetMessage(string.Format(GettextCatalog.GetString("Loading {0} add-in"), iad.Id));
                        }

                        if (!InsertAddin(statusMonitor, iad))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }
            catch (Exception ex) {
                ReportError("Add-in could not be loaded: " + ex.Message, id, ex, false);
                if (statusMonitor != null)
                {
                    statusMonitor.ReportError("Add-in '" + id + "' could not be loaded.", ex);
                }
                if (throwExceptions)
                {
                    throw;
                }
                return(false);
            }
        }
Ejemplo n.º 51
0
        public string BuildPackageFilename(IProgressStatus monitor,string targetDirectory, string filePath)
        {
            var conf = registry.GetAddinDescription(monitor, filePath);
            if (conf == null)
            {
                monitor.ReportError("Could not read add-in file: " + filePath, null);
                return null;
            }

            if (targetDirectory == null)
                targetDirectory = Path.GetDirectoryName (filePath);

            // 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(".__", ".");

            return Path.Combine(targetDirectory, name) + ".mpack";
        }
Ejemplo n.º 52
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.º 53
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);
            }
        }