home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2005 June (DVD) / DPPRO0605DVD.iso / dotNETSDK / SETUP.EXE / netfxsd1.cab / FL_appconfig_cs________.3643236F_FC70_11D3_A536_0090278A1BB8 < prev    next >
Encoding:
Text File  |  2001-07-10  |  7.8 KB  |  234 lines

  1. /**
  2.  * Writes out the Application Configuration File from an 
  3.  * AssemblyDependencies listing.
  4.  *
  5.  * @author  Jonathan Pryor
  6.  */
  7.  
  8. namespace ADepends
  9.   {
  10.   using System;
  11.   using System.Collections; // IComparer
  12.   using System.Diagnostics; // Debug
  13.   using System.Reflection;  // Assembly
  14.   using System.Text;        // Encoding
  15.   using System.Xml;         // XML stuff...
  16.  
  17.   /**
  18.    * Writes out an template Application Configuration File for use during
  19.    * the loading of the Application.
  20.    *
  21.    * It provides AssemblyIdentity rows for all Assemblies available from
  22.    * an AssemblyDependencies object.
  23.    *
  24.    * All other rows (AppDomain, BindingMode, and BindingPolicy) are
  25.    * either empty (BindingPolicy), guessed at (AppDomain & BindingMode), 
  26.    * or have a commented out implementation for demo purposes (BindingPolicy).
  27.    */
  28.   internal class AppConfig
  29.     {
  30.     /**
  31.      * Save a configuration file that lists the Assemblies contained in
  32.      * ``ad'', writing the contents to the file ``file''.
  33.      */
  34.     public static void SaveConfig (AssemblyDependencies ad, string file)
  35.       {
  36.       if (ad == null)
  37.         Debug.Assert (false, "Invalid AssemblyDependencies Object");
  38.       if (file == null)
  39.         Debug.Assert (false, "Invalid file name");
  40.  
  41.       XmlDocument d = new XmlDocument ();
  42.       XmlElement root = d.CreateElement (Localization.ACF_CONFIGURATION);
  43.  
  44.       XmlElement runtime = d.CreateElement (Localization.ACF_RUNTIME);
  45.       root.AppendChild (runtime);
  46.  
  47.       XmlElement asmBind = d.CreateElement (Localization.ACF_ASSEMBLYBINDING);
  48.       asmBind.Attributes.Append (_attribute (d, 
  49.           Localization.ACF_XMLNS, Localization.ACF_XMLURN));
  50.       runtime.AppendChild (asmBind);
  51.       
  52.  
  53.       _probing (d, asmBind);
  54.       _binding_redir (d, asmBind);
  55.       _assemblies(d, asmBind, ad);
  56.  
  57.       d.AppendChild (root);
  58.  
  59.       XmlTextWriter w = new XmlTextWriter (file, Encoding.UTF8);
  60.       w.Formatting = Formatting.Indented;
  61.       w.WriteStartDocument ();
  62.       d.Save (w);
  63.       w.Close ();
  64.       }
  65.  
  66.     /**
  67.      * Generate a template AppDomain XML Node.
  68.      */
  69.     private static void _probing (XmlDocument d, XmlNode parent)
  70.       {
  71.       XmlElement ad = d.CreateElement (Localization.ACF_PROBING);
  72.       ad.Attributes.Append (_attribute (d, 
  73.           Localization.ACF_ATTR_PRIVATE_PATH, ""));
  74.       parent.AppendChild (ad);
  75.       }
  76.  
  77.     /**
  78.      * Generate a template BindingMode XML Node.
  79.      */
  80.     private static void _binding_mode (XmlDocument d, XmlNode parent)
  81.       {
  82.       XmlElement bm = d.CreateElement (Localization.ACF_BINDING_MODE);
  83.       XmlElement abm = d.CreateElement (Localization.ACF_APP_BINDING_MODE);
  84.       bm.AppendChild (abm);
  85.       abm.Attributes.Append (_attribute (d, Localization.ACF_ATTR_MODE, 
  86.           Localization.ACF_ATTR_MODE_GUESS));
  87.       parent.AppendChild (bm);
  88.       }
  89.  
  90.     /**
  91.      * Generate a template BindingRedir row.
  92.      */
  93.     private static void _binding_redir (XmlDocument d, XmlNode parent)
  94.       {
  95.       XmlNode n = d.CreateComment (Localization.ACF_BINDING_REDIR_HELP);
  96.       parent.AppendChild (n);
  97.  
  98.       XmlElement br = d.CreateElement (Localization.ACF_BINDING_REDIR);
  99.       br.Attributes.Append (_attribute (d, Localization.ACF_ATTR_NAME, 
  100.           Localization.ACF_ATTR_NAME_GUESS));
  101.       br.Attributes.Append (_attribute (d, Localization.ACF_ATTR_PUBLIC_KEY_TOKEN, 
  102.           Localization.ACF_ATTR_PUBLIC_KEY_TOKEN_GUESS));
  103.       br.Attributes.Append (_attribute (d, Localization.ACF_ATTR_VERSION, 
  104.           Localization.ACF_ATTR_VERSION_GUESS));
  105.       br.Attributes.Append (_attribute (d, Localization.ACF_ATTR_VERSION_NEW, 
  106.           Localization.ACF_ATTR_VERSION_NEW_GUESS));
  107.       br.Attributes.Append (_attribute (d, Localization.ACF_ATTR_USE_LATEST, 
  108.           Localization.ACF_ATTR_USE_LATEST_GUESS));
  109.  
  110.       /*
  111.        * We want the XML available so people can see the format, but we
  112.        * don't actually have anything to specify, so it's wrapped in a 
  113.        * comment.
  114.        */
  115.       parent.AppendChild (d.CreateComment (br.OuterXml));
  116.       }
  117.  
  118.     /**
  119.      * Used to sort IAssemblyInfo objects according to the name they expose.
  120.      */
  121.     private class AsmInfoComparer : IComparer
  122.       {
  123.       public int Compare (object x, object y)
  124.         {
  125.         IAssemblyInfo ax = (IAssemblyInfo) x;
  126.         IAssemblyInfo ay = (IAssemblyInfo) y;
  127.  
  128.         return String.Compare (ax.Name, ay.Name);
  129.         }
  130.       }
  131.  
  132.     /**
  133.      * Generate an Assemblies XML Element consisting of AssemblyIdentity
  134.      * elements for all the Assemblies we loaded.
  135.      */
  136.     private static void _assemblies (XmlDocument d, XmlNode parent,
  137.       AssemblyDependencies ad)
  138.       {
  139.       XmlElement assemblies = d.CreateElement (Localization.ACF_DEPENDENTASSEMBLY);
  140.  
  141.       ArrayList l = new ArrayList (ad.Assemblies);
  142.       object[] asminfo = l.ToArray ();
  143.       Array.Sort (asminfo, new AsmInfoComparer());
  144.  
  145.       /*
  146.        * Due to obscurities of the dependency search & store process,
  147.        * the same assembly may be loaded multiple times.
  148.        * (This may happen if different AssemblyName's are loaded for
  149.        * what is, eventually, the same Assembly.)
  150.        *
  151.        * We would prefer to minimize duplicate lines, so ``o'' keeps
  152.        * track of what we've printed out, to keep from displaying
  153.        * it multiple times.
  154.        */
  155.       ArrayList o = new ArrayList ();
  156.       foreach (IAssemblyInfo ai in asminfo)
  157.         {
  158.         if (!o.Contains (ai.Name))
  159.           {
  160.           Trace.WriteLine ("Saving Assembly: ``" + ai.Name + "''");
  161.           assemblies.AppendChild (_assembly_identity (d, ai));
  162.           o.Add (ai.Name);
  163.           }
  164.         }
  165.  
  166.       parent.AppendChild (assemblies);
  167.       }
  168.  
  169.     /**
  170.      * Generate the AssemblyIdentity information for an Assembly.
  171.      */
  172.     private static XmlNode _assembly_identity (XmlDocument d, IAssemblyInfo ai)
  173.       {
  174.       AssemblyRef a = ai.GetAssembly ();
  175.       if (a == null)
  176.         return _bad_assembly (d, ai);
  177.  
  178.       XmlElement cb = d.CreateElement (Localization.ACF_ASSEMBLYIDENTITY);
  179.  
  180.       cb.Attributes.Append (_attribute (d, Localization.ACF_ATTR_NAME, 
  181.           a.GetName().Name));
  182.       cb.Attributes.Append (_attribute (d, Localization.ACF_ATTR_PUBLIC_KEY_TOKEN, 
  183.           _public_key_token(a)));
  184.       cb.Attributes.Append (_attribute (d, Localization.ACF_ATTR_CULTURE, 
  185.           a.GetName().CultureInfo.Name));
  186.       cb.Attributes.Append (_attribute (d, Localization.ACF_ATTR_VERSION,
  187.           a.GetName().Version.ToString()));
  188.       cb.Attributes.Append (_attribute (d, Localization.ACF_ATTR_CODE_BASE, 
  189.           a.CodeBase));
  190.  
  191.       return cb;
  192.       }
  193.  
  194.     /**
  195.      * The XML Node for an Assembly that couldn't be loaded: insert it
  196.      * as a comment, mentioning the reason for the error.
  197.      */
  198.     private static XmlNode _bad_assembly (XmlDocument d, IAssemblyInfo ai)
  199.       {
  200.       String s = String.Format (Localization.FMT_NOLOAD_ASSEMBLY,
  201.         ai.Name, ai.Error.Message);
  202.       return d.CreateComment (s);
  203.       }
  204.  
  205.     /**
  206.      * Create an XmlAttribute with name ``name'' and value ``value''.
  207.      */
  208.     private static XmlAttribute _attribute (XmlDocument d, 
  209.       string name, string value)
  210.       {
  211.       XmlAttribute n = d.CreateAttribute (name);
  212.       n.Value = value;
  213.       return n;
  214.       }
  215.  
  216.      /**
  217.      * Convert the public key token of an Assembly into a string
  218.      * (as strings are used in the XML).
  219.      *
  220.      **/
  221.     private static string _public_key_token (AssemblyRef a)
  222.       {
  223.       byte[] ab = a.GetName().GetPublicKeyToken ();
  224.       StringBuilder sb = new StringBuilder ();
  225.  
  226.       if (ab != null)
  227.         foreach (byte b in ab)
  228.           sb.Append (b.ToString("x2"));
  229.       return sb.ToString();
  230.       }
  231.     } /* class AppConfig */
  232.   } /* namespace ADepends */
  233.  
  234.