Changeset 612


Ignore:
Timestamp:
11/22/2008 1:33:03 AM (6 years ago)
Author:
lowjoel
Message:

Allow Eraser to run as a command line application (create our own console window). Define three actions: addtask, help and querymethods. Currently, help text and parameter parsing is implemented.

Location:
branches/eraser6
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser/Program.cs

    r608 r612  
    3030using System.Runtime.Serialization.Formatters.Binary; 
    3131using System.Globalization; 
     32using System.Reflection; 
    3233 
    3334namespace Eraser 
     
    4142        static void Main(string[] commandLine) 
    4243        { 
     44            //Trivial case: no command parameters 
    4345            if (commandLine.Length == 0) 
    4446                GUIMain(false); 
     47 
     48            //Determine if the sole parameter is --restart; if it is, start the GUI 
     49            //passing isRestart as true. Otherwise, we're a console application. 
    4550            else if (commandLine.Length == 1) 
    4651            { 
    47                 if (commandLine[0].Substring(0, 1) == "/" || 
    48                     commandLine[0].Substring(0, 2) == "--") 
     52                if (commandLine[0] == "/restart" || commandLine[0] == "--restart") 
    4953                { 
    5054                    GUIMain(true); 
     
    5559                } 
    5660            } 
     61 
     62            //The other trivial case: definitely a console application. 
    5763            else 
    5864                CommandMain(commandLine); 
    5965        } 
    6066 
     67        /// <summary> 
     68        /// Runs Eraser as a command-line application. 
     69        /// </summary> 
     70        /// <param name="commandLine">The command line parameters passed to Eraser.</param> 
    6171        private static void CommandMain(string[] commandLine) 
    6272        { 
    63         } 
    64  
     73            //Create a console for our GUI app. 
     74            KernelAPI.AllocConsole(); 
     75            Console.SetOut(new StreamWriter(Console.OpenStandardOutput())); 
     76            Console.SetIn(new StreamReader(Console.OpenStandardInput())); 
     77 
     78            //Map commands to our functions. 
     79            Dictionary<string, CommandHandler> handlers = 
     80                new Dictionary<string, CommandHandler>(); 
     81            handlers.Add("addtask", CommandAddTask); 
     82            handlers.Add("querymethods", CommandQueryMethods); 
     83            handlers.Add("help", delegate(Dictionary<string, string> arguments) 
     84                { 
     85                    CommandHelp(); 
     86                }); 
     87 
     88            try 
     89            { 
     90                //Get the command. 
     91                if (commandLine.Length < 1) 
     92                { 
     93                    CommandHelp(); 
     94                    return; 
     95                } 
     96                else if (!handlers.ContainsKey(commandLine[0])) 
     97                    throw new ArgumentException("Unknown action: " + commandLine[0]);    
     98 
     99                //Parse the command line. 
     100                Dictionary<string, string> cmdParams = new Dictionary<string, string>(); 
     101                for (int i = 1; i != commandLine.Length; ++i) 
     102                { 
     103                    string param = commandLine[i]; 
     104                    if (param.Length == 0) 
     105                        continue; 
     106 
     107                    if (param[0] == '/' || param[0] == '-') 
     108                    { 
     109                        //Ignore the second hyphen if the user specified --X 
     110                        if (param[0] == '-' && param.Length >= 2 && param[1] == '-') 
     111                            param = param.Substring(2); 
     112                        else 
     113                            param = param.Substring(1); 
     114 
     115                        //Separate the key/value at the first equal sign. 
     116                        int eqIdx = param.IndexOf('='); 
     117                        if (eqIdx != -1) 
     118                            cmdParams.Add(param.Substring(0, eqIdx), param.Substring(eqIdx + 1)); 
     119                        else 
     120                            cmdParams.Add(param, null); 
     121                    } 
     122                    else 
     123                    { 
     124                        throw new ArgumentException("Invalid command line parameter: " + 
     125                            param); 
     126                    } 
     127                } 
     128 
     129                //Call the function 
     130                handlers[commandLine[0]](cmdParams); 
     131            } 
     132            catch (ArgumentException e) 
     133            { 
     134                Console.WriteLine(e.Message + "\n"); 
     135                CommandUsage(); 
     136            } 
     137            finally 
     138            { 
     139                //Flush the buffer since we may have got buffered output. 
     140                Console.Out.Flush(); 
     141 
     142                Console.Write("\nPress any key to continue . . . "); 
     143                Console.Out.Flush(); 
     144                Console.ReadLine(); 
     145 
     146                //We are no longer using the console, release it. 
     147                KernelAPI.FreeConsole(); 
     148            } 
     149        } 
     150 
     151        /// <summary> 
     152        /// Parses the command line for tasks and adds them using the 
     153        /// <see cref="RemoteExecutor"/> class. 
     154        /// </summary> 
     155        /// <param name="commandLine">The command line parameters passed to the program.</param> 
     156        private static void CommandAddTask(Dictionary<string, string> arguments) 
     157        { 
     158            throw new NotImplementedException(); 
     159        } 
     160 
     161        /// <summary> 
     162        /// Lists all registered erasure methods. 
     163        /// </summary> 
     164        /// <param name="commandLine">The command line parameters passed to the program.</param> 
     165        private static void CommandQueryMethods(Dictionary<string, string> arguments) 
     166        { 
     167            throw new NotImplementedException(); 
     168        } 
     169 
     170        /// <summary> 
     171        /// Prints the help text for Eraser (with copyright) 
     172        /// </summary> 
     173        private static void CommandHelp() 
     174        { 
     175            Console.WriteLine(@"Eraser {0} 
     176(c) 2008 The Eraser Project 
     177Eraser is Open-Source Software: see http://eraser.heidi.ie/ for details. 
     178",  Assembly.GetExecutingAssembly().GetName().Version); 
     179 
     180            Console.Out.Flush(); 
     181            CommandUsage(); 
     182        } 
     183 
     184        /// <summary> 
     185        /// Prints the command line help for Eraser. 
     186        /// </summary> 
     187        private static void CommandUsage() 
     188        { 
     189            Console.WriteLine(@"usage: Eraser <action> <arguments> 
     190where action is 
     191    addtask                 Adds tasks to the current task list. 
     192    querymethods            Lists all registered Erasure methods. 
     193 
     194parameters for addtask: 
     195    eraser addtask --method <methodGUID> (--recycled | --unused=<volume> | " + 
     196@"--dir=<directory> | [file1 [file2 [...]]]) 
     197 
     198    --method, -m            The Erasure method to use. 
     199    --recycled, -r          Erases files and folders in the recycle bin 
     200    --unused, -u            Erases unused space in the volume. 
     201    --dir, --directory, -d  Erases files and folders in the directory 
     202        optional arguments: --dir=<directory>[,e=excludeMask][,i=includeMask] 
     203            excludeMask     A wildcard expression for files and folders to exclude. 
     204            includeMask     A wildcard expression for files and folders to include. 
     205                            The include mask is applied before the exclude mask. 
     206    file1 ... fileN         The list of files to erase. 
     207 
     208parameters for querymethods: 
     209    eraser querymethods"); 
     210            Console.Out.Flush(); 
     211        } 
     212 
     213        /// <summary> 
     214        /// Runs Eraser as a GUI application. 
     215        /// </summary> 
     216        /// <param name="isRestart">True if the program was passed the --restart 
     217        /// switch.</param> 
    65218        private static void GUIMain(bool isRestart) 
    66219        { 
     
    118271        /// </summary> 
    119272        public static Executor eraserClient; 
     273 
     274        /// <summary> 
     275        /// Handles commands passed to the program 
     276        /// </summary> 
     277        /// <param name="arguments">The arguments to the command</param> 
     278        private delegate void CommandHandler(Dictionary<string, string> arguments); 
    120279    } 
    121280 
  • branches/eraser6/Util/KernelAPI.cs

    r512 r612  
    2525using System.Reflection; 
    2626using System.Runtime.InteropServices; 
     27using Microsoft.Win32.SafeHandles; 
    2728 
    2829namespace Eraser.Util 
     
    693694            ES_USER_PRESENT = 0x00000004 
    694695        } 
     696 
     697        /// <summary> 
     698        /// Allocates a new console for the calling process. 
     699        /// </summary> 
     700        /// <returns>If the function succeeds, the return value is nonzero. 
     701        ///  
     702        /// If the function fails, the return value is zero. To get extended error 
     703        /// information, call Marshal.GetLastWin32Error.</returns> 
     704        /// <remarks>A process can be associated with only one console, so the AllocConsole 
     705        /// function fails if the calling process already has a console. A process can 
     706        /// use the FreeConsole function to detach itself from its current console, then 
     707        /// it can call AllocConsole to create a new console or AttachConsole to attach 
     708        /// to another console. 
     709        ///  
     710        /// If the calling process creates a child process, the child inherits the 
     711        /// new console. 
     712        ///  
     713        /// AllocConsole initializes standard input, standard output, and standard error 
     714        /// handles for the new console. The standard input handle is a handle to the 
     715        /// console's input buffer, and the standard output and standard error handles 
     716        /// are handles to the console's screen buffer. To retrieve these handles, use 
     717        /// the GetStdHandle function. 
     718        ///  
     719        /// This function is primarily used by graphical user interface (GUI) application 
     720        /// to create a console window. GUI applications are initialized without a 
     721        /// console. Console applications are initialized with a console, unless they 
     722        /// are created as detached processes (by calling the CreateProcess function 
     723        /// with the DETACHED_PROCESS flag).</remarks> 
     724        [DllImport("Kernel32.dll", SetLastError = true)] 
     725        public static extern bool AllocConsole(); 
     726 
     727        /// <summary> 
     728        /// Detaches the calling process from its console. 
     729        /// </summary> 
     730        /// <returns>If the function succeeds, the return value is nonzero. 
     731        ///  
     732        /// If the function fails, the return value is zero. To get extended error 
     733        /// information, call Marshal.GetLastWin32Error.</returns> 
     734        /// <remarks>A process can be attached to at most one console. If the calling 
     735        /// process is not already attached to a console, the error code returned is 
     736        /// ERROR_INVALID_PARAMETER (87). 
     737        ///  
     738        /// A process can use the FreeConsole function to detach itself from its 
     739        /// console. If other processes share the console, the console is not destroyed, 
     740        /// but the process that called FreeConsole cannot refer to it. A console is 
     741        /// closed when the last process attached to it terminates or calls FreeConsole. 
     742        /// After a process calls FreeConsole, it can call the AllocConsole function to 
     743        /// create a new console or AttachConsole to attach to another console.</remarks> 
     744        [DllImport("Kernel32.dll", SetLastError = true)] 
     745        public static extern bool FreeConsole(); 
    695746    } 
    696747} 
Note: See TracChangeset for help on using the changeset viewer.