Click here to Skip to main content
15,886,110 members
Articles / Programming Languages / XML

Converting .NET Assemblies to Silverlight Assemblies

Rate me:
Please Sign up or sign in to vote.
4.92/5 (15 votes)
3 Mar 2009CPOL5 min read 151.5K   1.4K   69  
Share your .NET assemblies with Silverlight.
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace SLAsm
{
    /// <summary>
    /// Represents an IL External Assembly reference
    /// </summary>
    struct ExternAssembly
    {
        /// <summary>
        /// The .Net Assembly Name
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// The Target Public key token
        /// </summary>
        public string PublicKeyToken { get; set; }
        /// <summary>
        /// The Target Version
        /// </summary>
        public Version Version { get; set; }

        public bool IsEmpty { get { return string.IsNullOrEmpty(Name); } }

        /// <summary>
        /// Fixes the references in the IL Code 
        /// </summary>
        /// <param name="IL">The Assembly's IL Code</param>
        /// <returns>The Modified IL Code</returns>
        public string FixAssembly(string IL)
        {
            Regex find = new Regex(".assembly extern " + Name + "\\s*{[^}]*}");
            Match asm = find.Match(IL);
            if (asm != null && asm.Length > 0)
            {
                Console.WriteLine(string.Format("Fixing Assembly reference for '{0}'", Name));
                StringBuilder retStr = new StringBuilder(IL.Length);
                retStr.Append(IL.Substring(0, asm.Index));
                string AsmIl = asm.Value;
                Regex publicKey = new Regex(".publickeytoken = \\([^)]*\\)", RegexOptions.Compiled);
                Match pKey = publicKey.Match(AsmIl);

                if (pKey != null && pKey.Length > 0)
                {

                    StringBuilder sbAsmIl = new StringBuilder(AsmIl.Length);
                    sbAsmIl.Append(AsmIl.Substring(0, pKey.Index));
                    sbAsmIl.Append(string.Format(".publickeytoken = ({0})", PublicKeyToken));
                    sbAsmIl.Append(AsmIl.Substring(pKey.Index + pKey.Length));
                    AsmIl = sbAsmIl.ToString();
                }
                Regex version = new Regex(".ver \\d:\\d:\\d:\\d", RegexOptions.Compiled);
                Match ver = version.Match(AsmIl);
                if (ver != null && ver.Length > 0)
                {
                    StringBuilder sbAsmIl = new StringBuilder(AsmIl.Length);
                    sbAsmIl.Append(AsmIl.Substring(0, ver.Index));
                    sbAsmIl.Append(string.Format(".ver {0}:{1}:{2}:{3}", Version.Major, Version.Minor, Version.Build, Version.Revision));
                    sbAsmIl.Append(AsmIl.Substring(ver.Index + ver.Length));
                    AsmIl = sbAsmIl.ToString();
                }
                retStr.Append(AsmIl);
                retStr.Append(IL.Substring(asm.Index + asm.Length));
                return RemoveAttributes(retStr.ToString());
            }

            return IL;

        }

        string RemoveAttributes(string IL)
        {
            if (UnSupportedAttributes == null || UnSupportedAttributes.Length == 0)
                return IL;
            foreach (string att in UnSupportedAttributes)
            {
                string regex = ".custom instance void \\[" + Name + "\\]" + att + "::.ctor[^=]*=[\\s]*\\([^\\)]*\\)";
                Regex uAtt = new Regex(regex, RegexOptions.Multiline);
                if (uAtt.IsMatch(IL))
                {
                    Console.WriteLine("Removing Unsupported Attribute " + att);
                    IL = uAtt.Replace(IL, "//SLASM: Removed Unsupported Attribute " + att);
                }
            }
            return IL;
        }
        /// <summary>
        /// An Array of strings representing Attributes not supported by the target assembly version that should be removed
        /// </summary>
        public string[] UnSupportedAttributes { get; set; }

        public const string NamespaceUrn = "urn:Silverlight-Assmblies/SLAsmSettings.xsd";

        /// <summary>
        /// Returns an <see cref="ExternAssembly"/> initialized to the content of an <see cref="XmlElement"/>
        /// </summary>
        /// <param name="xElement">The Element containing the info</param>
        public static ExternAssembly FromXml(XmlElement xElement)
        {
            ExternAssembly retVal = new ExternAssembly();
            if (xElement != null)
            {
                retVal.Name = xElement.GetAttribute("Name");
                retVal.Version = new Version(xElement.GetAttribute("Version"));
                retVal.PublicKeyToken = xElement.GetAttribute("PublicKeyToken");
                List<string> usAttribs = new List<string>();
                XmlNamespaceManager ns = new XmlNamespaceManager(xElement.OwnerDocument.NameTable);
                ns.AddNamespace("ns",NamespaceUrn);
                foreach (XmlElement xAtt in xElement.SelectNodes("ns:UnsupportedAttribute", ns))
                {
                    if (!string.IsNullOrEmpty(xAtt.InnerText))
                        usAttribs.Add(xAtt.InnerText);
                }
                retVal.UnSupportedAttributes = usAttribs.ToArray();
            }
            return retVal;

        }
    }
    
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) VCM Software
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions