public AddinFileInfo SetLastScanTime(string file, string addinId, bool isRoot, DateTime time, bool scanError, string scanDataMD5 = null)
        {
            AddinFileInfo info = (AddinFileInfo)files [file];

            if (info == null)
            {
                info         = new AddinFileInfo();
                info.File    = file;
                files [file] = info;
            }
            info.LastScan    = time;
            info.AddinId     = addinId;
            info.IsRoot      = isRoot;
            info.ScanError   = scanError;
            info.ScanDataMD5 = scanDataMD5;
            if (addinId != null)
            {
                info.Domain = GetDomain(isRoot);
            }
            else
            {
                info.Domain = null;
            }
            return(info);
        }
        public DateTime GetLastScanTime(string file)
        {
            AddinFileInfo info = (AddinFileInfo)files [file];

            if (info == null)
            {
                return(DateTime.MinValue);
            }
            else
            {
                return(info.LastScan);
            }
        }
Exemple #3
0
        public void SetLastScanTime(string file, string addinId, bool isRoot, DateTime time, bool scanError)
        {
            AddinFileInfo info = (AddinFileInfo)files [file];

            if (info == null)
            {
                info         = new AddinFileInfo();
                info.File    = file;
                files [file] = info;
            }
            info.LastScan  = time;
            info.AddinId   = addinId;
            info.IsRoot    = isRoot;
            info.ScanError = scanError;
        }
        void RegisterFileToScan(IProgressStatus monitor, string file, AddinScanResult scanResult, AddinScanFolderInfo folderInfo)
        {
            if (scanResult.LocateAssembliesOnly)
            {
                return;
            }

            AddinFileInfo finfo = folderInfo.GetAddinFileInfo(file);
            bool          added = false;

            if (finfo != null && File.GetLastWriteTime(file) == finfo.LastScan && !scanResult.RegenerateAllData)
            {
                if (finfo.ScanError)
                {
                    // Always schedule the file for scan if there was an error in a previous scan.
                    // However, don't set ChangesFound=true, in this way if there isn't any other
                    // change in the registry, the file won't be scanned again.
                    scanResult.AddFileToScan(file, folderInfo);
                    added = true;
                }

                if (finfo.AddinId == null || finfo.AddinId.Length == 0)
                {
                    return;
                }
                if (!finfo.IsRoot)
                {
                    if (database.AddinDescriptionExists(finfo.AddinId))
                    {
                        return;
                    }
                }
                else
                {
                    if (database.HostDescriptionExists(finfo.AddinId, file))
                    {
                        return;
                    }
                }
            }

            scanResult.ChangesFound = true;

            if (!scanResult.CheckOnly && !added)
            {
                scanResult.AddFileToScan(file, folderInfo);
            }
        }
        void RegisterFileToScan(IProgressStatus monitor, string file, AddinScanResult scanResult, AddinScanFolderInfo folderInfo)
        {
            if (scanResult.LocateAssembliesOnly)
            {
                return;
            }

            AddinFileInfo finfo = folderInfo.GetAddinFileInfo(file);
            bool          added = false;

            if (finfo != null && (!finfo.IsAddin || finfo.Domain == folderInfo.GetDomain(finfo.IsRoot)) && File.GetLastWriteTime(file) == finfo.LastScan && !scanResult.RegenerateAllData)
            {
                if (finfo.ScanError)
                {
                    // Always schedule the file for scan if there was an error in a previous scan.
                    // However, don't set ChangesFound=true, in this way if there isn't any other
                    // change in the registry, the file won't be scanned again.
                    scanResult.AddFileToScan(file, folderInfo);
                    added = true;
                }

                if (!finfo.IsAddin)
                {
                    return;
                }

                if (database.AddinDescriptionExists(finfo.Domain, finfo.AddinId))
                {
                    // It is an add-in and it has not changed. Paths in the ignore list
                    // are still valid, so they can be used.
                    if (finfo.IgnorePaths != null)
                    {
                        scanResult.AddPathsToIgnore(finfo.IgnorePaths);
                    }
                    return;
                }
            }

            scanResult.ChangesFound = true;

            if (!scanResult.CheckOnly && !added)
            {
                scanResult.AddFileToScan(file, folderInfo);
            }
        }
		public void SetLastScanTime (string file, string addinId, bool isRoot, DateTime time, bool scanError)
		{
			AddinFileInfo info = (AddinFileInfo) files [file];
			if (info == null) {
				info = new AddinFileInfo ();
				info.File = file;
				files [file] = info;
			}
			info.LastScan = time;
			info.AddinId = addinId;
			info.IsRoot = isRoot;
			info.ScanError = scanError;
		}
        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);
            }
        }
        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");
            }
        }
		public AddinFileInfo SetLastScanTime (string file, string addinId, bool isRoot, DateTime time, bool scanError)
		{
			AddinFileInfo info = (AddinFileInfo) files [file];
			if (info == null) {
				info = new AddinFileInfo ();
				info.File = file;
				files [file] = info;
			}
			info.LastScan = time;
			info.AddinId = addinId;
			info.IsRoot = isRoot;
			info.ScanError = scanError;
			if (addinId != null)
				info.Domain = GetDomain (isRoot);
			else
				info.Domain = null;
			return info;
		}