Click here to Skip to main content
15,897,187 members
Articles / Operating Systems / Windows

Extract GAC Assemblies

Rate me:
Please Sign up or sign in to vote.
4.45/5 (14 votes)
6 Jan 2007CPOL2 min read 66.7K   852   22  
Extracts .NET assemblies from GAC
#region Copyright notice
// ==================================================================================================
// This is an as-is implementation. feel free to use this code anyway you like :)
//
//                                                                     - Moim Hossain
//                                                                       2006
// ==================================================================================================
#endregion

#region Using Directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
#endregion

namespace GACExplorer
{
    /// <summary>
    /// The main form
    /// </summary>
    /// <remarks>
    ///     This class contains the core functionality.
    /// </remarks>
    /// <author>
    ///     Moim Hossain
    /// </author>
    public partial class GacExplorer : Form
    {
        /// <summary>
        /// Defines the status of the selection
        /// </summary>
        enum SelectionAction
        {
            /// <summary>
            /// Selected
            /// </summary>
            Select,

            /// <summary>
            /// Deselected
            /// </summary>
            Deselect
        }

        /// <summary>
        /// Creates a new instance
        /// </summary>
        public GacExplorer()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Exitint from the application
        /// </summary>
        /// <param name="sender">Button</param>
        /// <param name="e"></param>
        private void cmdExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// Deselection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lnkDeselect_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PerformSelectionAction(treeView1.Nodes, SelectionAction.Deselect);
        }

        /// <summary>
        /// Selection
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lnkSelect_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            PerformSelectionAction(treeView1.Nodes, SelectionAction.Select);
        }

        /// <summary>
        /// Toggling the selection of a node
        /// </summary>
        /// <remarks>   
        ///     This is a recursive routine that performs the selection and deselection
        /// </remarks>
        /// <param name="nodes">The Node collection</param>
        /// <param name="action">The action to be taken</param>
        private void PerformSelectionAction(TreeNodeCollection nodes, SelectionAction action)
        {
            foreach (TreeNode node in nodes)
            {
                if ((node as CheckedTreeNode) != null && (node.Tag as AssemblyInformation) != null)
                {
                    (node as CheckedTreeNode).Select = (action == SelectionAction.Select);
                }
                else
                {
                    PerformSelectionAction(node.Nodes, action);
                }
            }
        }

        /// <summary>
        /// Loading the assemblies
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbLoad_Click(object sender, EventArgs e)
        {
            statusBarPanel4.Text = "Loading assemblies..please wait.";
            treeView1.Nodes.Clear();
            this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
            string assemblyPath = String.Empty;
            if (Environment.GetEnvironmentVariables().Contains("windir"))
            {	// If the windir path is available already
                assemblyPath = System.IO.Path.Combine(Environment.GetEnvironmentVariable("windir"), "assembly");
            }
            else
            {	// Else read it from different source
                assemblyPath = Environment.GetFolderPath(Environment.SpecialFolder.System).Replace("system", "assembly\\gac").Replace("32", string.Empty);
            }

            TreeNode parentNode = new TreeNode("GAC", 2, 2);
            treeView1.Nodes.Add(parentNode);
            ExplorePath(new DirectoryInfo(assemblyPath), parentNode.Nodes);
            parentNode.Expand();
            this.Cursor = System.Windows.Forms.Cursors.Default;
            statusBarPanel4.Text = string.Empty;
        }

        /// <summary>
        /// A recursive routine that will explore the assemblies into the Gac
        /// </summary>
        /// <param name="assemblyPath">The path</param>
        /// <param name="nodes">The tree nodes</param>
        private void ExplorePath(DirectoryInfo parentDir, TreeNodeCollection nodes)
        {
            foreach (DirectoryInfo dInfo in parentDir.GetDirectories())
            {
                TreeNode node = new TreeNode(dInfo.Name, 2, 2);
                nodes.Add(node);
                node.Expand();
                ExplorePath(dInfo, node.Nodes);
            }
            foreach (FileInfo fInfo in parentDir.GetFiles("*.dll"))
            {
                CheckedTreeNode node = new CheckedTreeNode(fInfo.Name);
                AssemblyInformation assemblyInfo = new AssemblyInformation(fInfo);
                node.Tag = assemblyInfo;
                node.Text = fInfo.Name;
                nodes.Add(node);
            }
        }

        /// <summary>
        /// Handling the mouse up event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_MouseUp(object sender, MouseEventArgs e)
        {
            TreeNode node = treeView1.GetNodeAt(e.X, e.Y);
            if (e.Button == MouseButtons.Left && (node as CheckedTreeNode) != null)
            {
                (node as CheckedTreeNode).ToggleSelection();
            }
        }

        /// <summary>
        /// Handling the keyup event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Space && (treeView1.SelectedNode as CheckedTreeNode) != null)
            {
                (treeView1.SelectedNode as CheckedTreeNode).ToggleSelection();
            }
        }

        /// <summary>
        /// Handling the after select event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            lblAssemblyFullName.Text = "No Assembly is selected.";
            if ((treeView1.SelectedNode as CheckedTreeNode) != null && (treeView1.SelectedNode.Tag as AssemblyInformation) != null)
            {
                lblAssemblyFullName.Text = (treeView1.SelectedNode.Tag as AssemblyInformation).FullName;
            }
        }

        /// <summary>
        /// Handling the form loading event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GacExplorer_Load(object sender, EventArgs e)
        {
            lblAssemblyFullName.Text = "No Assembly is selected.";
        }

        /// <summary>
        /// Installing an assemby into the gac
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdInstall_Click(object sender, EventArgs e)
        {
            string envName = radDotNet2005.Checked ? "VS80COMNTOOLS" : "VS71COMNTOOLS";
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = "*.dll";
            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                Process process = new Process();

                string toolPath = Environment.GetEnvironmentVariable(envName);
                string vsCmdLinePath = System.IO.Path.Combine(toolPath, "vsvars32.bat");
                using (System.IO.StreamReader reader = new System.IO.StreamReader(vsCmdLinePath))
                {
                    string value = null;
                    while (null != (value = reader.ReadLine()))
                    {
                        if (value.IndexOf("FrameworkSDKDir") != -1)
                        {
                            string sdkPath = value.Substring(value.IndexOf("=") + 1).Trim();
                            string gacutilPath = System.IO.Path.Combine(sdkPath, @"bin\gacutil.exe");
                            string cmdLineArgument = " -i " + ofd.FileName;
                            process.StartInfo = new ProcessStartInfo(gacutilPath, cmdLineArgument);
                            break;
                        }
                    }
                }
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.UseShellExecute = false;
                process.Start();

                process.WaitForExit();
                string output = process.StandardOutput.ReadToEnd();
                lblTextStatus.Text = output;
            }
        }

        /// <summary>
        /// Extract the selected assemblies
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmdExtract_Click(object sender, EventArgs e)
        {
            List<AssemblyInformation> selectedAssemblies = GetSelectedAssemblies();
            if (selectedAssemblies.Count <= 0)
            {
                MessageBox.Show(this, "No assemblies are selected to extract.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog(this) == DialogResult.OK)
            {
                statusBarPanel4.Text = "Copying..please wait.";                        
                this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
                string folderPath = fbd.SelectedPath;
                try{
                foreach (AssemblyInformation assembly in selectedAssemblies)
                {   // Iterate
                    string fileName = assembly.FileInformation.DirectoryName;
                    fileName = fileName.Substring(fileName.ToLower().IndexOf("assembly") + "assembly".Length + 1);
                    string folderName = Path.Combine(folderPath, fileName);
                    DirectoryInfo dInfo = new DirectoryInfo(folderName);
                    if (!dInfo.Exists) dInfo.Create();
                    string destName = Path.Combine(folderName, assembly.FileInformation.Name);
                    if (File.Exists(destName))
                    {
                        File.Delete(destName);
                    }
                    assembly.FileInformation.CopyTo(destName);
                }
                }
                catch(Exception){}
                statusBarPanel4.Text = string.Empty;                        
                this.Cursor = System.Windows.Forms.Cursors.Default;
            }
        }

        /// <summary>
        /// Get the selected assemblies
        /// </summary>
        /// <returns>An instance of <see cref="List<AssemblyInformation>"/>.</returns>
        private List<AssemblyInformation> GetSelectedAssemblies()
        {
            List<AssemblyInformation> assemblies = new List<AssemblyInformation>();
            PopulateSelectedAssemblies(treeView1.Nodes, assemblies);
            return assemblies;
        }

        /// <summary>
        /// Recursively finding the selected assemblies
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="assemblies"></param>
        private void PopulateSelectedAssemblies(TreeNodeCollection nodes, List<AssemblyInformation> assemblies)
        {
            foreach (TreeNode node in nodes)
            {   // iterate
                if ((node.Tag as AssemblyInformation) != null && (node as CheckedTreeNode) != null && (node as CheckedTreeNode).Select)
                {
                    assemblies.Add((node.Tag as AssemblyInformation));
                }
                if (node.Nodes.Count > 0)
                    PopulateSelectedAssemblies(node.Nodes, assemblies);
            }
        }
    }
}

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
Architect
Netherlands Netherlands
Engineer Powered by the Cloud

Comments and Discussions