private static Assembly LoadAssemblyByName(string name, bool reflectOnly)
{
// Be nice & Thread Save
lock (_lock)
{
try
{
if (_missingAssemblies.Contains(name)) return null; // shortcut
AssemblyName assemblyName = new AssemblyName(name);
string baseName = assemblyName.Name;
// Prevent loading twice, it doesn't help
if (baseName == _currentlyLoading) return null;
_currentlyLoading = baseName;
// search for file to load
string sourceDll = LocateAssembly(baseName, assemblyName.CultureInfo);
// assembly could not be found?
if (String.IsNullOrEmpty(sourceDll))
{
_missingAssemblies.Add(name);
return null;
}
// Copy files to destination folder, unless the target file exists
// the folder should have been cleared on initialisation and once
// an assembly is loaded, we cannot re-load the assembly anyways.
string dllToLoad;
if (EnableShadowCopy)
{
dllToLoad = Path.Combine(TargetAssemblyFolder, baseName + ".dll");
Log.DebugFormat("Loading {0} (from {1}){2}", sourceDll, dllToLoad, reflectOnly ? " for reflection" : String.Empty);
try
{
if (!File.Exists(dllToLoad))
{
File.Copy(sourceDll, dllToLoad, true);
// Also copy .PDB Files.
string sourcePDBFile = PdbFromDll(sourceDll);
string targetPDBFile = PdbFromDll(dllToLoad);
if (File.Exists(sourcePDBFile))
{
File.Copy(sourcePDBFile, targetPDBFile, true);
}
// and all resources
foreach (var res in Directory.GetFiles(Path.GetDirectoryName(sourceDll), Path.GetFileNameWithoutExtension(sourceDll) + ".resources.dll", SearchOption.AllDirectories))
{
try
{
var lang = Path.GetFileName(Path.GetDirectoryName(res));
var targetRes = Path.Combine(Path.GetDirectoryName(dllToLoad), lang);
targetRes = Path.Combine(targetRes, Path.GetFileName(res));
Directory.CreateDirectory(Path.GetDirectoryName(targetRes));
File.Copy(res, targetRes, true);
}
catch (Exception ex)
{
Log.Warn("Error loading satellite assembly: " + ex.Message);
}
}
}
}
catch (Exception ex)
{
Log.Warn("Error loading assembly", ex);
}
}
else
{
Log.DebugFormat("Loading {0}{1}", sourceDll, reflectOnly ? " for reflection" : String.Empty);
dllToLoad = sourceDll;
}
Assembly result = null;
// Finally load the Assembly
if (reflectOnly)
{
result = Assembly.ReflectionOnlyLoadFrom(dllToLoad);
}
else
{
assemblyName.CodeBase = dllToLoad;
result = Assembly.Load(assemblyName);
// If the assembly could not be loaded, do nothing! Return null.
// See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1109769&SiteID=1
}
if (result == null)
Log.WarnFormat("Cannot load {0}", baseName);
return result;
}
finally
{
_currentlyLoading = null;
}
}
}