source: branches/eraser6/Eraser/Program.cs @ 612

Revision 612, 12.3 KB checked in by lowjoel, 6 years ago (diff)

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.

  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Windows.Forms;
25
26using Eraser.Manager;
27using Eraser.Util;
28using Microsoft.Win32;
29using System.IO;
30using System.Runtime.Serialization.Formatters.Binary;
31using System.Globalization;
32using System.Reflection;
33
34namespace Eraser
35{
36    static class Program
37    {
38        /// <summary>
39        /// The main entry point for the application.
40        /// </summary>
41        [STAThread]
42        static void Main(string[] commandLine)
43        {
44            //Trivial case: no command parameters
45            if (commandLine.Length == 0)
46                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.
50            else if (commandLine.Length == 1)
51            {
52                if (commandLine[0] == "/restart" || commandLine[0] == "--restart")
53                {
54                    GUIMain(true);
55                }
56                else
57                {
58                    CommandMain(commandLine);
59                }
60            }
61
62            //The other trivial case: definitely a console application.
63            else
64                CommandMain(commandLine);
65        }
66
67        /// <summary>
68        /// Runs Eraser as a command-line application.
69        /// </summary>
70        /// <param name="commandLine">The command line parameters passed to Eraser.</param>
71        private static void CommandMain(string[] commandLine)
72        {
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>
218        private static void GUIMain(bool isRestart)
219        {
220            Application.EnableVisualStyles();
221            Application.SetCompatibleTextRenderingDefault(false);
222            Application.SafeTopLevelCaptionFormat = S._("Eraser");
223
224            using (ManagerLibrary library = new ManagerLibrary(new Settings()))
225            using (eraserClient = new DirectExecutor())
226            {
227                //Set our UI language
228                EraserSettings settings = new EraserSettings();
229                System.Threading.Thread.CurrentThread.CurrentUICulture =
230                    new CultureInfo(settings.Language);
231
232                //Load the task list
233                if (settings.TaskList != null)
234                    using (MemoryStream stream = new MemoryStream(settings.TaskList))
235                        try
236                        {
237                            eraserClient.LoadTaskList(stream);
238                        }
239                        catch (Exception)
240                        {
241                            settings.TaskList = null;
242                            MessageBox.Show(S._("Could not load task list. All task entries have " +
243                                "been lost."), S._("Eraser"), MessageBoxButtons.OK,
244                                MessageBoxIcon.Error);
245                        }
246
247                //Create the main form
248                MainForm form = new MainForm();
249
250                //Run tasks which are meant to be run on restart
251                if (isRestart)
252                {
253                    eraserClient.QueueRestartTasks();
254                }
255
256                //Run the program
257                eraserClient.Run();
258                Application.Run(form);
259
260                //Save the task list
261                using (MemoryStream stream = new MemoryStream())
262                {
263                    eraserClient.SaveTaskList(stream);
264                    settings.TaskList = stream.ToArray();
265                }
266            }
267        }
268
269        /// <summary>
270        /// The global Executor instance.
271        /// </summary>
272        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);
279    }
280
281    class Settings : Manager.SettingsManager
282    {
283        /// <summary>
284        /// Registry-based storage backing for the Settings class.
285        /// </summary>
286        private class RegistrySettings : Manager.Settings
287        {
288            /// <summary>
289            /// Constructor.
290            /// </summary>
291            /// <param name="key">The registry key to look for the settings in.</param>
292            public RegistrySettings(Guid pluginID, RegistryKey key)
293            {
294                this.key = key;
295            }
296
297            public override object this[string setting]
298            {
299                get
300                {
301                    byte[] currentSetting = (byte[])key.GetValue(setting, null);
302                    if (currentSetting != null && currentSetting.Length != 0)
303                        using (MemoryStream stream = new MemoryStream(currentSetting))
304                            try
305                            {
306                                return new BinaryFormatter().Deserialize(stream);
307                            }
308                            catch (Exception)
309                            {
310                                key.DeleteValue(setting);
311                                MessageBox.Show(S._("Could not load the setting {0} for plugin {1}. " +
312                                    "The setting has been lost.", key, pluginID.ToString()),
313                                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error);
314                            }
315
316                    return null;
317                }
318                set
319                {
320                    if (value == null)
321                    {
322                        key.DeleteValue(setting);
323                    }
324                    else
325                    {
326                        using (MemoryStream stream = new MemoryStream())
327                        {
328                            new BinaryFormatter().Serialize(stream, value);
329                            key.SetValue(setting, stream.ToArray(), RegistryValueKind.Binary);
330                        }
331                    }
332                }
333            }
334
335            /// <summary>
336            /// The GUID of the plugin whose settings this object is storing.
337            /// </summary>
338            private Guid pluginID;
339
340            /// <summary>
341            /// The registry key where the data is stored.
342            /// </summary>
343            private RegistryKey key;
344        }
345
346        public override void Save()
347        {
348        }
349
350        protected override Manager.Settings GetSettings(Guid guid)
351        {
352            //Open the registry key containing the settings
353            const string eraserKeyPath = @"SOFTWARE\Eraser\Eraser 6";
354            RegistryKey eraserKey = Registry.CurrentUser.OpenSubKey(eraserKeyPath, true);
355            if (eraserKey == null)
356                eraserKey = Registry.CurrentUser.CreateSubKey(eraserKeyPath);
357
358            RegistryKey pluginsKey = eraserKey.OpenSubKey(guid.ToString(), true);
359            if (pluginsKey == null)
360                pluginsKey = eraserKey.CreateSubKey(guid.ToString());
361
362            //Return the Settings object.
363            return new RegistrySettings(guid, pluginsKey);
364        }
365    }
366
367    internal class EraserSettings
368    {
369        public EraserSettings()
370        {
371            settings = Manager.ManagerLibrary.Instance.SettingsManager.ModuleSettings;
372        }
373
374        /// <summary>
375        /// Gets or sets the task list, serialised in binary form by the Manager assembly.
376        /// </summary>
377        public byte[] TaskList
378        {
379            get
380            {
381                return (byte[])settings["TaskList"];
382            }
383            set
384            {
385                settings["TaskList"] = value;
386            }
387        }
388
389        /// <summary>
390        /// Gets or sets the LCID of the language which the UI should be displayed in.
391        /// </summary>
392        public string Language
393        {
394            get
395            {
396                return settings["Language"] == null ? 
397                    GetCurrentCulture().Name :
398                    (string)settings["Language"];
399            }
400            set
401            {
402                settings["Language"] = value;
403            }
404        }
405
406        /// <summary>
407        /// Gets or sets a value on whether the main frame should be minimised to the
408        /// system notification area.
409        /// </summary>
410        public bool HideWhenMinimised
411        {
412            get
413            {
414                return settings["HideWhenMinimised"] == null ?
415                    true : (bool)settings["HideWhenMinimised"];
416            }
417            set
418            {
419                settings["HideWhenMinimised"] = value;
420            }
421        }
422
423        /// <summary>
424        /// Gets the current UI culture, correct to the top-level culture (i.e., English
425        /// instead of English (United Kingdom))
426        /// </summary>
427        /// <returns>The CultureInfo of the current UI culture, correct to the top level.</returns>
428        private static CultureInfo GetCurrentCulture()
429        {
430            CultureInfo culture = CultureInfo.CurrentUICulture;
431            while (culture.Parent != CultureInfo.InvariantCulture)
432                culture = culture.Parent;
433
434            return culture;
435        }
436
437        private Manager.Settings settings;
438    }
439}
Note: See TracBrowser for help on using the repository browser.