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));
}
}
}
Related examples in the same category