Exemplo n.º 1
0
        private static void HandleAdminInstalls(string[] commandLineArgs)
        {
            NamedPipeClientStream PipeClient = new NamedPipeClientStream(commandLineArgs[0]);

            PipeClient.Connect(1000);
            if (PipeClient.IsConnected)
            {
                try
                {
                    using (StreamWriter Writer = new StreamWriter(PipeClient))
                    {
                        IFormatter Serializer = new BinaryFormatter();

                        while (true)
                        {
                            PrerequisiteBase Prerequisite = (PrerequisiteBase)Serializer.Deserialize(PipeClient);

                            try
                            {
                                Prerequisite.DoInstall();
                                Writer.WriteLine(string.Empty);
                            }
                            catch (Exception Error)
                            {
                                Writer.WriteLine(Error.Message);
                            }
                            Writer.Flush();
                            PipeClient.WaitForPipeDrain();
                        }
                    }
                }
                catch (IOException)
                {
                    //Pipe was closed remotely - nothing left to do. End
                }
                catch
                {
                    //Oops.. Something went wrong. Just exit, let the caller handle the issue. Must be handled anyway, as the user could also cancel UAC
                }
            }
            else
            {
                //Oops.. Something went wrong. Just exit, let the caller handle the issue. Must be handled anyway, as the user could also cancel UAC
            }
        }
Exemplo n.º 2
0
        private void SetUpSystem()
        {
            new Task(() =>
            {
                int PackagesToInstall  = this.prerequisites.Length;
                int PackagesToDownload = this.prerequisites.Count(_ => _.DownloadId != null);
                int PackagesDownloaded = 0;
                int PackagesInstalled  = 0;

                //Set up initial status for download and imnstallation
                bool IsAdminRequired     = this.prerequisites.Any(_ => _.RequiresAdmin);
                bool DownloadsNeeded     = PackagesToDownload > 0;
                bool MustWaitForDownload = PackagesToInstall == PackagesToDownload;
                this.Status = new InstallationStatus(
                    MustWaitForDownload
                                 ? (InstallationStatus.InstallationStatusBase) new InstallationStatus.InstallationWaitingForDownloadStatus()
                                 : new InstallationStatus.InstallingStatus(PackagesToInstall, 0, null),
                    DownloadsNeeded
                                 ? new InstallationStatus.DownloadingStatus(PackagesToDownload, 0, null)
                                 : default(InstallationStatus.DownloadStatusBase));

                //Set up queue for installable packages. All packages that do not need to be downloaded are added right now as installation can directly start
                Queue <PrerequisiteBase> InstallQueue = new Queue <PrerequisiteBase>();
                AutoResetEvent InstallQueueAdded      = new AutoResetEvent(false);
                this.prerequisites.Where(_ => _.DownloadId == null).ForEach(_ => InstallQueue.Enqueue(_));


                //If administrative rights are required,set up client process to delegate those installations to.
                if (IsAdminRequired)
                {
                    this.adminProcessConnector.LaunchProcess();
                }

                //Start download for all packages in parallel
                foreach (PrerequisiteBase Prerequisite in this.prerequisites.Where(_ => _.DownloadId != null))
                {
                    this.downloadFunc(
                        Prerequisite.DownloadId,
                        (id, progress) =>
                    {
                        lock (this.statusLock)
                        {
                            this.prerequisites.First(_ => _.DownloadId == id).DownloadProgress = progress;
                            double OverallProgress = this.prerequisites.Where(_ => _.DownloadId != null).Sum(_ => _.DownloadProgress);
                            lock (this.statusLock)
                            {
                                if (this.Status is InstallationErrorStatus)
                                {
                                    //Ignore if there is already an error reported. Can happen if multiple downloads are pending and one has a failure
                                    return;
                                }
                            }
                            // Update download status
                            this.Status = new InstallationStatus(((InstallationStatus)this.Status).Installation, new InstallationStatus.DownloadingStatus(PackagesToDownload, OverallProgress, null));
                        }
                    },
                        id =>
                    {
                        //TODO: Handle download errors
                        lock (this.statusLock)
                        {
                            if (this.Status is InstallationErrorStatus)
                            {
                                //Ignore if there is already an error reported. Can happen if multiple downloads are pending and one has a failure
                                return;
                            }
                        }
                        lock (InstallQueue)
                        {
                            InstallQueue.Enqueue(this.prerequisites.First(_ => _.DownloadId == id));
                            InstallQueueAdded.Set();
                            PackagesDownloaded++;
                            lock (this.statusLock)
                            {
                                if (PackagesToDownload != PackagesDownloaded)
                                {
                                    // Update download status
                                    this.Status = new InstallationStatus(((InstallationStatus)this.Status).Installation, new InstallationStatus.DownloadingStatus(PackagesToDownload, PackagesDownloaded, null));
                                }
                                else
                                {
                                    // All downloads finished
                                    this.Status = new InstallationStatus(((InstallationStatus)this.Status).Installation, new InstallationStatus.DownloadFinishedStatus());
                                }
                            }
                        }
                    });
                }


                //repeat until all prerequisites are installed
                while (this.prerequisites.Any(_ => _.WasInstalled == false))
                {
                    PrerequisiteBase Prerequisite = null;
                    do
                    {
                        lock (InstallQueue)
                        {
                            if (InstallQueue.Count > 0)
                            {
                                Prerequisite = InstallQueue.Dequeue();
                            }
                        }
                        if (Prerequisite == null)
                        {
                            lock (this.statusLock)
                            {
                                this.Status = new InstallationStatus(
                                    new InstallationStatus.InstallationWaitingForDownloadStatus(),
                                    ((InstallationStatus)this.Status).Download
                                    );
                            }
                            InstallQueueAdded.WaitOne();
                        }
                    } while (Prerequisite == null);


                    lock (this.statusLock)
                    {
                        this.Status = new InstallationStatus(
                            new InstallationStatus.InstallingStatus(PackagesToInstall, PackagesInstalled, Prerequisite.Name),
                            ((InstallationStatus)this.Status).Download
                            );
                    }

                    try
                    {
                        //if needed, run process with admin rights to execute installations
                        if (Prerequisite.RequiresAdmin)
                        {
                            this.adminProcessConnector.DoInstallRemote(Prerequisite);
                        }
                        else
                        {
                            Prerequisite.DoInstall();
                        }
                        Prerequisite.SetInstalled();
                    }
                    catch (Exception Error)
                    {
                        lock (this.statusLock)
                        {
                            this.Status = new InstallationErrorStatus(Error.Message);
                        }
                        //TODO: Stop downloads
                        break;
                    }

                    PackagesInstalled++;
                    lock (this.statusLock)
                    {
                        this.Status = new InstallationStatus(
                            new InstallationStatus.InstallingStatus(PackagesToInstall, PackagesInstalled, Prerequisite.Name),
                            ((InstallationStatus)this.Status).Download
                            );
                    }
                }

                //Installation finished or error occured. Close client program if it was started
                this.adminProcessConnector.EndIfStartedAndWaitForExit();

                lock (this.statusLock)
                {
                    if (this.Status is InstallationStatus)
                    {
                        this.Status = new InstallationSuccessStatus();
                    }
                    else
                    {
                        //Error status, leave as is
                    }
                }
            }).Start();
        }