// ====================================
// AssemblyLister
// ====================================
//
// Author: Jon Davis <jon@jondavis.net>
// http://www.jondavis.net/
//
// Date: 4/10/2006
//
// ====================================
// Abstract:
// ====================================
// This is a console application that will search for
// CLR-loadable assemblies in a specified path and
// also optionally execute ngen.exe which should be
// located in the path identified by the "CLRDIR"
// environment variable.
//
// ====================================
// To build:
// ====================================
// Create a console app in Visual Studio 2005 and
// replace the contents of Program.cs with the entire
// content of this web page. In the project properties,
// I recommend naming the assembly "AssemLst.exe".
// Once built, I also recommend copying it to your
// Framework directory, e.g.
// C:\Windows\Microsoft.net\Framework\v2.*\
//
// ====================================
// To use:
// ====================================
// Just execute ...
//
// AssemLst.exe /?
//
// ... to learn how to use the console application.
//
// ====================================
// Your license:
// ====================================
// You may compile this console app for personal
// use. You may not redistribute the compiled
// application, but you may redistribute this source
// as long as author credit is recognized.
//
using System;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
namespace AssemblyLister
{
class Program
{
static System.IO.FileInfo fi = new FileInfo(Assembly.GetExecutingAssembly().Location);
static string BaseArgHelp = "\r\n"
+ fi.Name + " [ -s ] [ -ngen [ -uninstall ] ] [ directory or file ]\r\n\r\n"
+ "Evaluates the specified file(s) or directory(ies) to determine whether they are CLR-loadable assemblies.\r\n\r\n"
+ "-s\t\t\tScans subdirectories. (Default is DISABLED.)\r\n\n"
+ "-v\t\t\tVerbose mode. (Default is DISABLED.)\r\n\n"
+ "-ngen [-uninstall]\tInstalls [or uninstalls] the assembly by pre-JIT'ing\r\n\t\t\twith ngen.exe."
+ " (Default is DISABLED.)\r\n\n"
+ "[directory]\t\tScans the specified path for CLR assembly files.\r\n"
+ "\t\t\tMatches are listed.\r\n\n"
+ "[file]\t\t\tScans the specified file to determine if it is an\r\n"
+ "\t\t\tassembly file. If it is, the path is repeated.\r\n\n";
static void Main(string[] args)
{
bool bFollowSubDirs = false;
bool bNgen = false;
bool bVerbose = false;
bool bNgenUninstall = false;
int f = 0;
for (int i = 0; i < args.Length; i++)
{
string arg = args[i];
if (arg.StartsWith("-") || arg.StartsWith("/"))
{
switch (arg.ToLower())
{
case "-s":
case "/s":
bFollowSubDirs = true;
break;
case "-v":
case "/v":
bVerbose = true;
break;
case "-ngen":
case "/ngen":
bNgen = true;
try
{
if (args[i + 1].ToLower() == "-uninstall" || args[i + 1].ToLower() == "/uninstall")
{
bNgenUninstall = true;
i++;
}
}
catch { }
break;
case "-?":
case "/?":
case "-help":
case "/help":
default:
Console.WriteLine(BaseArgHelp);
return;
}
}
else f++;
}
if (f == 0)
{
Console.WriteLine(BaseArgHelp);
return;
}
if (bVerbose) Console.WriteLine();
for (int i = 0; i < args.Length; i++)
{
string arg = args[i];
if (arg == ".") arg = Directory.GetCurrentDirectory();
if (!(arg.StartsWith("-") || arg.StartsWith("/")))
{
if (File.Exists(arg))
{
EvalFileForCLR(arg, true);
if (bNgen)
{
try
{
RunNgen(arg, bNgenUninstall, bVerbose);
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
return; // abort
}
}
}
else if (Directory.Exists(arg))
{
string[] matches = EvalDirForCLR(arg, bFollowSubDirs, true);
if (matches.Length > 0)
{
if (bVerbose) Console.WriteLine("\r\nFound " + matches.Length + " matches in " + arg + ".\r\n");
}
//foreach (string m in matches)
//{
// Console.WriteLine(m);
//}
if (bNgen)
{
if (bVerbose)
{
Console.WriteLine();
Console.WriteLine("Executing NGen ...");
Console.WriteLine();
}
foreach (string m in matches)
{
try
{
RunNgen(m, bNgenUninstall, bVerbose);
}
catch (Exception ex)
{
System.Console.WriteLine("Error executing NGen: " + ex.Message);
return; // abort
}
}
}
}
}
}
#if DEBUG
Console.WriteLine("Press Enter to continue.");
Console.ReadLine();
#endif
}
static bool EvalFileForCLR(string file, bool bOutputToConsole)
{
try
{
AssemblyName.GetAssemblyName(file);
if (bOutputToConsole) Console.WriteLine(file);
return true;
}
catch
{
return false;
}
}
static string[] EvalDirForCLR(string dir, bool bSubdirs, bool bOutputToConsole)
{
StringCollection sc = new StringCollection();
StringCollection files = new StringCollection();
files.AddRange(Directory.GetFiles(dir, "*.exe"));
files.AddRange(Directory.GetFiles(dir, "*.dll"));
foreach (string file in files)
{
if (EvalFileForCLR(file, bOutputToConsole))
{
sc.Add(file);
}
}
if (bSubdirs)
{
string[] subfolders = Directory.GetDirectories(dir);
foreach (string sf in subfolders)
{
sc.AddRange(Program.EvalDirForCLR(sf, bSubdirs, true));
}
}
string[] ret = new string[sc.Count];
sc.CopyTo(ret, 0);
return ret;
}
static void RunNgen(string assem, bool bUninstall, bool bVerbose)
{
string curdir = Directory.GetCurrentDirectory();
Directory.SetCurrentDirectory(Directory.GetParent(assem).FullName);
string dnpath = System.Environment.GetEnvironmentVariable("CLRDIR");
string sNgen = dnpath + "\\ngen.exe";
string sNgenArgs = "";
if (bUninstall) sNgenArgs += "uninstall ";
else sNgenArgs += "install ";
sNgenArgs += "\"" + assem + "\"";
if (bVerbose) Console.WriteLine("Executing: [ " + sNgen + " " + sNgenArgs + " ]");
else Console.WriteLine(sNgen + " " + sNgenArgs);
System.Diagnostics.ProcessStartInfo spi = new System.Diagnostics.ProcessStartInfo(sNgen, sNgenArgs);
spi.CreateNoWindow = true;
spi.RedirectStandardError = true;
spi.RedirectStandardInput = true;
spi.RedirectStandardOutput = true;
spi.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(spi);
if (bVerbose)
{
p.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(NGen_OutputDataReceived);
p.BeginOutputReadLine();
}
p.WaitForExit();
Directory.SetCurrentDirectory(curdir);
}
static void NGen_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
Console.WriteLine(e.Data);
}
}
}