diff options
-rw-r--r-- | Mono.Addins/ChangeLog | 11 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/AddinDatabase.cs | 88 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/AddinScanResult.cs | 7 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/AddinScanner.cs | 17 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/ProcessProgressStatus.cs | 13 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/SetupProcess.cs | 37 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins/AddinRegistry.cs | 4 |
7 files changed, 134 insertions, 43 deletions
diff --git a/Mono.Addins/ChangeLog b/Mono.Addins/ChangeLog index 373ef1d..476591c 100644 --- a/Mono.Addins/ChangeLog +++ b/Mono.Addins/ChangeLog @@ -1,5 +1,16 @@ 2007-07-02 Lluis Sanchez Gual <lluis@novell.com> + * Mono.Addins/AddinRegistry.cs, Mono.Addins.Database/SetupProcess.cs, + Mono.Addins.Database/AddinScanResult.cs, + Mono.Addins.Database/AddinDatabase.cs, + Mono.Addins.Database/ProcessProgressStatus.cs, + Mono.Addins.Database/AddinScanner.cs: Before scanning a file, log + the file name. If for some reason the scanner process crashes, the + main process will know the name of the file that made it crash and + will restart the scan adding it to the ignore file list. + +2007-07-02 Lluis Sanchez Gual <lluis@novell.com> + * Mono.Addins.mdp, Makefile.am: Added new file. * Mono.Addins/RuntimeAddin.cs, Mono.Addins/Addin.cs, Mono.Addins/IProgressStatus.cs, diff --git a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs index 6589383..94c45d3 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinDatabase.cs @@ -663,37 +663,7 @@ namespace Mono.Addins.Database } } - IProgressStatus scanMonitor = monitor; - bool retry = false; - do { - try { - if (monitor.LogLevel > 1) - monitor.Log ("Looking for addins"); - SetupProcess.ExecuteCommand (scanMonitor, registry.RegistryPath, AddinManager.StartupDirectory, "scan"); - retry = false; - } - catch (Exception ex) { - 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 (ex is ProcessFailedException && !retry) { - monitor.ReportError ("Add-in scan operation failed. The Mono 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) { - monitor.ReportError ("Add-in scan operation failed", (ex is ProcessFailedException ? null : ex)); - monitor.Cancel (); - return; - } - } - } - while (retry); + RunScannerProcess (monitor); ResetCachedData (); } @@ -721,6 +691,56 @@ namespace Mono.Addins.Database } } + void RunScannerProcess (IProgressStatus monitor) + { + IProgressStatus scanMonitor = monitor; + ArrayList pparams = new ArrayList (); + pparams.Add (null); // scan folder + + bool retry = false; + do { + try { + if (monitor.LogLevel > 1) + monitor.Log ("Looking for addins"); + SetupProcess.ExecuteCommand (scanMonitor, registry.RegistryPath, AddinManager.StartupDirectory, "scan", (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 Mono 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) { + monitor.ReportError ("Add-in scan operation failed", (ex is ProcessFailedException ? null : ex)); + monitor.Cancel (); + return; + } + } + } + while (retry); + } + bool DatabaseInfrastructureCheck (IProgressStatus monitor) { // Do some sanity check, to make sure the basic database infrastructure can be created @@ -765,9 +785,11 @@ namespace Mono.Addins.Database } } - internal void ScanFolders (IProgressStatus monitor, string folderToScan) + internal void ScanFolders (IProgressStatus monitor, string folderToScan, StringCollection filesToIgnore) { - ScanFolders (monitor, new AddinScanResult ()); + AddinScanResult res = new AddinScanResult (); + res.FilesToIgnore = filesToIgnore; + ScanFolders (monitor, res); } internal void ScanFolders (IProgressStatus monitor, AddinScanResult scanResult) diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs b/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs index 10ef046..42af5f4 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanResult.cs @@ -31,6 +31,7 @@ using System; using System.Reflection; using System.IO; using System.Collections; +using System.Collections.Specialized; using Mono.Addins.Description; namespace Mono.Addins.Database @@ -54,6 +55,7 @@ namespace Mono.Addins.Database public bool changesFound; public bool CheckOnly; public bool LocateAssembliesOnly; + public StringCollection FilesToIgnore; public bool ChangesFound { get { return changesFound; } @@ -70,6 +72,11 @@ namespace Mono.Addins.Database } } + public bool IgnoreFile (string file) + { + return FilesToIgnore != null && FilesToIgnore.Contains (file); + } + public void AddAddinToScan (string addinId) { if (!AddinsToScan.Contains (addinId)) diff --git a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs index ff24143..3d26522 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinScanner.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinScanner.cs @@ -168,9 +168,19 @@ namespace Mono.Addins.Database public void ScanFile (IProgressStatus monitor, string file, AddinScanFolderInfo folderInfo, AddinScanResult scanResult) { + if (scanResult.IgnoreFile (file)) { + // The file must be ignored. Maybe it caused a crash in a previous scan. + 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; @@ -274,6 +284,7 @@ namespace Mono.Addins.Database } finally { folderInfo.SetLastScanTime (file, scannedAddinId, scannedIsRoot, File.GetLastWriteTime (file), !scanSuccessful); + monitor.Log ("plog:endscan"); } } @@ -284,6 +295,8 @@ namespace Mono.Addins.Database if (monitor.LogLevel > 1) monitor.Log ("Scanning file: " + file); + monitor.Log ("plog:scan:" + file); + try { string ext = Path.GetExtension (file); bool scanSuccessful; @@ -306,6 +319,8 @@ namespace Mono.Addins.Database } catch (Exception ex) { monitor.ReportError ("Unexpected error while scanning file: " + file, ex); + } finally { + monitor.Log ("plog:endscan"); } return config; } diff --git a/Mono.Addins/Mono.Addins.Database/ProcessProgressStatus.cs b/Mono.Addins/Mono.Addins.Database/ProcessProgressStatus.cs index 612c7c1..3af2982 100644 --- a/Mono.Addins/Mono.Addins.Database/ProcessProgressStatus.cs +++ b/Mono.Addins/Mono.Addins.Database/ProcessProgressStatus.cs @@ -28,6 +28,7 @@ using System; +using System.Collections.Specialized; using System.IO; namespace Mono.Addins.Database @@ -54,7 +55,12 @@ namespace Mono.Addins.Database public void Log (string msg) { - Console.WriteLine ("process-ps-log:" + Encode (msg)); + if (msg.StartsWith ("plog:")) + // This is an special type of log that will be provided to the + // main process in case of a crash in the setup process + Console.WriteLine ("process-ps-plog:" + Encode (msg.Substring (5))); + else + Console.WriteLine ("process-ps-log:" + Encode (msg)); } public void ReportWarning (string message) @@ -101,7 +107,7 @@ namespace Mono.Addins.Database return msg.Replace ("&a", "&"); } - public static void MonitorProcessStatus (IProgressStatus monitor, TextReader reader) + public static void MonitorProcessStatus (IProgressStatus monitor, TextReader reader, StringCollection progessLog) { string line; string exceptionText = null; @@ -138,6 +144,9 @@ namespace Mono.Addins.Database case "process-ps-cancel": monitor.Cancel (); break; + case "process-ps-plog": + progessLog.Add (Decode (txt)); + break; default: wasTag = false; break; diff --git a/Mono.Addins/Mono.Addins.Database/SetupProcess.cs b/Mono.Addins/Mono.Addins.Database/SetupProcess.cs index 4d3f1af..0cf3323 100644 --- a/Mono.Addins/Mono.Addins.Database/SetupProcess.cs +++ b/Mono.Addins/Mono.Addins.Database/SetupProcess.cs @@ -28,6 +28,7 @@ using System; +using System.Collections.Specialized; using System.IO; using System.Text; using System.Diagnostics; @@ -42,11 +43,17 @@ namespace Mono.Addins.Database string asm = new Uri (typeof(SetupProcess).Assembly.CodeBase).LocalPath; string verboseParam = monitor.LogLevel.ToString (); + // Arguments string + StringBuilder sb = new StringBuilder (); + sb.Append (verboseParam).Append (' ').Append (name); + foreach (string arg in args) + sb.Append (" \"").Append (arg).Append ("\""); + Process process = new Process (); if (Util.IsWindows) - process.StartInfo = new ProcessStartInfo (asm, verboseParam + " " + name + " " + string.Join (" ", args)); + process.StartInfo = new ProcessStartInfo (asm, sb.ToString ()); else - process.StartInfo = new ProcessStartInfo ("mono", "--debug " + asm + " " + verboseParam + " " + name + " " + string.Join (" ", args)); + process.StartInfo = new ProcessStartInfo ("mono", "--debug " + asm + " " + sb.ToString ()); process.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardInput = true; @@ -67,10 +74,11 @@ namespace Mono.Addins.Database // string rr = process.StandardOutput.ReadToEnd (); // Console.WriteLine (rr); - ProcessProgressStatus.MonitorProcessStatus (monitor, process.StandardOutput); + StringCollection progessLog = new StringCollection (); + ProcessProgressStatus.MonitorProcessStatus (monitor, process.StandardOutput, progessLog); process.WaitForExit (); if (process.ExitCode != 0) - throw new ProcessFailedException (); + throw new ProcessFailedException (progessLog); } public static int Main (string[] args) @@ -86,7 +94,12 @@ namespace Mono.Addins.Database switch (args [1]) { case "scan": - reg.ScanFolders (monitor, args.Length > 2 ? args [2] : null); + string folder = args.Length > 2 ? args [2] : null; + if (folder.Length == 0) folder = null; + StringCollection filesToIgnore = new StringCollection (); + for (int n=3; n<args.Length; n++) + filesToIgnore.Add (args[n]); + reg.ScanFolders (monitor, folder, filesToIgnore); break; case "get-desc": reg.ParseAddin (monitor, args[2], args[3]); @@ -102,5 +115,19 @@ namespace Mono.Addins.Database class ProcessFailedException: Exception { + StringCollection progessLog; + + public ProcessFailedException (StringCollection progessLog) + { + this.progessLog = progessLog; + } + + public StringCollection ProgessLog { + get { return progessLog; } + } + + public string LastLog { + get { return progessLog.Count > 0 ? progessLog [progessLog.Count - 1] : ""; } + } } } diff --git a/Mono.Addins/Mono.Addins/AddinRegistry.cs b/Mono.Addins/Mono.Addins/AddinRegistry.cs index be9a146..363587b 100644 --- a/Mono.Addins/Mono.Addins/AddinRegistry.cs +++ b/Mono.Addins/Mono.Addins/AddinRegistry.cs @@ -196,9 +196,9 @@ namespace Mono.Addins return database.AddinDependsOn (id1, id2); } - internal void ScanFolders (IProgressStatus monitor, string folderToScan) + internal void ScanFolders (IProgressStatus monitor, string folderToScan, StringCollection filesToIgnore) { - database.ScanFolders (monitor, folderToScan); + database.ScanFolders (monitor, folderToScan, filesToIgnore); } internal void ParseAddin (IProgressStatus progressStatus, string file, string outFile) |