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

Revision 759, 25.9 KB checked in by lowjoel, 6 years ago (diff)

-Replace the Eraser program entry points with those that retunr ints for statuses to be returned to the shell extension
-Create a default constructor for the Handle class to allow for the initialisation of NULL handles
-Factor out the string formatting code to the FormatString? function. Allows for reuse later on
-Replace all new[]'s and selete[]'s with std::vector as the buffer to prevent memory leaks
-Implemented error checking when the Eraser binary is called from the shell extension. If the process returns an error status, we must be sure to read the output pipe for the error and display it to the user.

  • 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;
33using System.Diagnostics;
34
35namespace Eraser
36{
37    static class Program
38    {
39        /// <summary>
40        /// The main entry point for the application.
41        /// </summary>
42        [STAThread]
43        static int Main(string[] commandLine)
44        {
45            //Trivial case: no command parameters
46            if (commandLine.Length == 0)
47                GUIMain(false);
48
49            //Determine if the sole parameter is --restart; if it is, start the GUI
50            //passing isRestart as true. Otherwise, we're a console application.
51            else if (commandLine.Length == 1)
52            {
53                if (commandLine[0] == "/restart" || commandLine[0] == "--restart")
54                {
55                    GUIMain(true);
56                }
57                else
58                {
59                    return CommandMain(commandLine);
60                }
61            }
62
63            //The other trivial case: definitely a console application.
64            else
65                return CommandMain(commandLine);
66
67            //No error.
68            return 0;
69        }
70
71        /// <summary>
72        /// Runs Eraser as a command-line application.
73        /// </summary>
74        /// <param name="commandLine">The command line parameters passed to Eraser.</param>
75        private static int CommandMain(string[] commandLine)
76        {
77            //True if the user specified a quiet command.
78            bool isQuiet = false;
79
80            try
81            {
82                CommandLineProgram program = new CommandLineProgram(commandLine);
83                isQuiet = program.Arguments.Quiet;
84
85                using (ManagerLibrary library = new ManagerLibrary(new Settings()))
86                    program.Run();
87
88                return 1;
89            }
90            catch (Exception e)
91            {
92                Console.WriteLine(e.Message);
93            }
94            finally
95            {
96                //Flush the buffered output to the console
97                Console.Out.Flush();
98
99                //Don't ask for a key to press if the user specified Quiet
100                if (!isQuiet)
101                {
102                    Console.Write("\nPress enter to continue . . . ");
103                    Console.Out.Flush();
104                    Console.ReadLine();
105                }
106
107                KernelAPI.FreeConsole();
108            }
109        }
110
111        /// <summary>
112        /// Runs Eraser as a GUI application.
113        /// </summary>
114        /// <param name="isRestart">True if the program was passed the --restart
115        /// switch.</param>
116        private static void GUIMain(bool isRestart)
117        {
118            Application.EnableVisualStyles();
119            Application.SetCompatibleTextRenderingDefault(false);
120            Application.SafeTopLevelCaptionFormat = S._("Eraser");
121
122            using (ManagerLibrary library = new ManagerLibrary(new Settings()))
123            using (eraserClient = new RemoteExecutorServer())
124            {
125                //Set our UI language
126                EraserSettings settings = new EraserSettings();
127                System.Threading.Thread.CurrentThread.CurrentUICulture =
128                    new CultureInfo(settings.Language);
129
130                //Load the task list
131                if (settings.TaskList != null)
132                    using (MemoryStream stream = new MemoryStream(settings.TaskList))
133                        try
134                        {
135                            eraserClient.LoadTaskList(stream);
136                        }
137                        catch (Exception)
138                        {
139                            settings.TaskList = null;
140                            MessageBox.Show(S._("Could not load task list. All task entries have " +
141                                "been lost."), S._("Eraser"), MessageBoxButtons.OK,
142                                MessageBoxIcon.Error);
143                        }
144
145                //Create the main form
146                MainForm form = new MainForm();
147
148                //Run tasks which are meant to be run on restart
149                if (isRestart)
150                {
151                    eraserClient.QueueRestartTasks();
152                }
153
154                //Run the program
155                eraserClient.Run();
156                Application.Run(form);
157
158                //Save the task list
159                using (MemoryStream stream = new MemoryStream())
160                {
161                    eraserClient.SaveTaskList(stream);
162                    settings.TaskList = stream.ToArray();
163                }
164            }
165        }
166
167        /// <summary>
168        /// The global Executor instance.
169        /// </summary>
170        public static Executor eraserClient;
171
172        /// <summary>
173        /// Handles commands passed to the program
174        /// </summary>
175        /// <param name="arguments">The arguments to the command</param>
176        private delegate void CommandHandler(Dictionary<string, string> arguments);
177    }
178
179    class CommandLineProgram
180    {
181        #region Command Line parsing classes
182        /// <summary>
183        /// Manages a command line.
184        /// </summary>
185        public class CommandLine
186        {
187            /// <summary>
188            /// Constructor.
189            /// </summary>
190            /// <param name="cmdParams">The raw arguments passed to the program.</param>
191            public CommandLine(string[] cmdParams)
192            {
193                //Get the action.
194                if (cmdParams.Length < 1)
195                    throw new ArgumentException("An action must be specified.");
196                Action = cmdParams[0];
197
198                //Iterate over each argument, resolving them ourselves and letting
199                //subclasses resolve them if we don't know how to.
200                for (int i = 1; i != cmdParams.Length; ++i)
201                {
202                    if (IsParam(cmdParams[i], "quiet", "q"))
203                        Quiet = true;
204                    else if (!ResolveParameter(cmdParams[i]))
205                        throw new ArgumentException("Unknown argument: " + cmdParams[i]);
206                }
207            }
208
209            /// <summary>
210            /// Called when a parameter is not used by the current CommandLine object
211            /// for subclasses to handle their parameters.
212            /// </summary>
213            /// <param name="param">The parameter to resolve.</param>
214            /// <returns>Return true if the parameter was resolved and accepted.</returns>
215            virtual protected bool ResolveParameter(string param)
216            {
217                return false;
218            }
219
220            /// <summary>
221            /// Checks if the given <paramref name="parameter"/> refers to the
222            /// <paramref name="expectedParameter"/>, regardless of whether it is specified
223            /// with -, --, or /
224            /// </summary>
225            /// <param name="parameter">The parameter on the command line.</param>
226            /// <param name="expectedParameter">The parameter the program is looking for, without
227            /// the - or / prefix.</param>
228            /// <param name="shortParameter">The short parameter when used with a single hyphen,
229            /// without the - or / prefix.</param>
230            /// <returns>True if the parameter references the given expected parameter.</returns>
231            protected static bool IsParam(string parameter, string expectedParameter,
232                string shortParameter)
233            {
234                //Trivial case
235                if (parameter.Length < 1)
236                    return false;
237
238                //Extract the bits before the equal sign.
239                {
240                    int equalPos = parameter.IndexOf('=');
241                    if (equalPos != -1)
242                        parameter = parameter.Substring(0, equalPos);
243                }
244
245                //Get the first letter.
246                switch (parameter[0])
247                {
248                    case '-':
249                        //Can be a - or a --. Check for the second parameter
250                        if (parameter.Length < 2)
251                            //Nothing specified at the end... it's invalid.
252                            return false;
253
254                        if (parameter[1] == '-')
255                            return parameter.Substring(2) == expectedParameter;
256                        else if (shortParameter == null || shortParameter == string.Empty)
257                            return parameter.Substring(1) == expectedParameter;
258                        else
259                            return parameter.Substring(1) == shortParameter;
260                       
261                    case '/':
262                        //The / can be used with both long and short parameters.
263                        parameter = parameter.Substring(1);
264                        return parameter == expectedParameter || (
265                            shortParameter != null && shortParameter != string.Empty &&
266                            parameter == shortParameter
267                        );
268
269                    default:
270                        return false;
271                }
272            }
273
274            /// <summary>
275            /// Gets the list of subparameters of the parameter. Subparameters are text
276            /// after the first =, separated by commas.
277            /// </summary>
278            /// <param name="param">The subparameter text to parse.</param>
279            /// <returns>The list of subparameters in the parameter.</returns>
280            protected static List<KeyValuePair<string, string>> GetSubParameters(string param)
281            {
282                List<KeyValuePair<string, string>> result =
283                    new List<KeyValuePair<string, string>>();
284                int lastPos = 0;
285                int commaPos = (param += ',').IndexOf(',');
286
287                while (commaPos != -1)
288                {
289                    //Extract the current subparameter, and dissect the subparameter at
290                    //the first =.
291                    string subParam = param.Substring(lastPos, commaPos - lastPos);
292                    int equalPos = subParam.IndexOf('=');
293                    if (equalPos == -1)
294                        result.Add(new KeyValuePair<string, string>(subParam, null));
295                    else
296                        result.Add(new KeyValuePair<string, string>(subParam.Substring(0, equalPos),
297                            subParam.Substring(equalPos + 1)));
298
299                    //Find the next ,
300                    lastPos = ++commaPos;
301                    commaPos = param.IndexOf(',', commaPos);
302                }
303
304                return result;
305            }
306
307            /// <summary>
308            /// The action that the command line specifies.
309            /// </summary>
310            public string Action
311            {
312                get
313                {
314                    return action;
315                }
316                private set
317                {
318                    action = value;
319                }
320            }
321
322            /// <summary>
323            /// True if no console window should be created.
324            /// </summary>
325            public bool Quiet
326            {
327                get
328                {
329                    return quiet;
330                }
331                private set
332                {
333                    quiet = value;
334                }
335            }
336
337            private string action;
338            private bool quiet;
339        }
340
341        /// <summary>
342        /// Manages a command line for adding tasks to the global DirectExecutor
343        /// </summary>
344        class AddTaskCommandLine : CommandLine
345        {
346            /// <summary>
347            /// Constructor.
348            /// </summary>
349            /// <param name="cmdParams">The raw command line arguments passed to the program.</param>
350            public AddTaskCommandLine(string[] cmdParams)
351                : base(cmdParams)
352            {
353            }
354
355            protected override bool ResolveParameter(string param)
356            {
357                int equalPos = param.IndexOf('=');
358                if (IsParam(param, "method", "m"))
359                {
360                    if (equalPos == -1)
361                        throw new ArgumentException("--method must be specified with an Erasure " +
362                            "method GUID.");
363
364                    List<KeyValuePair<string, string>> subParams =
365                        GetSubParameters(param.Substring(equalPos + 1));
366                    ErasureMethod = new Guid(subParams[0].Key);
367                }
368                else if (IsParam(param, "schedule", "s"))
369                {
370                    if (equalPos == -1)
371                        throw new ArgumentException("--schedule must be specified with a Schedule " +
372                            "type.");
373
374                    List<KeyValuePair<string, string>> subParams =
375                        GetSubParameters(param.Substring(equalPos + 1));
376                    switch (subParams[0].Key)
377                    {
378                        case "now":
379                            Schedule = Schedule.RunNow;
380                            break;
381                        case "restart":
382                            schedule = Schedule.RunOnRestart;
383                            break;
384                        default:
385                            throw new ArgumentException("Unknown schedule type: " + subParams[0].Key);
386                    }
387                }
388                else if (IsParam(param, "recycled", "r"))
389                {
390                    targets.Add(new Task.RecycleBin());
391                }
392                else if (IsParam(param, "unused", "u"))
393                {
394                    if (equalPos == -1)
395                        throw new ArgumentException("--unused must be specified with the Volume " +
396                            "to erase.");
397
398                    //Create the UnusedSpace target for inclusion into the task.
399                    Task.UnusedSpace target = new Task.UnusedSpace();
400
401                    //Determine if cluster tips should be erased.
402                    target.EraseClusterTips = false;
403                    List<KeyValuePair<string, string>> subParams =
404                        GetSubParameters(param.Substring(equalPos + 1));
405                    foreach (KeyValuePair<string, string> kvp in subParams)
406                        if (kvp.Value == null && target.Drive == null)
407                            target.Drive = Path.GetFullPath(kvp.Key);
408                        else if (kvp.Key == "clusterTips")
409                            target.EraseClusterTips = true;
410                        else
411                            throw new ArgumentException("Unknown subparameter: " + kvp.Key);
412                    targets.Add(target);
413                }
414                else if (IsParam(param, "dir", "d") || IsParam(param, "directory", null))
415                {
416                    if (equalPos == -1)
417                        throw new ArgumentException("--directory must be specified with the " +
418                            "directory to erase.");
419
420                    //Create the base target
421                    Task.Folder target = new Task.Folder();
422
423                    //Parse the subparameters.
424                    List<KeyValuePair<string, string>> subParams =
425                        GetSubParameters(param.Substring(equalPos + 1));
426                    foreach (KeyValuePair<string, string> kvp in subParams)
427                        if (kvp.Value == null && target.Path == null)
428                            target.Path = Path.GetFullPath(kvp.Key);
429                        else if (kvp.Key == "excludeMask")
430                        {
431                            if (kvp.Value == null)
432                                throw new ArgumentException("The exclude mask must be specified " +
433                                    "if the excludeMask subparameter is specified");
434                            target.ExcludeMask = kvp.Value;
435                        }
436                        else if (kvp.Key == "includeMask")
437                        {
438                            if (kvp.Value == null)
439                                throw new ArgumentException("The include mask must be specified " +
440                                    "if the includeMask subparameter is specified");
441                            target.IncludeMask = kvp.Value;
442                        }
443                        else if (kvp.Key == "delete")
444                            target.DeleteIfEmpty = true;
445                        else
446                            throw new ArgumentException("Unknown subparameter: " + kvp.Key);
447
448                    //Add the target to the list of targets
449                    targets.Add(target);
450                }
451                else
452                {
453                    //It's just a file!
454                    Task.File target = new Task.File();
455                    target.Path = Path.GetFullPath(param);
456                    targets.Add(target);
457                }
458
459                return true;
460            }
461
462            /// <summary>
463            /// The erasure method which the user specified on the command line.
464            /// </summary>
465            public Guid ErasureMethod
466            {
467                get
468                {
469                    return erasureMethod;
470                }
471                private set
472                {
473                    erasureMethod = value;
474                }
475            }
476
477            /// <summary>
478            /// The schedule for the current set of targets.
479            /// </summary>
480            public Schedule Schedule
481            {
482                get
483                {
484                    return schedule;
485                }
486                set
487                {
488                    schedule = value;
489                }
490            }
491
492            /// <summary>
493            /// The list of targets which was specified on the command line.
494            /// </summary>
495            public List<Task.ErasureTarget> Targets
496            {
497                get
498                {
499                    return new List<Task.ErasureTarget>(targets.ToArray());
500                }
501                set
502                {
503                    targets = value;
504                }
505            }
506
507            private Guid erasureMethod;
508            private Schedule schedule = Schedule.RunNow;
509            private List<Task.ErasureTarget> targets = new List<Task.ErasureTarget>();
510        }
511        #endregion
512
513        /// <summary>
514        /// Constructor.
515        /// </summary>
516        /// <param name="cmdParams">The raw command line arguments passed to the program.</param>
517        public CommandLineProgram(string[] cmdParams)
518        {
519            try
520            {
521                //Parse the command line arguments.
522                if (cmdParams.Length < 1)
523                    throw new ArgumentException("An action must be specified.");
524
525                switch (cmdParams[0])
526                {
527                    case "addtask":
528                        Arguments = new AddTaskCommandLine(cmdParams);
529                        break;
530                    case "querymethods":
531                    case "help":
532                    default:
533                        Arguments = new CommandLine(cmdParams);
534                        break;
535                }
536
537                //If the user did not specify the quiet command line, then create the console.
538                if (!Arguments.Quiet)
539                    CreateConsole();
540
541                //Map actions to their handlers
542                actionHandlers.Add("addtask", AddTask);
543                actionHandlers.Add("querymethods", QueryMethods);
544                actionHandlers.Add("help", Help);
545            }
546            finally
547            {
548                if (Arguments == null || !Arguments.Quiet)
549                    CreateConsole();
550            }
551        }
552
553        /// <summary>
554        /// Runs the program, analogous to System.Windows.Forms.Application.Run.
555        /// </summary>
556        public void Run()
557        {
558            //Call the function handling the current command line.
559            actionHandlers[Arguments.Action]();
560        }
561
562        /// <summary>
563        /// Creates a console for our application, setting the input/output streams to the
564        /// defaults.
565        /// </summary>
566        private void CreateConsole()
567        {
568            if (KernelAPI.AllocConsole())
569            {
570                Console.SetOut(new StreamWriter(Console.OpenStandardOutput()));
571                Console.SetIn(new StreamReader(Console.OpenStandardInput()));
572            }
573        }
574
575        /// <summary>
576        /// Prints the command line help for Eraser.
577        /// </summary>
578        private static void CommandUsage()
579        {
580            Console.WriteLine(@"usage: Eraser <action> <arguments>
581where action is
582    help                    Show this help message.
583    addtask                 Adds tasks to the current task list.
584    querymethods            Lists all registered Erasure methods.
585
586global parameters:
587    --quiet, -q             Do not create a Console window to display progress.
588
589parameters for help:
590    eraser help
591
592    no parameters to set.
593
594parameters for addtask:
595    eraser addtask [--method=<methodGUID>] [--schedule=(now|restart)] (--recycled " +
596@"| --unused=<volume> | --dir=<directory> | [file1 [file2 [...]]])
597
598    --method, -m            The Erasure method to use.
599    --schedule, -s          The schedule the task will follow. The value must
600                            be one of:
601            now             The task will be queued for immediate execution.
602            restart         The task will be queued for execution when the
603                            computer is next restarted.
604    --recycled, -r          Erases files and folders in the recycle bin
605    --unused, -u            Erases unused space in the volume.
606        optional arguments: --unused=<drive>[,clusterTips]
607            clusterTips     If specified, the drive's files will have their
608                            cluster tips erased.
609    --dir, --directory, -d  Erases files and folders in the directory
610        optional arguments: --dir=<directory>[,e=excludeMask][,i=includeMask][,delete]
611            excludeMask     A wildcard expression for files and folders to
612                            exclude.
613            includeMask     A wildcard expression for files and folders to
614                            include.
615                            The include mask is applied before the exclude
616                            mask.
617            delete          Deletes the folder at the end of the erasure if
618                            specified.
619    file1 ... fileN         The list of files to erase.
620
621parameters for querymethods:
622    eraser querymethods
623
624    no parameters to set.
625
626All arguments are case sensitive.");
627            Console.Out.Flush();
628        }
629
630        #region Action Handlers
631        /// <summary>
632        /// The command line arguments passed to the program.
633        /// </summary>
634        public CommandLine Arguments
635        {
636            get
637            {
638                return arguments;
639            }
640            private set
641            {
642                arguments = value;
643            }
644        }
645
646        /// <summary>
647        /// Prints the help text for Eraser (with copyright)
648        /// </summary>
649        private void Help()
650        {
651            Console.WriteLine(@"Eraser {0}
652(c) 2008 The Eraser Project
653Eraser is Open-Source Software: see http://eraser.heidi.ie/ for details.
654", Assembly.GetExecutingAssembly().GetName().Version);
655
656            Console.Out.Flush();
657            CommandUsage();
658        }
659
660        /// <summary>
661        /// Lists all registered erasure methods.
662        /// </summary>
663        /// <param name="commandLine">The command line parameters passed to the program.</param>
664        private void QueryMethods()
665        {
666            //Output the header
667            const string methodFormat = "{0,-2} {1,-39} {2}";
668            Console.WriteLine(methodFormat, "", "Method", "GUID");
669            Console.WriteLine(new string('-', 79));
670
671            //Refresh the list of erasure methods
672            Dictionary<Guid, ErasureMethod> methods = ErasureMethodManager.GetAll();
673            foreach (ErasureMethod method in methods.Values)
674            {
675                Console.WriteLine(methodFormat, (method is UnusedSpaceErasureMethod) ?
676                    "U" : "", method.Name, method.GUID.ToString());
677            }
678        }
679
680        /// <summary>
681        /// Parses the command line for tasks and adds them using the
682        /// <see cref="RemoteExecutor"/> class.
683        /// </summary>
684        /// <param name="commandLine">The command line parameters passed to the program.</param>
685        private void AddTask()
686        {
687            AddTaskCommandLine arguments = (AddTaskCommandLine)Arguments;
688           
689            //Create the task, and set the method to use.
690            Task task = new Task();
691            ErasureMethod method = arguments.ErasureMethod == Guid.Empty ? 
692                ErasureMethodManager.Default :
693                ErasureMethodManager.GetInstance(arguments.ErasureMethod);
694            foreach (Task.ErasureTarget target in arguments.Targets)
695            {
696                target.Method = method;
697                task.Targets.Add(target);
698            }
699
700            //Check the number of tasks in the task.
701            if (task.Targets.Count == 0)
702                throw new ArgumentException("Tasks must contain at least one erasure target.");
703
704            //Set the schedule for the task.
705            task.Schedule = arguments.Schedule;
706
707            //Send the task out.
708            using (Program.eraserClient = new RemoteExecutorClient())
709            {
710                if (!((RemoteExecutorClient)Program.eraserClient).Connect())
711                {
712                    //The client cannot connect to the server. This probably means
713                    //that the server process isn't running. Start an instance.
714                    Process eraserInstance = Process.Start(
715                        Assembly.GetExecutingAssembly().Location);
716                    eraserInstance.WaitForInputIdle();
717
718                    if (!((RemoteExecutorClient)Program.eraserClient).Connect())
719                        throw new Exception("Eraser cannot connect to the running " +
720                            "instance for erasures.");
721                }
722
723                Program.eraserClient.Run();
724                Program.eraserClient.AddTask(ref task);
725            }
726        }
727        #endregion
728
729        /// <see cref="Arguments"/>
730        private CommandLine arguments;
731
732        /// <summary>
733        /// The prototype of an action handler in the class which executes an
734        /// action as specified in the command line.
735        /// </summary>
736        private delegate void ActionHandler();
737
738        /// <summary>
739        /// Matches an action handler to a function in the class.
740        /// </summary>
741        private Dictionary<string, ActionHandler> actionHandlers =
742            new Dictionary<string, ActionHandler>();
743    }
744
745    internal class Settings : Manager.SettingsManager
746    {
747        /// <summary>
748        /// Registry-based storage backing for the Settings class.
749        /// </summary>
750        private class RegistrySettings : Manager.Settings
751        {
752            /// <summary>
753            /// Constructor.
754            /// </summary>
755            /// <param name="key">The registry key to look for the settings in.</param>
756            public RegistrySettings(Guid pluginID, RegistryKey key)
757            {
758                this.key = key;
759            }
760
761            public override object this[string setting]
762            {
763                get
764                {
765                    byte[] currentSetting = (byte[])key.GetValue(setting, null);
766                    if (currentSetting != null && currentSetting.Length != 0)
767                        using (MemoryStream stream = new MemoryStream(currentSetting))
768                            try
769                            {
770                                return new BinaryFormatter().Deserialize(stream);
771                            }
772                            catch (Exception)
773                            {
774                                key.DeleteValue(setting);
775                                MessageBox.Show(S._("Could not load the setting {0} for plugin {1}. " +
776                                    "The setting has been lost.", key, pluginID.ToString()),
777                                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error);
778                            }
779
780                    return null;
781                }
782                set
783                {
784                    if (value == null)
785                    {
786                        key.DeleteValue(setting);
787                    }
788                    else
789                    {
790                        using (MemoryStream stream = new MemoryStream())
791                        {
792                            new BinaryFormatter().Serialize(stream, value);
793                            key.SetValue(setting, stream.ToArray(), RegistryValueKind.Binary);
794                        }
795                    }
796                }
797            }
798
799            /// <summary>
800            /// The GUID of the plugin whose settings this object is storing.
801            /// </summary>
802            private Guid pluginID;
803
804            /// <summary>
805            /// The registry key where the data is stored.
806            /// </summary>
807            private RegistryKey key;
808        }
809
810        public override void Save()
811        {
812        }
813
814        protected override Manager.Settings GetSettings(Guid guid)
815        {
816            //Open the registry key containing the settings
817            const string eraserKeyPath = @"SOFTWARE\Eraser\Eraser 6";
818            RegistryKey eraserKey = Registry.CurrentUser.OpenSubKey(eraserKeyPath, true);
819            if (eraserKey == null)
820                eraserKey = Registry.CurrentUser.CreateSubKey(eraserKeyPath);
821
822            RegistryKey pluginsKey = eraserKey.OpenSubKey(guid.ToString(), true);
823            if (pluginsKey == null)
824                pluginsKey = eraserKey.CreateSubKey(guid.ToString());
825
826            //Return the Settings object.
827            return new RegistrySettings(guid, pluginsKey);
828        }
829    }
830
831    internal class EraserSettings
832    {
833        public EraserSettings()
834        {
835            settings = Manager.ManagerLibrary.Instance.SettingsManager.ModuleSettings;
836        }
837
838        /// <summary>
839        /// Gets or sets the task list, serialised in binary form by the Manager assembly.
840        /// </summary>
841        public byte[] TaskList
842        {
843            get
844            {
845                return (byte[])settings["TaskList"];
846            }
847            set
848            {
849                settings["TaskList"] = value;
850            }
851        }
852
853        /// <summary>
854        /// Gets or sets the LCID of the language which the UI should be displayed in.
855        /// </summary>
856        public string Language
857        {
858            get
859            {
860                return settings["Language"] == null ? 
861                    GetCurrentCulture().Name :
862                    (string)settings["Language"];
863            }
864            set
865            {
866                settings["Language"] = value;
867            }
868        }
869
870        /// <summary>
871        /// Gets or sets whether the Shell Extension should be loaded into Explorer.
872        /// </summary>
873        public bool IntegrateWithShell
874        {
875            get
876            {
877                return settings["IntegrateWithShell"] == null ?
878                    true : (bool)settings["IntegrateWithShell"];
879            }
880            set
881            {
882                settings["IntegrateWithShell"] = value;
883            }
884        }
885
886        /// <summary>
887        /// Gets or sets a value on whether the main frame should be minimised to the
888        /// system notification area.
889        /// </summary>
890        public bool HideWhenMinimised
891        {
892            get
893            {
894                return settings["HideWhenMinimised"] == null ?
895                    true : (bool)settings["HideWhenMinimised"];
896            }
897            set
898            {
899                settings["HideWhenMinimised"] = value;
900            }
901        }
902
903        /// <summary>
904        /// Gets the current UI culture, correct to the top-level culture (i.e., English
905        /// instead of English (United Kingdom))
906        /// </summary>
907        /// <returns>The CultureInfo of the current UI culture, correct to the top level.</returns>
908        private static CultureInfo GetCurrentCulture()
909        {
910            CultureInfo culture = CultureInfo.CurrentUICulture;
911            while (culture.Parent != CultureInfo.InvariantCulture)
912                culture = culture.Parent;
913
914            return culture;
915        }
916
917        private Manager.Settings settings;
918    }
919}
Note: See TracBrowser for help on using the repository browser.