/// <summary>
        /// Updates the manifest from the server location
        /// </summary>
        /// <param name="PstrManifestPath"></param>
        /// <param name="PstrInstallPath"></param>
        /// <returns>bool</returns>
        private static bool Update(string PstrManifestPath, string PstrInstallPath)
        {
            try
            {
                string LstrLocalManifestFullPath = "";

                if (PstrManifestPath.ToLower().StartsWith("http"))
                {
                    LstrLocalManifestFullPath = DownloadFileFromWeb(PstrManifestPath, PstrInstallPath);
                }
                else
                {
                    LstrLocalManifestFullPath = DownloadFile(PstrManifestPath, PstrInstallPath);
                }

                Console.WriteLine("Update process completed.");
                return(true);
            }
            catch (Exception PobjEx)
            {
                PobjEx.HandleException(true, "Either the manifest server location is invalid, " +
                                       "cannot be accessed, or the local file is in use or " +
                                       "the path is no longer valid.");
                return(false);
            }
        }
        /// <summary>
        /// Uninstalls the web add-in
        /// </summary>
        /// <param name="PstrLocalManifestFullName"></param>
        /// <returns>bool</returns>
        private static bool Uninstall(string PstrLocalManifestFullName, bool PbolDoNotDelete = false)
        {
            try
            {
                string LstrId = GetManifestId(PstrLocalManifestFullName);

                if (LstrId == null)
                {
                    throw new Exception("Invalid manifest file detected.");
                }

                if (!PbolDoNotDelete)
                {
                    FileInfo LobjFile = new FileInfo(PstrLocalManifestFullName); // grab the local
                    Console.WriteLine("Deleting the manifest file: " + PstrLocalManifestFullName);
                    LobjFile.Delete();
                }

                Console.WriteLine("Deleting Registry entries...");
                RegistryKey LobjKey = Registry.CurrentUser.OpenSubKey(REG_KEY, true);
                LobjKey.DeleteValue(LstrId);
                LobjKey.DeleteSubKey(LstrId);
                Console.WriteLine("Registry keys deleted.");
                Console.WriteLine("Uninstall process completed.");
                return(true);
            }
            catch (Exception PobjEx)
            {
                PobjEx.HandleException(true, "Either the manifest path is invalid, cannot be accessed, or " +
                                       "the manifest is not a valid XML file, is not a Web Add-in " +
                                       "manifest, or the local path does not exist, or the local " +
                                       "file is still in use.");
                return(false);
            }
        }
        /// <summary>
        /// Installs the Web Add-in
        /// </summary>
        /// <param name="PstrManifestPath"></param>
        /// <param name="PstrInstallPath"></param>
        private static bool Install(string PstrManifestPath, string PstrInstallPath)
        {
            try
            {
                // copy the manifest down to the install path
                Console.WriteLine("Accessing the manifest file: " + PstrManifestPath);

                string LstrLocalManifestFullPath = "";

                if (PstrManifestPath.ToLower().StartsWith("http"))
                {
                    LstrLocalManifestFullPath = DownloadFileFromWeb(PstrManifestPath, PstrInstallPath);
                }
                else
                {
                    LstrLocalManifestFullPath = DownloadFile(PstrManifestPath, PstrInstallPath);
                }

                Console.WriteLine("Copy complete. Analyzing file...");
                string LstrId = GetManifestId(LstrLocalManifestFullPath);

                if (LstrId == null)
                {
                    throw new Exception("Invalid manifest file detected.");
                }
                Console.WriteLine("Writing Registry entries...");
                RegistryKey LobjKey = Registry.CurrentUser.OpenSubKey(REG_KEY, true);
                if (LobjKey == null)
                {
                    LobjKey = Registry.CurrentUser.CreateSubKey(REG_KEY, true);
                }
                if (LobjKey == null)
                {
                    throw new Exception("Unable to create or write to the registry path: HKCU\\" + REG_KEY);
                }
                LobjKey.SetValue(LstrId, LstrLocalManifestFullPath, RegistryValueKind.String);
                LobjKey = LobjKey.CreateSubKey(LstrId);
                LobjKey.SetValue(VALUE_UseDirectDebugger, 1, RegistryValueKind.DWord);
                LobjKey.SetValue(VALUE_UseLiveReload, 0, RegistryValueKind.DWord);
                LobjKey.SetValue(VALUE_UseWebDebugger, 0, RegistryValueKind.DWord);
                Console.WriteLine("Registry keys completed.");
                Console.WriteLine("Install process completed.");
                return(true);
            }
            catch (Exception PobjEx)
            {
                PobjEx.HandleException(true, "Either the manifest path is invalid, cannot be accessed, or " +
                                       "the manifest is not a valid XML file, is not a Web Add-in " +
                                       "manifest, or the local path does not exist, or the local " +
                                       "file is still in use.");
                return(false);
            }
        }
 /// <summary>
 /// Confirms the path specified
 /// </summary>
 /// <param name="PstrPath"></param>
 /// <param name="PbolIsFile"></param>
 /// <returns></returns>
 private bool ConfirmPath(string PstrPath, bool PbolIsFile = false)
 {
     try
     {
         if (PbolIsFile)
         {
             return(new FileInfo(PstrPath).Exists);
         }
         else
         {
             return(new DirectoryInfo(PstrPath).Exists);
         }
     }
     catch (Exception PobjEx)
     {
         PobjEx.HandleException(true);
         return(false);
     }
 }
 /// <summary>
 /// Sideloads the add-in for testing from the location of the manifest
 /// Does not download and install, just uses the manifest in-place
 /// </summary>
 /// <param name="PstrManifestPath"></param>
 /// <returns></returns>
 private static bool Test(string PstrManifestPath)
 {
     try
     {
         string LstrId = GetManifestId(PstrManifestPath);
         if (LstrId == null)
         {
             throw new Exception("Invalid manifest file detected.");
         }
         Console.WriteLine("Writing Registry entries...");
         RegistryKey LobjKey = Registry.CurrentUser.OpenSubKey(REG_KEY, true);
         if (LobjKey == null)
         {
             LobjKey = Registry.CurrentUser.CreateSubKey(REG_KEY, true);
         }
         if (LobjKey == null)
         {
             throw new Exception("Unable to create or write to the registry path: HKCU\\" + REG_KEY);
         }
         LobjKey.SetValue(LstrId, PstrManifestPath, RegistryValueKind.String);
         LobjKey = LobjKey.CreateSubKey(LstrId);
         LobjKey.SetValue(VALUE_UseDirectDebugger, 1, RegistryValueKind.DWord);
         LobjKey.SetValue(VALUE_UseLiveReload, 0, RegistryValueKind.DWord);
         LobjKey.SetValue(VALUE_UseWebDebugger, 0, RegistryValueKind.DWord);
         Console.WriteLine("Registry keys completed.");
         Console.WriteLine("Test sideload process completed.");
         return(true);
     }
     catch (Exception PobjEx)
     {
         PobjEx.HandleException(true, "Either the manifest path is invalid, cannot be accessed, or " +
                                "the manifest is not a valid XML file, is not a Web Add-in " +
                                "manifest, or the local path does not exist, or the local " +
                                "file is still in use.");
         return(false);
     }
 }
        /// <summary>
        /// Opens the manifest file, locates the ID and returns it
        /// This is needed for each operation - install / uninstall
        /// </summary>
        /// <param name="PstrFilename"></param>
        /// <returns>string</returns>
        private static string GetManifestId(string LocalManifestPath)
        {
            try
            {
                XmlDocument LobjDoc = new XmlDocument();
                LobjDoc.Load(LocalManifestPath);

                XmlNamespaceManager LobjMgr = new XmlNamespaceManager(LobjDoc.NameTable);
                LobjMgr.AddNamespace(XML_NS, XML_NS_PATH);
                XmlNode LobjIdNode = LobjDoc.DocumentElement.SelectSingleNode(PATH_IdTag, LobjMgr);
                if (LobjIdNode == null)
                {
                    throw new Exception("Id not found in manifest file at " + PATH_IdTag);
                }
                Console.WriteLine("Manifest ID found: " + LobjIdNode.InnerText);
                return(LobjIdNode.InnerText);
            }
            catch (Exception PobjEx)
            {
                PobjEx.HandleException(true, "The file provided is not a valid XML file, " +
                                       "or it is not a properly formatted Web Add-in manifest.");
                return(null);
            }
        }
        /// <summary>
        /// ctor - INIT class object with values
        /// </summary>
        /// <param name="PobjArgs"></param>
        public ProcessedArguments(string[] PobjArgs)
        {
            try
            {
                int LintArgCount = 0;
                foreach (string LstrRawArg in PobjArgs)
                {
                    // strip off all leading dashes or slashes
                    string LstrArg = LstrRawArg.StartsWith("-") || LstrRawArg.StartsWith("/") ?
                                     LstrRawArg.Substring(1) :
                                     LstrRawArg;
                    // now process
                    if (LstrArg.ToLower() == "?" ||
                        LstrArg.ToLower() == "help")
                    {
                        Help = true;
                        return;
                    }
                    if (LstrArg.ToLower() == "test")
                    {
                        Test = true;
                    }
                    if (LstrArg.ToLower() == "cleanup")
                    {
                        Cleanup = true;
                    }
                    if (LstrArg.ToLower() == "install")
                    {
                        Install = true;
                    }
                    if (LstrArg.ToLower() == "update")
                    {
                        Update = true;
                    }
                    if (LstrArg.ToLower() == "uninstall")
                    {
                        Uninstall = true;
                    }
                    if (LstrArg.ToLower() == "manifestpath")
                    {
                        // verify that the path to the manifest is valid and is an XML file

                        var tmp = PobjArgs[LintArgCount + 1].ToLower();

                        if (tmp.StartsWith("http") || ConfirmPath(tmp, true))
                        {
                            if (tmp.EndsWith("xml"))
                            {
                                ManifestPath = tmp;
                            }
                            else
                            {
                                throw new Exception("Manifest path must be an xml file.");
                            }
                        }
                        else
                        {
                            throw new Exception("An invalid ManifestPath was specified.");
                        }
                    }
                    // verify that the path to install is a valid folder location
                    if (LstrArg.ToLower() == "installpath")
                    {
                        if (ConfirmPath(PobjArgs[LintArgCount + 1]))
                        {
                            InstallPath = PobjArgs[LintArgCount + 1];
                        }
                        else
                        {
                            throw new Exception("An invalid InstallPath was specified.");
                        }
                    }

                    if (LstrArg.ToLower() == "installedmanifestfullname")
                    {
                        if (ConfirmPath(PobjArgs[LintArgCount + 1], true))
                        {
                            InstalledManifestFullName = PobjArgs[LintArgCount + 1];
                        }
                        else
                        {
                            throw new Exception("An invalid Installed Manifest was specified.");
                        }
                    }
                    LintArgCount++;
                }

                // validate the install/update/uninstall/test/cleanup switches
                if ((Install == true && Uninstall == true) ||
                    (Install == true && Update == true) ||
                    (Update == true && Uninstall == true) ||
                    (Install == true && Test == true) ||
                    (Uninstall == true && Test == true) ||
                    (Update == true && Test == true) ||
                    (Cleanup == true && Test == true) ||
                    (Cleanup == true && Uninstall == true) ||
                    (Cleanup == true && Update == true) ||
                    (Cleanup == true && Install == true))
                {
                    throw new Exception("Invalid switch combination.");
                }

                if (Uninstall == true)
                {
                    if (string.IsNullOrEmpty(InstalledManifestFullName))
                    {
                        throw new Exception("Installed Manifiest location must be secpified for uninstall.");
                    }
                }
                else if (Install == true || Update == true)  //this is an install or update
                {
                    // validate that paths are specified
                    if (string.IsNullOrEmpty(ManifestPath) || string.IsNullOrEmpty(InstallPath))
                    {
                        throw new Exception("Both a ManifestPath and an InstallPath must be specified.");
                    }
                }
                else if (Test == true || Cleanup == true) // this is for testing/local only
                {
                    if (string.IsNullOrEmpty(ManifestPath))
                    {
                        throw new Exception("ManifestPath must be specified.");
                    }
                    if (!string.IsNullOrEmpty(InstallPath))
                    {
                        throw new Exception("The install path is not required for this option.");
                    }
                }

                // all is good
                Processed = true;
            }
            catch (Exception PobjEx)
            {
                PobjEx.HandleException(true, "The arguments were invalid. Please use -help for guidance.");
            }
        }