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

Revision 616, 13.0 KB checked in by lowjoel, 6 years ago (diff)

Allow the user to specify that he wants a quiet session.

  • 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            //Map commands to our functions.
74            Dictionary<string, CommandHandler> handlers =
75                new Dictionary<string, CommandHandler>();
76            handlers.Add("addtask", CommandAddTask);
77            handlers.Add("querymethods", CommandQueryMethods);
78            handlers.Add("help", delegate(Dictionary<string, string> arguments)
79                {
80                    CommandHelp();
81                });
82
83            try
84            {
85                //Get the command.
86                if (commandLine.Length < 1)
87                {
88                    CommandCreateConsole();
89                    CommandHelp();
90                    return;
91                }
92                else if (!handlers.ContainsKey(commandLine[0]))
93                    throw new ArgumentException("Unknown action: " + commandLine[0]);
94
95                //Parse the command line.
96                Dictionary<string, string> cmdParams = new Dictionary<string, string>();
97                for (int i = 1; i != commandLine.Length; ++i)
98                {
99                    string param = commandLine[i];
100                    if (param.Length == 0)
101                        continue;
102
103                    if (param[0] == '/' || param[0] == '-')
104                    {
105                        //Ignore the second hyphen if the user specified --X
106                        if (param[0] == '-' && param.Length >= 2 && param[1] == '-')
107                            param = param.Substring(2);
108                        else
109                            param = param.Substring(1);
110
111                        //Separate the key/value at the first equal sign.
112                        int eqIdx = param.IndexOf('=');
113                        if (eqIdx != -1)
114                            cmdParams.Add(param.Substring(0, eqIdx), param.Substring(eqIdx + 1));
115                        else
116                            cmdParams.Add(param, null);
117                    }
118                    else
119                    {
120                        throw new ArgumentException("Invalid command line parameter: " +
121                            param);
122                    }
123                }
124
125                //If the user did not specify the quiet command line, then create the console.
126                if (!cmdParams.ContainsKey("q") && !cmdParams.ContainsKey("quiet"))
127                    CommandCreateConsole();
128
129                //Call the function
130                using (ManagerLibrary library = new ManagerLibrary(new Settings()))
131                using (eraserClient = new RemoteExecutorClient())
132                    handlers[commandLine[0]](cmdParams);
133            }
134            catch (ArgumentException e)
135            {
136                CommandCreateConsole();
137                Console.WriteLine(e.Message + "\n");
138                CommandUsage();
139            }
140            catch (Exception e)
141            {
142                Console.WriteLine(e.Message);
143            }
144            finally
145            {
146                //Flush the buffer since we may have got buffered output.
147                Console.Out.Flush();
148
149                Console.Write("\nPress any key to continue . . . ");
150                Console.Out.Flush();
151                Console.ReadLine();
152
153                //We are no longer using the console, release it.
154                KernelAPI.FreeConsole();
155            }
156        }
157
158        /// <summary>
159        /// Creates a console for our application, setting the input/output streams to the
160        /// defaults.
161        /// </summary>
162        private static void CommandCreateConsole()
163        {
164            KernelAPI.AllocConsole();
165            Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
166            Console.SetIn(new StreamReader(Console.OpenStandardInput()));
167        }
168
169        /// <summary>
170        /// Parses the command line for tasks and adds them using the
171        /// <see cref="RemoteExecutor"/> class.
172        /// </summary>
173        /// <param name="commandLine">The command line parameters passed to the program.</param>
174        private static void CommandAddTask(Dictionary<string, string> arguments)
175        {
176            throw new NotImplementedException();
177        }
178
179        /// <summary>
180        /// Lists all registered erasure methods.
181        /// </summary>
182        /// <param name="commandLine">The command line parameters passed to the program.</param>
183        private static void CommandQueryMethods(Dictionary<string, string> arguments)
184        {
185            throw new NotImplementedException();
186        }
187
188        /// <summary>
189        /// Prints the help text for Eraser (with copyright)
190        /// </summary>
191        private static void CommandHelp()
192        {
193            Console.WriteLine(@"Eraser {0}
194(c) 2008 The Eraser Project
195Eraser is Open-Source Software: see http://eraser.heidi.ie/ for details.
196",  Assembly.GetExecutingAssembly().GetName().Version);
197
198            Console.Out.Flush();
199            CommandUsage();
200        }
201
202        /// <summary>
203        /// Prints the command line help for Eraser.
204        /// </summary>
205        private static void CommandUsage()
206        {
207            Console.WriteLine(@"usage: Eraser <action> <arguments>
208where action is
209    addtask                 Adds tasks to the current task list.
210    querymethods            Lists all registered Erasure methods.
211
212global parameters:
213    --quiet, -q             Do not create a Console window to display progress.
214
215parameters for addtask:
216    eraser addtask --method <methodGUID> (--recycled | --unused=<volume> | " +
217@"--dir=<directory> | [file1 [file2 [...]]])
218
219    --method, -m            The Erasure method to use.
220    --recycled, -r          Erases files and folders in the recycle bin
221    --unused, -u            Erases unused space in the volume.
222    --dir, --directory, -d  Erases files and folders in the directory
223        optional arguments: --dir=<directory>[,e=excludeMask][,i=includeMask]
224            excludeMask     A wildcard expression for files and folders to exclude.
225            includeMask     A wildcard expression for files and folders to include.
226                            The include mask is applied before the exclude mask.
227    file1 ... fileN         The list of files to erase.
228
229parameters for querymethods:
230    eraser querymethods");
231            Console.Out.Flush();
232        }
233
234        /// <summary>
235        /// Runs Eraser as a GUI application.
236        /// </summary>
237        /// <param name="isRestart">True if the program was passed the --restart
238        /// switch.</param>
239        private static void GUIMain(bool isRestart)
240        {
241            Application.EnableVisualStyles();
242            Application.SetCompatibleTextRenderingDefault(false);
243            Application.SafeTopLevelCaptionFormat = S._("Eraser");
244
245            using (ManagerLibrary library = new ManagerLibrary(new Settings()))
246            using (eraserClient = new DirectExecutor())
247            {
248                //Set our UI language
249                EraserSettings settings = new EraserSettings();
250                System.Threading.Thread.CurrentThread.CurrentUICulture =
251                    new CultureInfo(settings.Language);
252
253                //Load the task list
254                if (settings.TaskList != null)
255                    using (MemoryStream stream = new MemoryStream(settings.TaskList))
256                        try
257                        {
258                            eraserClient.LoadTaskList(stream);
259                        }
260                        catch (Exception)
261                        {
262                            settings.TaskList = null;
263                            MessageBox.Show(S._("Could not load task list. All task entries have " +
264                                "been lost."), S._("Eraser"), MessageBoxButtons.OK,
265                                MessageBoxIcon.Error);
266                        }
267
268                //Create the main form
269                MainForm form = new MainForm();
270
271                //Run tasks which are meant to be run on restart
272                if (isRestart)
273                {
274                    eraserClient.QueueRestartTasks();
275                }
276
277                //Run the program
278                eraserClient.Run();
279                Application.Run(form);
280
281                //Save the task list
282                using (MemoryStream stream = new MemoryStream())
283                {
284                    eraserClient.SaveTaskList(stream);
285                    settings.TaskList = stream.ToArray();
286                }
287            }
288        }
289
290        /// <summary>
291        /// The global Executor instance.
292        /// </summary>
293        public static Executor eraserClient;
294
295        /// <summary>
296        /// Handles commands passed to the program
297        /// </summary>
298        /// <param name="arguments">The arguments to the command</param>
299        private delegate void CommandHandler(Dictionary<string, string> arguments);
300    }
301
302    class Settings : Manager.SettingsManager
303    {
304        /// <summary>
305        /// Registry-based storage backing for the Settings class.
306        /// </summary>
307        private class RegistrySettings : Manager.Settings
308        {
309            /// <summary>
310            /// Constructor.
311            /// </summary>
312            /// <param name="key">The registry key to look for the settings in.</param>
313            public RegistrySettings(Guid pluginID, RegistryKey key)
314            {
315                this.key = key;
316            }
317
318            public override object this[string setting]
319            {
320                get
321                {
322                    byte[] currentSetting = (byte[])key.GetValue(setting, null);
323                    if (currentSetting != null && currentSetting.Length != 0)
324                        using (MemoryStream stream = new MemoryStream(currentSetting))
325                            try
326                            {
327                                return new BinaryFormatter().Deserialize(stream);
328                            }
329                            catch (Exception)
330                            {
331                                key.DeleteValue(setting);
332                                MessageBox.Show(S._("Could not load the setting {0} for plugin {1}. " +
333                                    "The setting has been lost.", key, pluginID.ToString()),
334                                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error);
335                            }
336
337                    return null;
338                }
339                set
340                {
341                    if (value == null)
342                    {
343                        key.DeleteValue(setting);
344                    }
345                    else
346                    {
347                        using (MemoryStream stream = new MemoryStream())
348                        {
349                            new BinaryFormatter().Serialize(stream, value);
350                            key.SetValue(setting, stream.ToArray(), RegistryValueKind.Binary);
351                        }
352                    }
353                }
354            }
355
356            /// <summary>
357            /// The GUID of the plugin whose settings this object is storing.
358            /// </summary>
359            private Guid pluginID;
360
361            /// <summary>
362            /// The registry key where the data is stored.
363            /// </summary>
364            private RegistryKey key;
365        }
366
367        public override void Save()
368        {
369        }
370
371        protected override Manager.Settings GetSettings(Guid guid)
372        {
373            //Open the registry key containing the settings
374            const string eraserKeyPath = @"SOFTWARE\Eraser\Eraser 6";
375            RegistryKey eraserKey = Registry.CurrentUser.OpenSubKey(eraserKeyPath, true);
376            if (eraserKey == null)
377                eraserKey = Registry.CurrentUser.CreateSubKey(eraserKeyPath);
378
379            RegistryKey pluginsKey = eraserKey.OpenSubKey(guid.ToString(), true);
380            if (pluginsKey == null)
381                pluginsKey = eraserKey.CreateSubKey(guid.ToString());
382
383            //Return the Settings object.
384            return new RegistrySettings(guid, pluginsKey);
385        }
386    }
387
388    internal class EraserSettings
389    {
390        public EraserSettings()
391        {
392            settings = Manager.ManagerLibrary.Instance.SettingsManager.ModuleSettings;
393        }
394
395        /// <summary>
396        /// Gets or sets the task list, serialised in binary form by the Manager assembly.
397        /// </summary>
398        public byte[] TaskList
399        {
400            get
401            {
402                return (byte[])settings["TaskList"];
403            }
404            set
405            {
406                settings["TaskList"] = value;
407            }
408        }
409
410        /// <summary>
411        /// Gets or sets the LCID of the language which the UI should be displayed in.
412        /// </summary>
413        public string Language
414        {
415            get
416            {
417                return settings["Language"] == null ? 
418                    GetCurrentCulture().Name :
419                    (string)settings["Language"];
420            }
421            set
422            {
423                settings["Language"] = value;
424            }
425        }
426
427        /// <summary>
428        /// Gets or sets a value on whether the main frame should be minimised to the
429        /// system notification area.
430        /// </summary>
431        public bool HideWhenMinimised
432        {
433            get
434            {
435                return settings["HideWhenMinimised"] == null ?
436                    true : (bool)settings["HideWhenMinimised"];
437            }
438            set
439            {
440                settings["HideWhenMinimised"] = value;
441            }
442        }
443
444        /// <summary>
445        /// Gets the current UI culture, correct to the top-level culture (i.e., English
446        /// instead of English (United Kingdom))
447        /// </summary>
448        /// <returns>The CultureInfo of the current UI culture, correct to the top level.</returns>
449        private static CultureInfo GetCurrentCulture()
450        {
451            CultureInfo culture = CultureInfo.CurrentUICulture;
452            while (culture.Parent != CultureInfo.InvariantCulture)
453                culture = culture.Parent;
454
455            return culture;
456        }
457
458        private Manager.Settings settings;
459    }
460}
Note: See TracBrowser for help on using the repository browser.