public void Main_Start()
        {
            //clear working directory if exists
            if (Directory.Exists(workdir))
            {
                Directory.Delete(workdir, true);
            }

            //check if saved cemu path is a valid install
            if (!PathFinder.ConfirmValidCemuInstall(Settings.Default.DefaultCemuPath))
            {
                //loop until valid cemu install has been selected
                bool validInstall = false;
                do
                {
                    validInstall = false;

                    if (CemuInstallDialog.ShowDialog() == DialogResult.OK)
                    {
                        if (PathFinder.ConfirmValidCemuInstall(CemuInstallDialog.SelectedPath))
                        {
                            validInstall = true;
                            cemudir      = CemuInstallDialog.SelectedPath;
                            //save valid cemu install folder to user settings
                            Settings.Default.DefaultCemuPath = cemudir;
                            Settings.Default.Save();
                        }
                        else
                        {
                            MessageBox.Show("Cemu.exe was not found in the selected directory. Please select the correct Folder.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    else
                    {
                        //exit if dialog is aborted
                        MessageBox.Show("Folder selection cancelled. Exiting...", "Cancelled selection", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        Environment.Exit(0);
                    }
                } while (!validInstall);
            }
            else
            {
                cemudir = Settings.Default.DefaultCemuPath;
            }

            bool validZip = false;

            do
            {
                validZip = false;

                if (openModZipDialog.ShowDialog() == DialogResult.OK)
                {
                    if (PathFinder.ModFileValid(openModZipDialog.FileName, new string[] { "zip" }))
                    {
                        validZip   = true;
                        modzippath = openModZipDialog.FileName;
                    }
                    else
                    {
                        MessageBox.Show("Error loading file. File either doesn't exist or isn't a zip file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    //exit if Modzip selection is aborted
                    MessageBox.Show("Mod Zip-File selection cancelled. Exiting...", "Cancelled selection", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Environment.Exit(0);
                }
            } while (!validZip);

            //show main Form once all files/paths have been selected and confirmed correct
            this.allowshowdisplay = true;
            this.Visible          = true;

            //extract mod zip file to subdir of the workingdir
            using (ZipFile zip = new ZipFile(modzippath))
            {
                zip.ExtractAll(extracteddir);
            }

            string metadata = File.ReadAllText(Directory.GetFiles(extracteddir, "meta.yml", SearchOption.AllDirectories).First() ?? null);

            if (metadata == string.Empty)
            {
                MessageBox.Show("Mod Zip-File Does not contain meta.yml and is not compatible with this installer. Please ask the Mod Author to add support. \nExiting...", "Mod not compatible.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                Environment.Exit(0);
            }
            DeserializerBuilder deserializerBuilder = new DeserializerBuilder().IgnoreUnmatchedProperties();
            IDeserializer       deserializer        = deserializerBuilder.Build();

            meta = deserializer.Deserialize <Meta>(metadata);

            //generate list of all directories containing "rules.txt"
            ICollection <string> choicedirs = Directory.GetDirectories(extracteddir, "*", SearchOption.AllDirectories).Where(m => File.Exists(Path.Combine(m, "rules.txt"))).ToList();

            RadioButton[] choiceRadioButtons = new RadioButton[meta.Choices.Count];
            int           i = 0;

            foreach (var item in meta.Choices)
            {
                RadioButton newRadioButton = new RadioButton();
                try
                {
                    newRadioButton = new RadioButton()
                    {
                        Name     = item.Key + "RadioButton",
                        Text     = item.Key,
                        AutoSize = true,
                        Tag      = new ChoiceEx()
                        {
                            Choice = item.Value, choicedir = choicedirs.First(m => m.TrimEnd('\\').EndsWith(item.Key))
                        }
                    };
                }
                catch (InvalidOperationException)
                {
                    MessageBox.Show("Choice names in meta.yml do not match subfolders inside the zip. Please notify the Mod Author to resolve this issue. \nExiting...", "Faulty Mod Configuration.", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    Environment.Exit(0);
                }
                newRadioButton.Click += NewRadioButton_Click;
                choiceRadioButtons[i] = newRadioButton;
                i++;
            }
            leftPanel.Controls.AddRange(choiceRadioButtons);
        }
        private void InstallButton_Click(object sender, EventArgs e)
        {
            //get the directory of the selected choice
            string choicedir = (string)((Button)sender).Tag;

            //abort install if no option has been selected
            if (!leftPanel.Controls.OfType <RadioButton>().Any(m => m.Checked))
            {
                MessageBox.Show("Please select an Option on the left before installing.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //read the "path" of the Choice graphicPack rules.txt
            var     parser   = new FileIniDataParser();
            IniData data     = parser.ReadFile(Path.Combine(choicedir, "rules.txt"));
            string  origpath = data["Definition"]["path"];

            string basepath = string.Empty;

            if (File.Exists(Path.Combine(extracteddir, "base", "rules.txt")))
            {
                //read the "path" of the Base graphicPack rules.txt
                data     = parser.ReadFile(Path.Combine(extracteddir, "base", "rules.txt"));
                basepath = data["Definition"]["path"];
            }

            //iterate through all subfolders of the cemu\graphicPacks folder which contain a rules.txt
            foreach (string dir in Directory.GetDirectories(Path.Combine(cemudir, "graphicPacks")).Where(m => File.Exists(Path.Combine(m, "rules.txt"))))
            {
                //read the "path" of the existing graphicPacks rules.txt
                data = parser.ReadFile(Path.Combine(dir, "rules.txt"));
                string pathinfo = data["Definition"]["path"];
                //delete the graphicspack if the path conflicts with the new one (it is the same mod)
                if (pathinfo == origpath && origpath != string.Empty)
                {
                    Directory.Delete(dir, true);
                }
                //in case the rules.txt is in the base dir and not the choice dir check using that rules.txt aswell
                else if (pathinfo == basepath && basepath != string.Empty)
                {
                    Directory.Delete(dir, true);
                }
            }
            //delete the target folder if it already exists (rarely the case here as it mostly gets deleted duering identical rules.txt path setting)
            if (Directory.Exists(Path.Combine(cemudir, "graphicPacks", meta.targetfoldername)))
            {
                Directory.Delete(Path.Combine(cemudir, "graphicPacks", meta.targetfoldername), true);       //using a try catch shouldnt be nessecary here
            }
            if (Directory.Exists(Path.Combine(extracteddir, "base")))
            {
                Directory.Move(Path.Combine(extracteddir, "base"), Path.Combine(cemudir, "graphicPacks", meta.targetfoldername));
            }
            //move the chosen Choice dir to the graphicPacks folder and rename it to the targetfoldername
            PathFinder.MoveDirectory(choicedir, Path.Combine(cemudir, "graphicPacks", meta.targetfoldername));
            if (MessageBox.Show("Installation successful. \nDo you want to run Cemu now?", "Installation successful", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Process process = new Process();
                process.StartInfo.FileName         = Path.Combine(cemudir, "cemu.exe");
                process.StartInfo.WorkingDirectory = cemudir;
                process.Start();
            }
            else if (MessageBox.Show("Do you want to install another mod?", "Installation successful", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                Process.Start("WildModLauncher.exe");
            }
            Environment.Exit(0);
        }