Inheritance: System.MarshalByRefObject
        public AddinScanDataFileGenerator(AddinDatabase database, AddinRegistry registry, string rootFolder) : base(database)
        {
            this.database   = database;
            this.rootFolder = Path.GetFullPath(rootFolder);

            assemblyIndex = new AssemblyIndex();
            locator       = new AssemblyLocator(database, registry, assemblyIndex);
            scanner       = new AddinScanner(database, locator);
        }
		public void ParseAddin (IProgressStatus progressStatus, string file, string outFile, bool inProcess)
		{
			if (!inProcess) {
				SetupProcess.ExecuteCommand (progressStatus, registry.RegistryPath, AddinManager.StartupDirectory, "get-desc", Path.GetFullPath (file), outFile);
				return;
			}
			
			using (fileDatabase.LockRead ())
			{
				// First of all, check if the file belongs to a registered add-in
				AddinScanFolderInfo finfo;
				if (GetFolderInfoForPath (progressStatus, Path.GetDirectoryName (file), out finfo) && finfo != null) {
					AddinFileInfo afi = finfo.GetAddinFileInfo (file);
					if (afi != null && afi.AddinId != null) {
						AddinDescription adesc;
						if (afi.IsRoot)
							GetHostDescription (progressStatus, afi.AddinId, file, out adesc);
						else
							GetAddinDescription (progressStatus, afi.AddinId, out adesc);
						if (adesc != null)
							adesc.Save (outFile);
						return;
					}
				}
				
				
				AddinScanner scanner = new AddinScanner (this);
				
				SingleFileAssemblyResolver res = new SingleFileAssemblyResolver (progressStatus, registry, scanner);
				ResolveEventHandler resolver = new ResolveEventHandler (res.Resolve);

				EventInfo einfo = typeof(AppDomain).GetEvent ("ReflectionOnlyAssemblyResolve");
				
				try {
					AppDomain.CurrentDomain.AssemblyResolve += resolver;
					if (einfo != null) einfo.AddEventHandler (AppDomain.CurrentDomain, resolver);
				
					AddinDescription desc = scanner.ScanSingleFile (progressStatus, file, new AddinScanResult ());
					if (desc != null)
						desc.Save (outFile);
				}
				finally {
					AppDomain.CurrentDomain.AssemblyResolve -= resolver;
					if (einfo != null) einfo.RemoveEventHandler (AppDomain.CurrentDomain, resolver);
				}
			}
		}
		public SingleFileAssemblyResolver (IProgressStatus progressStatus, AddinRegistry registry, AddinScanner scanner)
		{
			this.scanner = scanner;
			this.registry = registry;
			this.progressStatus = progressStatus;
		}
		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.º 5
0
        public void ParseAddin(IProgressStatus progressStatus, string domain, string file, string outFile, bool inProcess)
        {
            if (!inProcess) {
                ISetupHandler setup = GetSetupHandler ();
                setup.GetAddinDescription (progressStatus, registry, Path.GetFullPath (file), outFile);
                return;
            }

            using (fileDatabase.LockRead ())
            {
                // First of all, check if the file belongs to a registered add-in
                AddinScanFolderInfo finfo;
                if (GetFolderInfoForPath (progressStatus, Path.GetDirectoryName (file), out finfo) && finfo != null) {
                    AddinFileInfo afi = finfo.GetAddinFileInfo (file);
                    if (afi != null && afi.IsAddin) {
                        AddinDescription adesc;
                        GetAddinDescription (progressStatus, afi.Domain, afi.AddinId, file, out adesc);
                        if (adesc != null)
                            adesc.Save (outFile);
                        return;
                    }
                }

                AddinScanResult sr = new AddinScanResult ();
                sr.Domain = domain;
                AddinScanner scanner = new AddinScanner (this, sr, progressStatus);

                SingleFileAssemblyResolver res = new SingleFileAssemblyResolver (progressStatus, registry, scanner);
                ResolveEventHandler resolver = new ResolveEventHandler (res.Resolve);

                EventInfo einfo = typeof(AppDomain).GetEvent ("ReflectionOnlyAssemblyResolve");

                try {
                    AppDomain.CurrentDomain.AssemblyResolve += resolver;
                    if (einfo != null) einfo.AddEventHandler (AppDomain.CurrentDomain, resolver);

                    AddinDescription desc = scanner.ScanSingleFile (progressStatus, file, sr);
                    if (desc != null) {
                        // Reset the xml doc so that it is not reused when saving. We want a brand new document
                        desc.ResetXmlDoc ();
                        desc.Save (outFile);
                    }
                }
                finally {
                    AppDomain.CurrentDomain.AssemblyResolve -= resolver;
                    if (einfo != null) einfo.RemoveEventHandler (AppDomain.CurrentDomain, resolver);
                }
            }
        }