// Parse binding redirects from XML config internal static List <BindingRedirect> GetBindingRedirects() { var result = new List <BindingRedirect>(); var appConfig = Path.GetFullPath(typeof(AssemblyBindingRedirectHelper).Assembly.Location) + ".config"; if (!File.Exists(appConfig)) { return(result); } var doc = ReadAppConfig(appConfig); foreach (XPathNavigator node in doc.CreateNavigator().Select(DEPENDENCIES)) { var entry = new BindingRedirect { ShortName = node.SelectSingleNode("assemblyIdentity/@name").Value, PublicKeyToken = node.SelectSingleNode("assemblyIdentity/@publicKeyToken").Value, RedirectToVersion = node.SelectSingleNode("bindingRedirect/@newVersion").Value, }; result.Add(entry); } return(result); }
public static void RedirectAssembly(BindingRedirect bindingRedirect) { ResolveEventHandler handler = null; handler = (sender, args) => { var requestedAssembly = new AssemblyName(args.Name); if (requestedAssembly.Name != bindingRedirect.ShortName) { return(null); } var targetPublicKeyToken = new AssemblyName("x, PublicKeyToken=" + bindingRedirect.PublicKeyToken) .GetPublicKeyToken(); requestedAssembly.Version = new Version(bindingRedirect.RedirectToVersion); requestedAssembly.SetPublicKeyToken(targetPublicKeyToken); requestedAssembly.CultureInfo = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.AssemblyResolve -= handler; return(Assembly.Load(requestedAssembly)); }; AppDomain.CurrentDomain.AssemblyResolve += handler; }
// Register assembly resolve handler for the redirected assembly with the current appdomain private static void RedirectAssembly(BindingRedirect bindingRedirect) { AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; // this local function properly captures the bindingRedirect argument Assembly ResolveAssembly(object sender, ResolveEventArgs args) { var requestedAssembly = new AssemblyName(args.Name); if (requestedAssembly.Name != bindingRedirect.ShortName) { return(null); } // a dummy name is used since we only need the class to // calculate the actual public key token for us here var targetPublicKeyToken = new AssemblyName( $"x, PublicKeyToken={bindingRedirect.PublicKeyToken}").GetPublicKeyToken(); requestedAssembly.SetPublicKeyToken(targetPublicKeyToken); requestedAssembly.Version = new Version(bindingRedirect.RedirectToVersion); requestedAssembly.CultureInfo = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly; return(Assembly.Load(requestedAssembly)); } }
/// <summary> /// Adds a binding redirect. /// </summary> /// <param name="bindingRedirect">The binding redirect to add.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="bindingRedirect"/> is null.</exception> public void AddBindingRedirect(BindingRedirect bindingRedirect) { if (bindingRedirect == null) { throw new ArgumentNullException("bindingRedirect"); } bindingRedirects.Add(bindingRedirect); }
private void TransformData(configuration xml) { foreach (var item in xml.runtime) { var br = new BindingRedirect { ShortName = item.dependentAssembly.assemblyIdentity.name, PublicKeyToken = item.dependentAssembly.assemblyIdentity.publicKeyToken, RedirectToVersion = item.dependentAssembly.bindingRedirect.newVersion }; BindingRedirects.Add(br); } }
private static void RedirectAssembly(BindingRedirect bindingRedirect, TraceWriter log) { Assembly Handler(object sender, ResolveEventArgs args) { var requestedAssembly = new AssemblyName(args.Name); if (requestedAssembly.Name != bindingRedirect.ShortName) { return(null); } log.Info($"Found match for {bindingRedirect}"); var targetPublicKeyToken = new AssemblyName("x, PublicKeyToken=" + bindingRedirect.PublicKeyToken).GetPublicKeyToken(); requestedAssembly.SetPublicKeyToken(targetPublicKeyToken); requestedAssembly.Version = new Version(bindingRedirect.RedirectToVersion); requestedAssembly.CultureInfo = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.AssemblyResolve -= Handler; return(Assembly.Load(requestedAssembly)); } AppDomain.CurrentDomain.AssemblyResolve += Handler; }
private void Parse(string appConfigFilePath) { void Error(string text) => errors.Add(text); document = XDocument.Load(appConfigFilePath); var configuration = document.Root; var runtime = configuration.Element("runtime"); if (runtime == null) { Error($"Element 'runtime' not found"); return; } var assemblyBinding = runtime.Elements(Xmlns("assemblyBinding")); if (assemblyBinding == null || !assemblyBinding.Any()) { Error($"Element 'assemblyBinding' not found"); return; } assemblyBindingElement = assemblyBinding.FirstOrDefault(); var dependentAssemblyElements = assemblyBinding.Elements(Xmlns("dependentAssembly")); foreach (var dependentAssembly in dependentAssemblyElements) { var assemblyIdentity = dependentAssembly.Element(Xmlns("assemblyIdentity")); if (assemblyIdentity == null) { Error($"One of dependentAssembly elements doesn't have an assemblyIdentity subelement"); continue; } var name = GetAttributeValue(assemblyIdentity, "name"); if (name == null) { Error($"assemblyIdentity is missing the 'name' attribute"); continue; } var culture = GetAttributeValue(assemblyIdentity, "culture"); var publicKeyToken = GetAttributeValue(assemblyIdentity, "publicKeyToken"); if (publicKeyToken == null) { Error($"assemblyIdentity {name} is missing the 'publicKeyToken' attribute"); continue; } var bindingRedirect = dependentAssembly.Element(Xmlns("bindingRedirect")); if (bindingRedirect == null) { Error($"dependentAssembly for {name} doesn't have a bindingRedirect subelement"); continue; } var oldVersionString = GetAttributeValue(bindingRedirect, "oldVersion"); if (oldVersionString == null) { Error($"bindingRedirect for {name} is missing the 'oldVersion' attribute"); continue; } var newVersionString = GetAttributeValue(bindingRedirect, "newVersion"); if (newVersionString == null) { Error($"bindingRedirect for {name} is missing the 'newVersion' attribute"); continue; } Tuple <string, string> range = ParseVersionRange(oldVersionString); if (range == null) { Error($"oldVersion range for {name} is in incorrect format"); continue; } if (!Version.TryParse(range.Item1, out var oldVersionStart)) { Error($"Can't parse old start version: {range.Item1}"); continue; } if (!Version.TryParse(range.Item2, out var oldVersionEnd)) { Error($"Can't parse old end version: {range.Item2}"); continue; } if (!Version.TryParse(newVersionString, out var newVersion)) { Error($"Can't parse newVersion: {newVersion}"); continue; } var bindingRedirectResult = new BindingRedirect { Name = name, Culture = culture, PublicKeyToken = publicKeyToken, OldVersionRangeStart = oldVersionStart, OldVersionRangeEnd = oldVersionEnd, NewVersion = newVersion, DependentAssemblyElement = dependentAssembly, BindingRedirectElement = bindingRedirect, AssemblyIdentityElement = assemblyIdentity }; bindingRedirects.Add(bindingRedirectResult); } }
public void AddBindingRedirect(BindingRedirect bindingRedirect) { bindingRedirects.Add(bindingRedirect); }
static Dictionary <string, BindingRedirect> _LoadBindingRedirects(string configFilePath) { var xdoc = XDocument.Load(configFilePath); var xRuntime = xdoc.Element("configuration")?.Element("runtime"); if (xRuntime == null) { return(null); } XNamespace ns = "urn:schemas-microsoft-com:asm.v1"; var xDependentAssemblies = xRuntime.Elements(ns + "assemblyBinding").SelectMany(x => x.Elements(ns + "dependentAssembly")).ToArray(); Dictionary <string, BindingRedirect> bindingRedirects = null; foreach (var xDependentAssembly in xDependentAssemblies) { var xAsmID = xDependentAssembly.Element(ns + "assemblyIdentity"); if (xAsmID == null) { continue; } var xBindingRedirect = xDependentAssembly.Element(ns + "bindingRedirect"); if (xBindingRedirect == null) { continue; } string asmIDName = xAsmID.Attribute("name")?.Value; string asmIDPublicKeyToken = xAsmID.Attribute("publicKeyToken")?.Value; string asmIDCulture = xAsmID.Attribute("culture")?.Value; if (asmIDName == null || asmIDPublicKeyToken == null || asmIDCulture == null) { continue; } string asmName = $"{asmIDName}, Culture={asmIDCulture}, PublicKeyToken={asmIDPublicKeyToken}"; string oldVersion = xBindingRedirect.Attribute("oldVersion")?.Value; string newVersion = xBindingRedirect.Attribute("newVersion")?.Value; if (oldVersion == null || newVersion == null) { continue; } var parts = oldVersion.Split(new[] { '-' }, 2, StringSplitOptions.None).Select(x => x.Trim()).ToList(); if (parts.Count == 0) { continue; } if (bindingRedirects == null) { bindingRedirects = new Dictionary <string, BindingRedirect>(StringComparer.OrdinalIgnoreCase); } bindingRedirects[asmName] = new BindingRedirect( Version.Parse(parts[0]), Version.Parse(parts.Last()), Version.Parse(newVersion)); } return(bindingRedirects); }
/// <summary> /// Adds a binding redirect. /// </summary> /// <param name="bindingRedirect">The binding redirect to add.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="bindingRedirect"/> is null.</exception> public void AddBindingRedirect(BindingRedirect bindingRedirect) { if (bindingRedirect == null) throw new ArgumentNullException("bindingRedirect"); bindingRedirects.Add(bindingRedirect); }