diff options
author | Lluis Sanchez <lluis@xamarin.com> | 2018-04-10 14:00:14 +0300 |
---|---|---|
committer | Lluis Sanchez <lluis@xamarin.com> | 2018-04-10 14:06:00 +0300 |
commit | 712f29353b8a73235689fa8f6dc9c4ceaf51571b (patch) | |
tree | ec74fe2eb38a7b12f6e293a47ef440a130fa5f95 /Mono.Addins | |
parent | 192492f76892e38692be8fb2c6e577b91624b3d3 (diff) |
Fix crash when re-scanning add-in folders
When using pre-generated add-in scan files, sometimes
updating the add-in db may cause a crash. That's because
a post-update process tries to refresh the domain of each add-in
and it is done by getting the domain of the folder that contains
the add-in. When using scan data files, there is only folder info
for the root directory, not for each add-in directory, so the domain
query fails.
The solution is to not try to refresh the domain. A domain change of
an add-in at run-time is an unlikely scenario that in general is not
properly supported, and it requires a restart.
Diffstat (limited to 'Mono.Addins')
-rw-r--r-- | Mono.Addins/Mono.Addins.Database/AddinFileSystemExtension.cs | 4 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins/Addin.cs | 14 | ||||
-rwxr-xr-x | Mono.Addins/Mono.Addins/AddinEngine.cs | 61 | ||||
-rw-r--r-- | Mono.Addins/Mono.Addins/AddinManager.cs | 8 |
4 files changed, 72 insertions, 15 deletions
diff --git a/Mono.Addins/Mono.Addins.Database/AddinFileSystemExtension.cs b/Mono.Addins/Mono.Addins.Database/AddinFileSystemExtension.cs index bb015d7..ce5f6ae 100644 --- a/Mono.Addins/Mono.Addins.Database/AddinFileSystemExtension.cs +++ b/Mono.Addins/Mono.Addins.Database/AddinFileSystemExtension.cs @@ -192,6 +192,10 @@ namespace Mono.Addins.Database return reflector; } + /// <summary> + /// Deletes a file + /// </summary> + /// <param name="filePath">File path.</param> public virtual void DeleteFile (string filePath) { File.Delete (filePath); diff --git a/Mono.Addins/Mono.Addins/Addin.cs b/Mono.Addins/Mono.Addins/Addin.cs index 8f7cc17..47f9917 100644 --- a/Mono.Addins/Mono.Addins/Addin.cs +++ b/Mono.Addins/Mono.Addins/Addin.cs @@ -270,9 +270,17 @@ namespace Mono.Addins internal void ResetCachedData () { - // The domain may have changed - if (sourceFile != null) - domain = database.GetFolderDomain (null, Path.GetDirectoryName (sourceFile)); + // The domain may have changed (?!) + + // This check has been commented out because GetFolderDomain will fail if sourceFile changed + // or if there is no folder info for the add-in (it may happen when using pre-generated add-in + // scan data files). + // A domain change at run-time is an unlikely scenario and not properly supported anyway in + // other parts of the code. In general, changes in an already loaded add-in are not supported. + +// if (sourceFile != null) +// domain = database.GetFolderDomain (null, Path.GetDirectoryName (sourceFile)); + desc = null; addin = null; } diff --git a/Mono.Addins/Mono.Addins/AddinEngine.cs b/Mono.Addins/Mono.Addins/AddinEngine.cs index d027aec..25bd3be 100755 --- a/Mono.Addins/Mono.Addins/AddinEngine.cs +++ b/Mono.Addins/Mono.Addins/AddinEngine.cs @@ -105,7 +105,7 @@ namespace Mono.Addins Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - Initialize (asm, configDir, null, null); + Initialize (asm, null, configDir, null, null); } /// <summary> @@ -137,7 +137,7 @@ namespace Mono.Addins Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - Initialize (asm, configDir, addinsDir, null); + Initialize (asm, null, configDir, addinsDir, null); } /// <summary> @@ -174,19 +174,64 @@ namespace Mono.Addins Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - Initialize (asm, configDir, addinsDir, databaseDir); + Initialize (asm, null, configDir, addinsDir, databaseDir); } - internal void Initialize (Assembly startupAsm, string configDir, string addinsDir, string databaseDir) + /// <summary> + /// Initializes the add-in engine. + /// </summary> + /// <param name='configDir'> + /// Location of the add-in registry. + /// </param> + /// <param name='addinsDir'> + /// Add-ins directory. If the path is relative, it is considered to be relative + /// to the configDir directory. + /// </param> + /// <param name='databaseDir'> + /// Location of the add-in database. If the path is relative, it is considered to be relative + /// to the configDir directory. + /// </param> + /// <param name='startupDirectory'> + /// Statup directory. This is the directory where add-in scans will start. + /// </param> + /// <remarks> + /// The add-in engine needs to be initialized before doing any add-in operation. + /// Configuration information about the add-in registry will be stored in the + /// provided location. The add-in engine will look for add-ins in the provided + /// 'addinsDir' directory. Cached information about add-ins will be stored in + /// the 'databaseDir' directory. + /// + /// When specifying a path, it is possible to use a special folder name as root. + /// For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced + /// by the location of the Environment.SpecialFolder.Personal folder. Any value + /// of the Environment.SpecialFolder enumeration can be used (always between square + /// brackets) + /// </remarks> + public void Initialize (string configDir, string addinsDir, string databaseDir, string startupDirectory) + { + if (initialized) + return; + + Assembly asm = Assembly.GetEntryAssembly (); + if (asm == null) asm = Assembly.GetCallingAssembly (); + Initialize (null, startupDirectory, configDir, addinsDir, databaseDir); + } + + internal void Initialize (Assembly startupAsm, string customStartupDirectory, string configDir, string addinsDir, string databaseDir) { lock (LocalLock) { if (initialized) return; Initialize (this); - - string asmFile = new Uri (startupAsm.CodeBase).LocalPath; - startupDirectory = System.IO.Path.GetDirectoryName (asmFile); + + string asmFile = null; + + if (startupAsm != null) { + asmFile = new Uri (startupAsm.CodeBase).LocalPath; + startupDirectory = System.IO.Path.GetDirectoryName (asmFile); + } else + startupDirectory = customStartupDirectory; string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY"); if (customDir != null && customDir.Length > 0) @@ -197,7 +242,7 @@ namespace Mono.Addins else registry = new AddinRegistry (this, configDir, startupDirectory, addinsDir, databaseDir); - if (registry.CreateHostAddinsFile (asmFile) || registry.UnknownDomain) + if ((asmFile != null && registry.CreateHostAddinsFile (asmFile)) || registry.UnknownDomain) registry.Update (new ConsoleProgressStatus (false)); initialized = true; diff --git a/Mono.Addins/Mono.Addins/AddinManager.cs b/Mono.Addins/Mono.Addins/AddinManager.cs index 11f3f81..6365f5a 100644 --- a/Mono.Addins/Mono.Addins/AddinManager.cs +++ b/Mono.Addins/Mono.Addins/AddinManager.cs @@ -59,7 +59,7 @@ namespace Mono.Addins // Code not shared with the other Initialize since I need to get the calling assembly Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - AddinEngine.Initialize (asm, null, null, null); + AddinEngine.Initialize (asm, null, null, null, null); } /// <summary> @@ -84,7 +84,7 @@ namespace Mono.Addins { Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - AddinEngine.Initialize (asm, configDir, null, null); + AddinEngine.Initialize (asm, null, configDir, null, null); } /// <summary> @@ -113,7 +113,7 @@ namespace Mono.Addins { Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - AddinEngine.Initialize (asm, configDir, addinsDir, null); + AddinEngine.Initialize (asm, null, configDir, addinsDir, null); } /// <summary> @@ -147,7 +147,7 @@ namespace Mono.Addins { Assembly asm = Assembly.GetEntryAssembly (); if (asm == null) asm = Assembly.GetCallingAssembly (); - AddinEngine.Initialize (asm, configDir, addinsDir, databaseDir); + AddinEngine.Initialize (asm, null, configDir, addinsDir, databaseDir); } /// <summary> |