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); } }
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); }
/// <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); } }
/// <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); } }
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); } }
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); } }
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); } }
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); } }
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; } }
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"); } }
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; } }
/// <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 (); }
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 (); }
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; } }
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; } }
/// <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; } }
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); }
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); }
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); }
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); }
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); } }
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; } }
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; } }
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 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; }
public void ReportError(string message, Exception exception) { local.ReportError(message, exception); }
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); } }
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; } }
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; } }
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; } }
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; }
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); }
/// <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(); }
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"); } }
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); } }
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"; }
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(); }
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); } }