private int UnzipFilesToBin(string name, string zipFileLocation, string cultureCode, ref List <InternalNotification> queuedNotifications)
        {
            // unzip
            string languageFolder = GetLanguageFolder(cultureCode);

            Unzipper.UnZipFiles(zipFileLocation, languageFolder, false);

            // clean up
            Utility.WriteDebugInfo(String.Format("Deleteing '{0}' zip file at {1}", name, zipFileLocation));
            if (File.Exists(zipFileLocation))
            {
                File.Delete(zipFileLocation);
            }

            // notify
            string text = String.Format(Properties.Resources.LanguageInstaller_LanguageInstalledText, name);

            if (ApplicationMain.HasProgramLaunchedYet)
            {
                text += (" " + Properties.Resources.LanguageInstaller_RestartRequiredText);
            }
            InternalNotification n = new InternalNotification(Properties.Resources.LanguageInstaller_LanguageInstalledTitle, Utility.GetResourceString(text), null);

            queuedNotifications.Add(n);

            // done
            Properties.Settings.Default.CultureCode = cultureCode;
            int cultureCodeHash = cultureCode.GetHashCode();

            return(cultureCodeHash);
        }
        public bool LaunchInstaller(string uri, bool appIsAlreadyRunning, ref List <InternalNotification> queuedNotifications, ref int cultureCodeHash)

        {
            bool installed = false;

            this.uri = uri;

            this.appIsAlreadyRunning = appIsAlreadyRunning;

            this.tempFolder = Path.Combine(Utility.UserSettingFolder, TEMP_FOLDER);



            try

            {
                this.wc = new Growl.CoreLibrary.WebClientEx();

                wc.Headers.Add("User-Agent", USER_AGENT);



                byte[] data = wc.DownloadData(this.uri);

                string definition = Encoding.UTF8.GetString(data).Trim();

                SubscriberInfo info = SubscriberInfo.Parse(definition);

                if (info != null)

                {
                    this.InfoLabel.Text = String.Format(Utility.GetResourceString(Properties.Resources.SubscriberInstaller_Prompt), info.Name, info.Author, info.Description);

                    this.YesButton.Visible = true;

                    this.NoButton.Visible = true;

                    this.OKButton.Visible = false;



                    /* NOTE: there is a bug that is caused when Growl is launched via protocol handler (growl:) from Opera.
                     *
                     * when that happens, the call to ShowDialog hangs.
                     *
                     * i could not find any documentation on this or any reason why it would be happening (not on a non-ui thread, windows handle is already created, etc).
                     *
                     * the only fix i could find was to Show/Hide the form before calling ShowDialog. i dont even know why this works, but it does.
                     *
                     * */

                    this.Show();

                    this.Hide();



                    DialogResult result = this.ShowDialog();

                    if (result == DialogResult.Yes)

                    {
                        this.InfoLabel.Text = Utility.GetResourceString(Properties.Resources.SubscriberInstaller_Installing);

                        this.progressBar1.Value = 0;

                        this.progressBar1.Visible = true;

                        this.YesButton.Enabled = false;

                        this.NoButton.Enabled = false;

                        this.Show();

                        this.Refresh();



                        if (Directory.Exists(this.tempFolder))
                        {
                            Directory.Delete(this.tempFolder, true);
                        }

                        Directory.CreateDirectory(this.tempFolder);

                        string zipFileName = Path.Combine(this.tempFolder, String.Format("{0}.zip", System.Guid.NewGuid().ToString()));

                        info.LocalZipFileLocation = zipFileName;



                        wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);

                        wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);



                        StartDownload(info);



                        Utility.WriteDebugInfo(String.Format("Downloading subscriber plugin '{0}' to {1}", info.Name, info.LocalZipFileLocation));



                        System.Threading.WaitHandle[] handles = new System.Threading.WaitHandle[] { are, mre };

                        while (System.Threading.WaitHandle.WaitAny(handles) == 0)

                        {
                            lock (this.progress_lock)

                            {
                                this.progressBar1.Value = this.progress.ProgressPercentage;

                                Application.DoEvents();
                            }
                        }



                        this.progressBar1.Value = 100;

                        Application.DoEvents();



                        Utility.WriteDebugInfo(String.Format("Finished downloading subscriber plugin '{0}' to {1}", info.Name, info.LocalZipFileLocation));



                        if (this.errorMessage == null)

                        {
                            // unzip files to the correct location

                            string folder = Path.Combine(SubscriptionManager.UserPluginDirectory, Growl.CoreLibrary.PathUtility.GetSafeFolderName(info.Name));

                            if (!ApplicationMain.HasProgramLaunchedYet || !Directory.Exists(folder))

                            {
                                Utility.WriteDebugInfo(String.Format("Subscriber '{0}' downloaded - starting unzip.", info.Name));

                                Unzipper.UnZipFiles(info.LocalZipFileLocation, folder, false);



                                string text = String.Format(Properties.Resources.SubscriberInstaller_InstalledText, info.Name);

                                InternalNotification n = new InternalNotification(Properties.Resources.SubscriberInstaller_InstalledTitle, Utility.GetResourceString(text), null);

                                queuedNotifications.Add(n);



                                installed = true;



                                this.Close();
                            }

                            else

                            {
                                // display with the same name aleady exists...

                                ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.SubscriberInstaller_AlreadyInstalled), info.Name), true);
                            }



                            // clean up

                            Utility.WriteDebugInfo(String.Format("Deleteing '{0}' zip file at {1}", info.Name, info.LocalZipFileLocation));

                            if (File.Exists(info.LocalZipFileLocation))
                            {
                                File.Delete(info.LocalZipFileLocation);
                            }
                        }

                        else

                        {
                            Utility.WriteDebugInfo(String.Format("Error downloading subscriber plugin '{0}'.", info.Name));

                            ShowMessage(errorMessage, true);
                        }
                    }
                }

                else

                {
                    // definition file was malformed

                    ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.SubscriberInstaller_BadDefinitionFile), this.uri), true);
                }
            }

            catch (Exception ex)

            {
                // error downloading definition file

                Utility.WriteDebugInfo(String.Format("Error downloading subscriber plugin. {0} - {1}", ex.Message, ex.StackTrace));

                ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.SubscriberInstaller_NonexistentDefinitionFile), this.uri), true);
            }

            return(installed);
        }