216 lines · 9.0 KB · C#
RawDownload
//******************************************************************************************************//  Program.cs - Gbtc////  Copyright © 2018, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this//  file except in compliance with the License. You may obtain a copy of the License at:////      http://opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  02/07/2018 - J. Ritchie Carroll//       Generated original version of source code.////****************************************************************************************************** using System;using System.IO;using System.Reflection;using System.Text;using System.Xml;using GSF.IO; namespace ValidateAssemblyBindings{    // NOTE: The build output folder for this application is intentionally the "Libraries" location    // so that the tool will be available for GSF.Web dependent downstream applications as part of    // the nightly build roll-down process.    class Program    {        static int Main(string[] args)        {            if (args.Length != 1)            {                Console.Error.WriteLine("USAGE: ValidateAssemblyBindings <appConfigFileName>");                Console.Error.WriteLine();                Console.Error.WriteLine("    Example: ValidateAssemblyBindings openPDC.exe.config");                Console.Error.WriteLine();                return 1;            }             try            {                string appConfigFileName = FilePath.GetAbsolutePath(args[0]);                 if (!File.Exists(appConfigFileName))                    throw new FileNotFoundException($"Application configuration file name \"{appConfigFileName}\" not found.");                 Console.WriteLine($"Validating assembly bindings for \"{appConfigFileName}\"");                                if (ValidateAssemblyBindings(appConfigFileName))                {                    Console.WriteLine("Assembly bindings validation succeeded.");                    return 0;                }                else                {                    Console.Error.WriteLine("Assembly bindings validation failed.");                    return 3;                }            }            catch (Exception ex)            {                Console.Error.WriteLine($"ERROR: Failed to validate assembly bindings: {ex.Message}");                Console.Error.WriteLine();                return 2;            }        }         // Validates the assembly bindings for the specified application <paramref name="configFileName"/>.        private static bool ValidateAssemblyBindings(string configFileName)        {            if (!File.Exists(configFileName))                return false;             XmlDocument configFile = new XmlDocument();            configFile.Load(configFileName);             XmlNode runTime = configFile.SelectSingleNode("configuration/runtime");             if (runTime == null)            {                XmlNode config = configFile.SelectSingleNode("configuration");                 // This is expected to already exist...                if (config == null)                    return false;                 runTime = configFile.CreateElement("runtime");                config.AppendChild(runTime);                 XmlElement gcServer = configFile.CreateElement("gcServer");                XmlAttribute enabled = configFile.CreateAttribute("enabled");                enabled.Value = "true";                 gcServer.Attributes.Append(enabled);                runTime.AppendChild(gcServer);                 XmlElement gcConcurrent = configFile.CreateElement("gcConcurrent");                enabled = configFile.CreateAttribute("enabled");                enabled.Value = "true";                 gcConcurrent.Attributes.Append(enabled);                runTime.AppendChild(gcConcurrent);                 XmlElement generatePublisherEvidence = configFile.CreateElement("generatePublisherEvidence");                enabled = configFile.CreateAttribute("enabled");                enabled.Value = "false";                 generatePublisherEvidence.Attributes.Append(enabled);                runTime.AppendChild(generatePublisherEvidence);            }             const string xmlns = "urn:schemas-microsoft-com:asm.v1";            XmlNamespaceManager nsmgr = new XmlNamespaceManager(configFile.NameTable);            nsmgr.AddNamespace("s", xmlns);             XmlDocument assemblyBindingsXml = new XmlDocument();            XmlElement assemblyBinding = assemblyBindingsXml.CreateElement("assemblyBinding", xmlns);            string[] assemblyFileNames = FilePath.GetFileList(FilePath.GetAbsolutePath("*.dll"));             foreach (string assemblyFileName in assemblyFileNames)            {                try                {                    Assembly assembly = Assembly.LoadFrom(assemblyFileName);                    AssemblyName assemblyName = assembly.GetName();                    string version = assemblyName.Version?.ToString();                     if (version is null || version.Equals("0.0.0.0") || version.Equals("1.0.0.0"))                        continue;                     StringBuilder keyTokenImage = new StringBuilder();                    byte[] keyTokenBytes = assemblyName.GetPublicKeyToken();                     if (!(keyTokenBytes is null))                    {                        foreach (byte keyToken in keyTokenBytes)                            keyTokenImage.Append($"{keyToken:x}");                    }                     XmlElement dependentAssembly = assemblyBindingsXml.CreateElement("dependentAssembly", xmlns);                     // Load assembly identity element                    XmlElement assemblyIdentity = assemblyBindingsXml.CreateElement("assemblyIdentity", xmlns);                     XmlAttribute name = assemblyBindingsXml.CreateAttribute("name");                    name.Value = assemblyName.Name;                    assemblyIdentity.Attributes.Append(name);                     if (keyTokenImage.Length > 0)                    {                        XmlAttribute publicKeyToken = assemblyBindingsXml.CreateAttribute("publicKeyToken");                        publicKeyToken.Value = keyTokenImage.ToString();                        assemblyIdentity.Attributes.Append(publicKeyToken);                    }                     string cultureName = assemblyName.CultureName;                     if (string.IsNullOrWhiteSpace(cultureName))                        cultureName = "neutral";                     XmlAttribute culture = assemblyBindingsXml.CreateAttribute("culture");                    culture.Value = cultureName;                    assemblyIdentity.Attributes.Append(culture);                     dependentAssembly.AppendChild(assemblyIdentity);                     // Load binding redirect element                    XmlElement bindingRedirect = assemblyBindingsXml.CreateElement("bindingRedirect", xmlns);                     XmlAttribute oldVersion = assemblyBindingsXml.CreateAttribute("oldVersion");                    oldVersion.Value = $"1.0.0.0-{version}";                    bindingRedirect.Attributes.Append(oldVersion);                     XmlAttribute newVersion = assemblyBindingsXml.CreateAttribute("newVersion");                    newVersion.Value = version;                    bindingRedirect.Attributes.Append(newVersion);                     dependentAssembly.AppendChild(bindingRedirect);                     // Add new dependent assembly to binding redirect                    assemblyBinding.AppendChild(dependentAssembly);                }                catch (Exception ex)                {                    if (!(ex is BadImageFormatException))                        Console.WriteLine($"Skipping \"{assemblyFileName}\": {ex.Message}");                }            }                        assemblyBindingsXml.AppendChild(assemblyBinding);             XmlDocumentFragment assemblyBindings = configFile.CreateDocumentFragment();            assemblyBindings.InnerXml = assemblyBindingsXml.InnerXml;             XmlNode oldAssemblyBindings = configFile.SelectSingleNode("configuration/runtime/s:assemblyBinding", nsmgr);             if (oldAssemblyBindings is null)                runTime.AppendChild(assemblyBindings);            else                runTime.ReplaceChild(assemblyBindings, oldAssemblyBindings);             configFile.Save(configFileName);             return true;        }    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t