I had an interesting problem with the Managed Extensibility Framework yesterday. I’m using the DirectoryCatalog to load assemblies from a given directory. Pretty standard stuff. When I tested my host on my developer machine, it got the works on my machine badge, but when I ran the host on one of our servers, it ignored all the assemblies.
Nothing loaded …
Hmm …
It turns out, after much digging and help from my Twitter crew, that the assembly loader that MEF’s DirectoryCatalog uses ignores any files that have a URL Zone set. I described these zones in detail in my previous post here:
http://mikehadlow.blogspot.com/2011/07/detecting-and-changing-files-internet.html
Because we copy our plugins from a file share, Windows was marking them as belonging to the Intranet Zone. Thus the odd only-when-deployed behaviour.
How you deal with this depends on whether you think that files marked in this way represent a security threat or not. If you do, the best policy is to detect any assemblies in your DirectoryCatalogue directory that have a Zone set and log them. You can do that with the System.Security.Policy.Zone class:
var zone = Zone.CreateFromUrl("file:///C:/temp/ZoneTest.doc");
if (zone.SecurityZone != SecurityZone.MyComputer)
{
Console.WriteLine("File is blocked");
}
Console.Out.WriteLine("zone.SecurityZone = {0}", zone.SecurityZone);
If you don’t consider files copied from elsewhere a security concern, but rather a feature of your operating procedure, then you can clear the Zone flags from all the assemblies in the directory with the help of Richard Deeming’s Trinet.Core.IO.Ntfs library. I wrote a little class using this:
public class UrlZoneService
{
public static void ClearUrlZonesInDirectory(string directoryPath)
{
foreach (var filePath in Directory.EnumerateFiles(directoryPath))
{
var fileInfo = new FileInfo(filePath);
fileInfo.DeleteAlternateDataStream("Zone.Identifier");
}
}
}
I just run this before initiating my DirectoryCatalogue and now network copied assemblies load as expected.
This should be a quadroople rant!!!! I just spent all day trying to figure out why one of my plugins wasn't loading on a remote site. I was copying over the latest plugins via. ftp. It worked on the ASP.NET app since I was doing impersonation, but in the Windows service, since it was only running as local service, it wouldn't load the damn plugin! Thank you for this, I never would have figured this out.
ReplyDeleteI had this error running the MEF Sample Code (Calculator Sample). Was getting a lot of frustration until I saw your post and remembered that when you unzip a file using windows extractor, it maintains the files "blocked". Using 7zip it worked. :D
ReplyDelete