Add and Remove Assembly
using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.ComponentModel; using System.Globalization; namespace SPaDevToolkit.StsAdm.Commands.Utilities { internal static class Gac { public static void AddAssembly(string assemblyPath) { string mscorcfgStrongName = string.Format(CultureInfo.InvariantCulture, "mscorcfg,Version={0}, Culture={1}, PublicKeyToken={2}", "2.0.0.0", "neutral", "b03f5f7f11d50a3a"); Assembly assembly = Assembly.Load(mscorcfgStrongName); //Type name is not expected to be changed. Type type = assembly.GetType("Microsoft.CLRAdmin.Fusion"); int result; result = (int)Reflection.InvokeMember(type, "AddAssemblytoGac", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, new object[] { assemblyPath }); //If some error occurred if (result != 0) { throw new Exception(string.Format(CultureInfo.InvariantCulture, "Assembly could not be placed in GAC. Error code returned was {0}", result.ToString())); } } public static void RemoveAssembly(string assemblyPath) { //Get assembly strong name details string strongName = Assembly.LoadFrom(assemblyPath).FullName; string[] strongNameParts = strongName.Split(new char[] { ',' }); string assemblyName = strongNameParts[0]; string version = strongNameParts[1].Split(new char[] { '=' })[1]; string publicKey = strongNameParts[3].Split(new char[] { '=' })[1]; string configFileStrongName = string.Format(CultureInfo.InvariantCulture, "mscorcfg,Version={0}, Culture={1}, PublicKeyToken={2}", "2.0.0.0", "neutral", "b03f5f7f11d50a3a"); Assembly assembly = Assembly.Load(configFileStrongName); //Type name is not expected to be changed. Type fusionType = assembly.GetType("Microsoft.CLRAdmin.Fusion"); //MethodInfo mi = fusionType.GetMethod("RemoveAssemblyFromGac", BindingFlags.NonPublic | BindingFlags.Static); //Create variable of AssemInfo struct Type assemblyInfoType = assembly.GetType("Microsoft.CLRAdmin.AssemInfo"); object assemInfo = Activator.CreateInstance(assemblyInfoType, true); //Binding flags to filter/search out fields in the type BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.GetField; //Set field values. //Disassembler shows only following fields are used by RemoveAssemblyFromGac method. //FieldInfo sName = assemblyInfoType.GetField("Name", bindingFlags); //sName.SetValue(assemInfo, assemblyName); Reflection.SetField(assemInfo, "Name", new object[] { assemblyName }); //FieldInfo sVersion = assemblyInfoType.GetField("Version", bindingFlags); //sVersion.SetValue(assemInfo, version); Reflection.SetField(assemInfo, "Version", new object[] { version }); //FieldInfo sPublicKeyToken = assemblyInfoType.GetField("PublicKeyToken", bindingFlags); //sPublicKeyToken.SetValue(assemInfo, publicKey); Reflection.SetField(assemInfo, "PublicKeyToken", new object[] { publicKey }); //FieldInfo sFusionName = assemblyInfoType.GetField("sFusionName", bindingFlags); //sFusionName.SetValue(assemInfo, string.Format(CultureInfo.InvariantCulture, "{0}{1}", strongName, ", processorArchitecture=MSIL")); Reflection.SetField(assemInfo, "sFusionName", new object[] { string.Format(CultureInfo.InvariantCulture, "{0}{1}", strongName, ", processorArchitecture=MSIL") }); //FieldInfo nCacheType = assemblyInfoType.GetField("nCacheType", bindingFlags); //nCacheType.SetValue(assemInfo, (uint)2); Reflection.SetField(assemInfo, "nCacheType", new object[] { (uint)2 }); bool result; //result = (bool)mi.Invoke(null, new object[] { assemInfo }); result = (bool)Reflection.InvokeMember(fusionType, "RemoveAssemblyFromGac", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, new object[] { assemInfo }); //If some error occurred if (!result) { throw new Exception(string.Format(CultureInfo.InvariantCulture, "Assembly could not be uninstalled from GAC. Error code returned was {0}", result.ToString())); } } internal static class Reflection { public static object InvokeMember(object src, string strName, BindingFlags type, object[] args) { bool bStatic = (src is Type); Type t = bStatic ? (Type)src : src.GetType(); BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.DeclaredOnly | (bStatic ? BindingFlags.Static : BindingFlags.Instance) | type; object target = (bStatic ? null : src); return (t.InvokeMember(strName, bindingFlags, null, target, args)); } public static object GetProperty(object src, string strName) { return (InvokeMember(src, strName, BindingFlags.GetProperty, null)); } public static object SetProperty(object src, string strName, object[] args) { return (InvokeMember(src, strName, BindingFlags.SetProperty, args)); } public static object GetField(object src, string strName) { return (InvokeMember(src, strName, BindingFlags.GetField, null)); } public static object SetField(object src, string strName, object[] args) { return (InvokeMember(src, strName, BindingFlags.SetField, args)); } } }