msnmsn.cs

 
   1  using System;
   2  using System.Collections.Generic;
   3  using System.Diagnostics;
   4  using System.Globalization;
   5  using System.IO;
   6  using System.Reflection;
   7  using System.Text;
   8  
   9  namespace MS.StrongName.ManagedSN
  10  {
  11       /// <summary>
  12       ///      Entry point for the ManagedSN tool.  Handles the first level of command line parsing
  13       ///      and dispatching to appropriate methods for each option. 
  14       /// </summary>
  15      public static class ManagedStrongName
  16      {
  17           /// <summary>
  18           ///      Return code for successfully completion
  19           /// </summary>
  20          public const int SuccessCode = 0;
  21          
  22           /// <summary>
  23           ///      Return code when an error occurs or a failed completion
  24           /// </summary>
  25          public const int ErrorCode = 101;
  26  
  27          private static IDictionary<string, Command> commands = null;
  28  
  29           /// <summary>
  30           ///      Table of available commands
  31           /// </summary>
  32          internal static IDictionary<string, Command> CommandTable
  33          {
  34              get
  35              {
  36                  if(commands == null)
  37                      commands = CreateCommandTable();
  38  
  39                  return commands;
  40              }
  41          }
  42          
  43           /// <summary>
  44           ///      Managed tool that provides the same services as the .NET SDK's sn.exe tool
  45           /// </summary>
  46          public static int Main(string[] args)
  47          {
  48              Log.Message(String.Format(
  49                  CultureInfo.CurrentCulture,
  50                  Resources.Header,
  51                  FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion));
  52              Log.Message(String.Empty);
  53  
  54               // make sure we hook all unexpected errors to fail more gracefully
  55              AppDomain.CurrentDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
  56              {
  57                  Log.Error(Resources.InternalError);
  58                  Log.Error(e.ExceptionObject.ToString());
  59                  return;
  60              };
  61              
  62               // get the first command line option
  63              string option;
  64              if(args.Length >= 1)
  65              {
  66                  option = args[0].Trim();
  67                  if(String.IsNullOrEmpty(option))
  68                      option = "?";    // empty means get help
  69                  
  70                   // get the - or / off the front of the option
  71                  if(option[0] == '-' || option[0] == '/')
  72                      option = option.Substring(1, option.Length - 1);
  73              }
  74              else
  75                  option = "?";        // no options means get help
  76  
  77               // go do what's requested of us
  78              OptionHandler handler;
  79              Command command = CommandTable[option];
  80  
  81               // null means we had an invalid option
  82              if(command == null)
  83                  handler = new OptionHandler(InvalidOption);
  84              else
  85                  handler = command.Handler;
  86  
  87              return handler(args);
  88          }
  89  
  90           /// <summary>
  91           ///      Setup the table of options -> SN commands
  92           /// </summary>
  93           /// <returns>A dictionary mapping option names to Command objects</returns>
  94          private static IDictionary<string, Command> CreateCommandTable()
  95          {
  96              Command[] commandList = new Command[]
  97              {
  98                  new Command("d", new OptionHandler(Commands.DeleteKeyPair), Resources.DeleteKeyPairArguments, Resources.DeleteKeyPairHelp),
  99                  new Command("e", new OptionHandler(Commands.ExtractAssemblyPublicKey), Resources.ExtractAssemblyPublicKeyArguments, Resources.ExtractAssemblyPublicKeyHelp),
 100                  new Command("h", new OptionHandler(Commands.Help), null, Resources.HelpHelp),
 101                  new Command("?", new OptionHandler(Commands.Help), null, Resources.HelpHelp),
 102                  new Command("i", new OptionHandler(Commands.InstallKeyPair), Resources.InstallKeyPairArguments, Resources.InstallKeyPairHelp),
 103                  new Command("k", new OptionHandler(Commands.GenerateKey), Resources.GenerateKeyArguments, Resources.GenerateKeyHelp),
 104                  new Command("m", new OptionHandler(Commands.MachineKeyStore), Resources.MachineKeyStoreArguments, Resources.MachineKeyStoreHelp),
 105                  new Command("p", new OptionHandler(Commands.ExtractPublicKeyFromKeyPair), Resources.ExtractPublicKeyFromKeyPairArguments, Resources.ExtractPublicKeyFromKeyPairHelp),
 106                  new Command("pc", new OptionHandler(Commands.ExtractPublicKeyFromKeyContainer), Resources.ExtractPublicKeyFromKeyContainerArguments, Resources.ExtractPublicKeyFromKeyContainerHelp),
 107                  new Command("t", new OptionHandler(Commands.DisplayPublicKeyTokenFromFile), Resources.DisplayPublicKeyTokenFromFileArguments, Resources.DisplayPublicKeyTokenFromFileHelp),
 108                  new Command("tp", new OptionHandler(Commands.DisplayPublicKeyTokenWithKeyFromFile), Resources.DisplayPublicKeyTokenWithKeyFromFileArguments, Resources.DisplayPublicKeyTokenWithKeyFromFileHelp),
 109                  new Command("T", new OptionHandler(Commands.DisplayPublicKeyTokenFromAssembly), Resources.DisplayPublicKeyTokenFromAssemblyArguments, Resources.DisplayPublicKeyTokenFromAssemblyHelp),
 110                  new Command("Tp", new OptionHandler(Commands.DisplayPublicKeyTokenWithKeyFromAssembly), Resources.DisplayPublicKeyTokenWithKeyFromAssemblyArguments, Resources.DisplayPublicKeyTokenWithKeyFromAssemblyHelp),
 111                  new Command("v", new OptionHandler(Commands.Verify), Resources.VerifyArguments, Resources.VerifyHelp),
 112                  new Command("vf", new OptionHandler(Commands.ForceVerify), Resources.ForceVerifyArguments, Resources.ForceVerifyHelp)
 113              };
 114              
 115               // set the commands up in a dictionary
 116              Dictionary<string, Command> commandTable = new Dictionary<string, Command>(commandList.Length);
 117              foreach(Command command in commandList)
 118                  commandTable[command.Option] = command;
 119  
 120              return commandTable;
 121          }
 122          
 123           /// <summary>
 124           ///      Display help for an invalid option
 125           /// </summary>
 126          private static int InvalidOption(string[] arguments)
 127          {
 128              Debug.Assert(arguments.Length > 0);
 129              
 130              Log.Error(String.Format(
 131                  CultureInfo.InvariantCulture,
 132                  Resources.InvalidOption,
 133                  arguments[0]));
 134              Log.Error(String.Empty);
 135  
 136              return Commands.Help(arguments);
 137          }
 138  
 139           /// <summary>
 140           ///      Format a help string to be displayed on multiple lines
 141           /// </summary>
 142           /// <param name="help">help string to format</param>
 143           /// <param name="padding">number of spaces to add to the beginning of each line</param>
 144          public static string[] FormatHelp(string help, int padding)
 145          {
 146              Debug.Assert(help != null, "Null help string");
 147              Debug.Assert(padding >= 0, "Invalid padding value");
 148  
 149              int consoleSize = Console.WindowWidth;
 150              List<string> lines = new List<string>((help.Length / consoleSize) + 1);
 151  
 152               // split on whitespace
 153              string[] words = help.Split(new char[] {' ', '\t', '\n'});
 154              
 155               // setup the first line
 156              StringBuilder currentLine = new StringBuilder(consoleSize);
 157              currentLine.Append(' ', (int)padding);
 158  
 159               // add each word in the help text
 160              foreach(string word in words)
 161              {
 162                   // if this word will make the line too big, start a new line
 163                   // allow an exception for the first word of a line, to prevent
 164                   // infinite looping when one word is bigger than the console
 165                  if(currentLine.Length != padding && currentLine.Length + word.Length >= consoleSize)
 166                  {
 167                      lines.Add(currentLine.ToString());
 168                  
 169                      currentLine = new StringBuilder(consoleSize);
 170                      currentLine.Append(' ', (int)padding);
 171                  }
 172  
 173                  currentLine.Append(word);
 174                  currentLine.Append(' ');
 175              }
 176              
 177               // finish the last line
 178              lines.Add(currentLine.ToString());
 179              return lines.ToArray();
 180          }
 181      }
 182  }