private void TimerStatus(object state)
        {
            DriverUpgradeData upgradeData = state as DriverUpgradeData;

            TimeSpan delta    = new TimeSpan(0, 0, 1);
            TimeSpan timeSpan = new TimeSpan();

            while (!_timerEvent.WaitOne(1000))
            {
                timeSpan           = timeSpan.Add(delta);
                upgradeData.Status = Resource.DurationFormat.FormatWith
                                     (
                    timeSpan.Hours,
                    timeSpan.Minutes,
                    timeSpan.Seconds,
                    timeSpan.Milliseconds
                                     );

                TriggerDataUpdateEvent();
            }
        }
        /// <summary>
        /// Returns a list of installed queues by driver and architecture.
        /// </summary>
        /// <param name="driverName">Name of the driver.</param>
        /// <param name="architectureName">Name of the architecture.</param>
        /// <returns></returns>
        public static Collection <DriverUpgradeData> SelectQueues(string driverName, string architectureName)
        {
            if (string.IsNullOrEmpty(architectureName))
            {
                throw new ArgumentNullException("architectureName");
            }

            Collection <DriverUpgradeData> queues = new Collection <DriverUpgradeData>();

            ProcessorArchitecture selectedArch = (architectureName.Equals("x64", StringComparison.OrdinalIgnoreCase))
                ? ProcessorArchitecture.NTAMD64 : ProcessorArchitecture.NTx86;

            var processors = PrintProcessor.ProcessorsByArchitecture;

            string basePath = @"System\CurrentControlSet\Control\Print\Printers";

            using (RegistryKey key = Registry.LocalMachine.OpenSubKey(basePath))
            {
                foreach (string queueName in key.GetSubKeyNames())
                {
                    using (RegistryKey queueKey = Registry.LocalMachine.OpenSubKey(Path.Combine(basePath, queueName)))
                    {
                        if (queueKey != null)
                        {
                            // Check that the driver name matches for this queue.  If it does, keep going.
                            object driverModel = queueKey.GetValue("Printer Driver");
                            if (driverModel != null && driverModel.ToString().Equals(driverName, StringComparison.OrdinalIgnoreCase))
                            {
                                // Find the processor name, see if it has the same architecture as the requested driver
                                // If it does, then add the associated queue to the list.
                                object processorValue = queueKey.GetValue("Print Processor");
                                if (processorValue != null)
                                {
                                    string processorName = (string)processorValue;

                                    // Determine if the given print processor is associated with the current
                                    // architecture for any queues referencing the given driver name.  If
                                    // this queue's driver maps to a print processor for this architecture
                                    // then add it to the list of queues using the given driver...
                                    var any =
                                        (
                                            from archKey in processors.Keys
                                            from value in processors[archKey]
                                            where processorName.Equals(value, StringComparison.OrdinalIgnoreCase) &&
                                            archKey == selectedArch.ToDriverArchitecture()
                                            select archKey
                                        ).Any();

                                    if (any)
                                    {
                                        DriverUpgradeData data = new DriverUpgradeData(queueName);
                                        data.PrintProcessor = processorName;
                                        queues.Add(data);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(queues);
        }
        private void UpgradeToNewVersion(object state)
        {
            try
            {
                UpdateStatus("Installing {0}...".FormatWith(_newDriver.Name), StatusEventType.StatusChange);
                _queueManager.InstallDriver();
                UpdateStatus("Installing {0}...done".FormatWith(_newDriver.Name), StatusEventType.StatusChange);

                int      queueCount = 0;
                TimeSpan totalTime  = new TimeSpan();

                DateTime start = DateTime.Now;
                foreach (var upgradeData in _upgradeData)
                {
                    UpdateStatus("Upgrading {0}".FormatWith(upgradeData.QueueName), StatusEventType.StatusChange);

                    _currentData = upgradeData;

                    if (upgradeData.Include)
                    {
                        queueCount++;
                        lock (this)
                        {
                            _uiTimerThread = new Thread(TimerStatus);
                            _uiTimerThread.Start(upgradeData);
                        }

                        upgradeData.StartTime = DateTime.Now;
                        _queueManager.UpgradeDriver(upgradeData.QueueName);
                        upgradeData.EndTime = DateTime.Now;

                        // Release the timer prompt so it stops
                        _timerEvent.Set();

                        TimeSpan upgradeDuration = upgradeData.EndTime.Subtract(upgradeData.StartTime);
                        upgradeData.Duration = Resource.DurationFormat.FormatWith
                                               (
                            upgradeDuration.Hours,
                            upgradeDuration.Minutes,
                            upgradeDuration.Seconds,
                            upgradeDuration.Milliseconds
                                               );
                        upgradeData.Status = "Complete";

                        totalTime = totalTime.Add(upgradeData.EndTime.Subtract(upgradeData.StartTime));

                        TriggerDataUpdateEvent();
                    }
                    else
                    {
                        upgradeData.Status = "Skipping";
                    }
                }
                DateTime end = DateTime.Now;

                CalculateStatistics(queueCount, start, end, totalTime);
            }
            catch (Win32Exception ex)
            {
                UpdateStatus("Install failed...{0}".FormatWith(ex.Message), StatusEventType.StatusChange);
                FireUpgradeCompleted();
                return;
            }
        }