// Try the assembly directory
string location = Path.GetDirectoryName (Location);
string fullName = Path.Combine (location, Path.Combine (culture.Name, an.Name + ".dll"));
- if (!throwOnFileNotFound && !File.Exists (fullName))
- return null;
- return (RuntimeAssembly)LoadFrom (fullName);
+ try {
+ return (RuntimeAssembly)LoadFrom (fullName);
+ } catch {
+ if (!throwOnFileNotFound && !File.Exists (fullName))
+ return null;
+ throw;
+ }
}
#if !MOBILE
foreach (var url in files){
string fname = LocateFile (new Uri (url).LocalPath);
- string aname = Path.GetFileName (fname);
+ string aname = MakeBundle.GetAssemblyName (fname);
maker.Add ("assembly:" + aname, fname);
if (File.Exists (fname + ".config"))
var symbolEscapeRE = new System.Text.RegularExpressions.Regex ("[^\\w_]");
foreach (var url in files) {
string fname = LocateFile (new Uri (url).LocalPath);
- string aname = Path.GetFileName (fname);
+ string aname = MakeBundle.GetAssemblyName (fname);
string encoded = symbolEscapeRE.Replace (aname, "_");
if (prog == null)
static readonly Universe universe = new Universe ();
static readonly Dictionary<string, string> loaded_assemblies = new Dictionary<string, string> ();
-
+
+ public static string GetAssemblyName (string path)
+ {
+ string name = Path.GetFileName (path);
+
+ // A bit of a hack to support satellite assemblies. They all share the same name but
+ // are placed in subdirectories named after the locale they implement. Also, all of
+ // them end in .resources.dll, therefore we can use that to detect the circumstances.
+ if (name.EndsWith (".resources.dll", StringComparison.OrdinalIgnoreCase)) {
+ string dir = Path.GetDirectoryName (path);
+ int idx = dir.LastIndexOf (Path.DirectorySeparatorChar);
+ if (idx >= 0) {
+ name = dir.Substring (idx + 1) + Path.DirectorySeparatorChar + name;
+ Console.WriteLine ($"Storing satellite assembly '{path}' with name '{name}'");
+ } else if (!quiet)
+ Console.WriteLine ($"Warning: satellite assembly {path} doesn't have locale path prefix, name conflicts possible");
+ }
+
+ return name;
+ }
+
static bool QueueAssembly (List<string> files, string codebase)
{
//Console.WriteLine ("CODE BASE IS {0}", codebase);
return true;
var path = new Uri(codebase).LocalPath;
- var name = Path.GetFileName (path);
+ var name = GetAssemblyName (path);
string found;
if (loaded_assemblies.TryGetValue (name, out found)) {
Error (string.Format ("Duplicate assembly name `{0}'. Both `{1}' and `{2}' use same assembly name.", name, path, found));
{
int i;
char *name;
+ gchar *lowercase_filename;
MonoImage *image = NULL;
-
+ gboolean is_satellite = FALSE;
/*
* we do a very simple search for bundled assemblies: it's not a general
* purpose assembly loading mechanism.
if (!bundles)
return NULL;
+ lowercase_filename = g_utf8_strdown (filename, -1);
+ is_satellite = g_str_has_suffix (lowercase_filename, ".resources.dll");
+ g_free (lowercase_filename);
name = g_path_get_basename (filename);
-
mono_assemblies_lock ();
for (i = 0; !image && bundles [i]; ++i) {
- if (strcmp (bundles [i]->name, name) == 0) {
+ if (strcmp (bundles [i]->name, is_satellite ? filename : name) == 0) {
image = mono_image_open_from_data_with_name ((char*)bundles [i]->data, bundles [i]->size, FALSE, status, refonly, name);
break;
}
mono_assemblies_unlock ();
if (image) {
mono_image_addref (image);
- mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Loader loaded assembly from bundle: '%s'.", name);
+ mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Assembly Loader loaded assembly from bundle: '%s'.", is_satellite ? filename : name);
g_free (name);
return image;
}