On Windows, if the addin registry is accessed using a UNC path (e.g., "\server\share\directory") instead of a local path (e.g., "X:\directory"). Mono.Addins will mangle the path name upon initialization, which can result in a number
of different (usually fatal) exceptions. For example, on my workstation MonoDevelop 2.4.1 reports the following error:
System.IO.FileNotFoundException: Could not find file '\\irtnog.net\roothome\xenophon\Library\MonoDevelop\addin-db-001\hosts'.
File name: '\\irtnog.net\roothome\xenophon\Library\MonoDevelop\addin-db-001\hosts'
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.InternalCreateDirectory(String fullPath, String path, DirectorySecurity dirSecurity)
at System.IO.Directory.CreateDirectory(String path, DirectorySecurity directorySecurity)
at Mono.Addins.AddinRegistry.CreateHostAddinsFile(String hostFile)
at Mono.Addins.AddinEngine.Initialize(String configDir, Assembly startupAsm)
at Mono.Addins.AddinManager.Initialize(String configDir)
at MonoDevelop.Core.Runtime.Initialize(Boolean updateAddinRegistry)
FATAL ERROR [2011-01-11 13:36:36Z]: MonoDevelop failed to start. Some of the assemblies required to run MonoDevelop (for example gtk
-sharp, gnome-sharp or gtkhtml-sharp) may not be properly installed in the GAC.
System.InvalidOperationException: Add-in engine not initialized.
at Mono.Addins.AddinManager.GetExtensionObjects(String path)
at MonoDevelop.Ide.IdeStartup.Run(String args)
at MonoDevelop.Startup.MonoDevelopMain.Main(String args)
In my case, the system administrator has set a Group Policy Object (GPO) that redirects the AppData\Roaming folder to a network share, which here is \irtnog.net\root\home\xenophon\Library. However, according to my testing, the error will occur regardless of
how Mono.Addins selects the adding registry directory. For example, MonoDevelop raises the same exception if I set MONO_ADDINS_REGISTRY to a UNC path.
To work around this problem, one can set MONO_ADDINS_REGISTRY to a local path, even if that path refers to a drive letter mapped to a network share. In my case, U: maps to \irtnog.net\root\home\xenophon, so I can get MonoDevelop to start normally if I set MONO_ADDINS_REGISTRY
As you can see from my examples, Mono.Addins.Database.Util.GetFullPath() removes the directory separator between the root of the path and its remaining parts. The code assumes that the root includes a trailing directory separator (which is not the case for
UNC paths), so in the last line of the method, when it rejoins the root together with the other parts of the path, it neglects to check for a trailing slash in the root and add one in if it is missing.
There probably several ways to fix this. I would probably use System.IO.Path.Combine(), because the resulting code would be more portable. My patch (attached) uses the "root" local variable to hold the new path, which is built up using Path.Combine()
over each iteration of GetFullPath's for loop. I also renamed "root" to "newPath" to make the variable's revised purpose clearer to other readers and removed the now superfluous "newParts" variable. Please note that my patch is
against release 0.5 of Mono.Addins in the unified diff format.