Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

Converting .NET Assemblies to Silverlight Assemblies

, 3 Mar 2009 CPOL
Share your .NET assemblies with Silverlight.
SLAsm.zip
SLAsm
SLAsm
bin
Disassembler
ildasm.exe
Properties
SLAsm.csproj.user
using System;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Collections.Generic;

namespace SLAsm
{
    class Program
    {
        

        public static string ILDisassembler { get; set; }
        public static string ILAssembler { get; set; }
        /// <summary>
        /// Validate the IL Assembler .Disassembler Paths
        /// </summary>
        static bool validatePaths()
        {
            return !string.IsNullOrEmpty(ILDisassembler)
                && System.IO.File.Exists(ILDisassembler)
                && !string.IsNullOrEmpty(ILAssembler)
                && System.IO.File.Exists(ILAssembler);
        }
        /// <summary>
        /// Load the settings from the SLAsm.Settings.xml file
        /// </summary>
        /// <returns></returns>
        static ExternAssembly[] LoadSettings()
        {
            try
            {
                string sPath = System.IO.Path.ChangeExtension(
                    typeof(ExternAssembly).Assembly.Location, ".Settings.xml");
                if (!System.IO.File.Exists(sPath))
                {
                    Console.WriteLine(string.Format("Error: Could not locate Settings File ('{0}')", sPath));
                    return new ExternAssembly[] { };
                }
                XmlDocument xDoc = new XmlDocument();
                xDoc.Load(sPath);
                
                string LocalPath = System.IO.Path.GetDirectoryName(sPath);
                
                //Updated to allow %path% token be replaced by the local path
                ILDisassembler = xDoc.DocumentElement.GetAttribute("ILDisassembler").Replace("%path%",LocalPath);
                
                //Updated to load ilasm from the .Net instalation dir
                ILAssembler = System.IO.Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "ilasm.exe");
                if(!System.IO.File.Exists(ILAssembler))
                    ILAssembler = xDoc.DocumentElement.GetAttribute("ILAssembler").Replace("%path%", LocalPath);
                XmlNamespaceManager nsMgr = new XmlNamespaceManager(xDoc.NameTable);
                nsMgr.AddNamespace("ns", ExternAssembly.NamespaceUrn);
                List<ExternAssembly> assemblies = new List<ExternAssembly>();
                foreach (XmlElement xExtern in xDoc.DocumentElement.SelectNodes("ns:ExternAssembly[@Name]",nsMgr))
                {
                    ExternAssembly asm = ExternAssembly.FromXml(xExtern);
                    if (!asm.IsEmpty)
                        assemblies.Add(asm);
                }
                return assemblies.ToArray();

            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(string.Format("Unexpected Error!\n{0}", ex.Message));
            }
            return new ExternAssembly[] { };
        }
        

        static int Main(string[] args)
        {
            if (args == null || args.Length == 0 || args[0].Equals("/?") || args[0].Equals("-?"))
            {
                Console.WriteLine("Usage: SLAsm.exe <AssemblyPath.dll> [/Key=<StrongNameKeyPath.snk>] [/Output=<TargetPath.dll>]");
                return 0;
            }

            

            //Load Settings
            ExternAssembly[] Assemblies = LoadSettings();

            if (Assemblies.Length == 0)
            {
                Console.WriteLine("Could not load Assembly Settings");
                return -2;
            }
            //Validate External Paths
            if (!validatePaths())
            {
                Console.ForegroundColor = ConsoleColor.Red;
                string sError ="Invalid paths set for IL Assembler / Disassembler\nPlease modify the SLAsm.Settings.xml file";
                Console.Error.WriteLine(sError);
                
                return -1;
            }

            string Path = null, Output = null, KeyFile = null;
            foreach (string arg in args)
            {
                string[] spl = arg.Split('=');
                if (spl.Length > 1)
                {
                    switch (spl[0].Trim().ToLower())
                    {
                        case "/key":
                            KeyFile = spl[1].Trim();
                            break;
                        case "/output":
                            Output = spl[1].Trim();
                            break;
                    }
                }
                else
                {
                    Path = spl[0].Trim();
                }
            }
            if (string.IsNullOrEmpty(Output))
                Output = System.IO.Path.ChangeExtension(Path, ".SL.dll");
            
            if (!System.IO.File.Exists(Path))
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.Error.WriteLine("Error: Invalid Input assembly");

                return -3;
            }

            

            //Start Disassembler
            Process p = new Process();
            Console.WriteLine(string.Format("Disassembling '{0}'", Path));
            p.StartInfo = new ProcessStartInfo(ILDisassembler,string.Format("{0}.dll /out:{0}.il /text /nobar",System.IO.Path.GetFileNameWithoutExtension( Path)));
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(Path);
            p.Start();
            p.WaitForExit();
            if (p.ExitCode != 0)
            {
                StringBuilder sB = new StringBuilder(p.StandardOutput.ReadToEnd());
                if (sB.Length > 0)
                {
                    Console.WriteLine("Result from ILDAsm was:");
                    Console.WriteLine(sB.ToString());
                }
            }



            string ILFile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Path), System.IO.Path.GetFileNameWithoutExtension(Path) + ".il");
            if (System.IO.File.Exists(ILFile))
            {
                //Load IL Code
                string IL = System.IO.File.ReadAllText(ILFile);
                Console.WriteLine("Fixing Assembly references...");

                //Iterate All Problematic Assembly references and fix their version
                foreach (ExternAssembly item in Assemblies)
                    IL = item.FixAssembly(IL);
                
                //Check for a Strong name Key and remove if exists
                Regex publicKey = new Regex(".publickey\\s=\\s\\([^\\)]*\\)", RegexOptions.Compiled);
                Match pkey = publicKey.Match(IL);
                if (pkey != null && pkey.Length != 0)
                {
                    Console.WriteLine("Removing Strong name Key...");
                    StringBuilder sBIL = new StringBuilder(IL.Length - pkey.Length);
                    sBIL.Append(IL.Substring(0, pkey.Index));
                    sBIL.Append(IL.Substring(pkey.Index + pkey.Length));
                    IL = sBIL.ToString();
                }

                //Output the modified IL Code
                System.IO.File.WriteAllText(ILFile, IL);

                //Start The IL Assembler Process
                string sParams = "{0}.il /dll /out:\"{1}\"";
                string resFile = System.IO.Path.ChangeExtension(Path, ".res");
                if (System.IO.File.Exists(resFile))
                    sParams = "{0}.il /dll /resource:{0}.res /out:\"{1}\"";
                if (!string.IsNullOrEmpty(KeyFile))
                    sParams += string.Format(" /key=\"{0}\"", args[1]);
                sParams = "/Quiet /Optiomize " + sParams;

                if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(Output)))
                    System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Output));
                Console.WriteLine("Re-Assembling File...");
                p = new Process();
                p.StartInfo = new ProcessStartInfo(ILAssembler, string.Format(sParams, System.IO.Path.GetFileNameWithoutExtension(Path),Output));
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(Path);

                p.Start();
                if (!p.HasExited)
                    p.WaitForExit();
                if (p.ExitCode != 0)                    
                        Console.WriteLine("ILAsm Faild!");
                else
                    Console.WriteLine(string.Format("Silverlight Compatible Assembly created in: '{0}'", Output));
                System.IO.File.Delete(ILFile);
                if (System.IO.File.Exists(resFile))
                    System.IO.File.Delete(resFile);
                return 0;
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Could not find IL code for assembly");
                return -1;
            }
        }

       

        
       

    }
}

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)

Share

About the Author

Suriel Bendahan
Software Developer (Senior) VCM Software
Israel Israel
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150302.1 | Last Updated 3 Mar 2009
Article Copyright 2009 by Suriel Bendahan
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid