using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Runtime.InteropServices;
using System.Data;
using System.IO;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.ComponentModel;
using System.Runtime.Remoting;
namespace CodeDomAssistant
{
public class DynProvider
{
static public DataSet GetAssemblyInfo()
{
DataSet data = new DataSet();
data.DataSetName = "AssemblyDataSet";
DataTable table = data.Tables.Add("Assembly");
table.Columns.Add("Load", typeof(bool));
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Path", typeof(string));
table.Columns.Add("IsGAC", typeof(bool));
table.Columns.Add("HasProvider", typeof(bool));
string localpath = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CodeDomAssistant");
if (!Directory.Exists(localpath))
{
Directory.CreateDirectory(localpath);
}
string assemblydatafile = Path.Combine(localpath, "AssemblyData.xml");
if (File.Exists(assemblydatafile))
{
data.ReadXml(assemblydatafile);
}
data.AcceptChanges();
return data;
}
static public void SaveAssemblyInfo(DataSet assemblydata)
{
string localpath = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CodeDomAssistant");
if (!Directory.Exists(localpath))
{
Directory.CreateDirectory(localpath);
}
string assemblydatafile = Path.Combine(localpath, "AssemblyData.xml");
assemblydata.WriteXml(assemblydatafile);
assemblydata.AcceptChanges();
}
static public void MergeLocal(DataSet assemblydata, string assemblyfile, Progress progress)
{
DataRow assemblyInfo = null;
bool updated = false;
bool hasprovider = false;
AppDomain appdomain = null;
try
{
if (progress != null)
{
progress.Message = string.Format("Scanning DLL: {0}", Path.GetFileName(assemblyfile));
progress.Notify();
}
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
appdomain = AppDomain.CreateDomain("TestCodeDomProviders", null, setup);
ObjectHandle handle = appdomain.CreateInstance("RemoteLoader", "RemoteLoader.RemoteLoaderFactory");
RemoteLoader.RemoteLoaderFactory factory = (RemoteLoader.RemoteLoaderFactory)handle.Unwrap();
string name = factory.GetAssemblyName(assemblyfile);
if (name != null)
{
hasprovider = factory.IsSubclassOfCodeDomProvider(assemblyfile);
DataRow[] rows = assemblydata.Tables[0].Select(string.Format(@"Path = '{0}'", assemblyfile));
if (rows.Length == 0)
assemblyInfo = assemblydata.Tables[0].NewRow();
else
assemblyInfo = rows[0];
assemblyInfo["Load"] = false;
assemblyInfo["Name"] = name;
assemblyInfo["Path"] = assemblyfile;
assemblyInfo["IsGAC"] = false;
assemblyInfo["HasProvider"] = hasprovider;
if (rows.Length == 0)
{
assemblydata.Tables[0].Rows.Add(assemblyInfo);
}
updated = true;
}
}
finally
{
if (appdomain != null)
{
AppDomain.Unload(appdomain);
}
}
}
static public void MergeGAC(DataSet assemblydata, bool refreshcache, Progress progress)
{
bool updated = false;
AppDomain appdomain = null;
try
{
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
appdomain = AppDomain.CreateDomain("FindCodeDomProviders", null, setup);
ObjectHandle handle = appdomain.CreateInstance("RemoteLoader", "RemoteLoader.RemoteLoaderFactory");
RemoteLoader.RemoteLoaderFactory factory = (RemoteLoader.RemoteLoaderFactory)handle.Unwrap();
string strGacDir = Path.Combine(System.Environment.ExpandEnvironmentVariables("%windir%"), @"assembly\GAC");
string[] gac = System.IO.Directory.GetDirectories(strGacDir);
foreach (string dir in gac)
{
if (progress != null)
{
progress.Message = string.Format("Scanning GAC: {0}", Path.GetFileName(dir));
progress.Notify();
}
string[] assDirs = System.IO.Directory.GetDirectories(dir);
foreach (string dir2 in assDirs)
{
string[] files = System.IO.Directory.GetFiles(dir2, "*.dll");
foreach (string assemblyfile in files)
{
DataRow[] rows = assemblydata.Tables[0].Select(string.Format(@"Path = '{0}'", assemblyfile));
if (rows.Length == 0 || refreshcache)
{
string name = factory.GetAssemblyName(assemblyfile);
if (name != null)
{
bool hasprovider = factory.IsSubclassOfCodeDomProvider(assemblyfile);
DataRow assemblyInfo = null;
if (rows.Length == 0)
assemblyInfo = assemblydata.Tables[0].NewRow();
else
assemblyInfo = rows[0];
assemblyInfo = assemblydata.Tables[0].NewRow();
assemblyInfo["Load"] = false;
assemblyInfo["Name"] = name;
assemblyInfo["Path"] = assemblyfile;
assemblyInfo["IsGAC"] = true;
assemblyInfo["HasProvider"] = hasprovider;
if (rows.Length == 0)
{
assemblydata.Tables[0].Rows.Add(assemblyInfo);
}
updated = true;
}
}
}
}
}
}
finally
{
if (appdomain != null)
{
AppDomain.Unload(appdomain);
}
}
}
}
}