/// <summary>
        /// Exexutes the Print Job
        /// </summary>
        /// <returns></returns>
        private PluginExecutionResult ExecutePrintJob()
        {
            PluginExecutionResult printResult = new PluginExecutionResult(PluginResult.Passed);

            try
            {
                PrintQueue     defaultPrintQueue;
                PrintQueueInfo printQueueInfo = ExecutionData.PrintQueues.GetRandom();
                UpdateStatus("Print Activity: Retrieving print queue for " + printQueueInfo.QueueName);
                defaultPrintQueue = PrintQueueController.Connect(printQueueInfo);
                PrintingEngine engine = new PrintingEngine();

                // Select a documents to print
                DocumentCollectionIterator documentIterator = new DocumentCollectionIterator(CollectionSelectorMode.ShuffledRoundRobin);
                Document document = documentIterator.GetNext(ExecutionData.Documents);

                // Download the document and log the starting information for the print job
                Guid     jobId     = SequentialGuid.NewGuid();
                FileInfo localFile = ExecutionServices.FileRepository.GetFile(document);

                UpdateStatus($"Print Activity: Printing {localFile.Name} to {defaultPrintQueue.FullName}");
                var result = engine.Print(localFile, defaultPrintQueue);
                UpdateStatus($"Print Activity: Finished printing {localFile.Name}");

                return(printResult);
            }
            catch (Exception genericException)
            {
                printResult = new PluginExecutionResult(PluginResult.Failed, genericException.ToString());
                ExecutionServices.SystemTrace.LogError(genericException.ToString());
                return(printResult);
            }
        }
        /// <summary>
        /// Print Job Sepearator method will be called from non Printing Plugins.
        /// </summary>
        /// <param name="executionData"></param>
        public void PrintJobSeparator(PluginExecutionData executionData)
        {
            PrintQueueInfo printQueueInfo = executionData.PrintQueues.FirstOrDefault();
            PrintQueue     printQueue     = printQueue = PrintQueueController.Connect(printQueueInfo);

            PrintJobSeparator(executionData, printQueue);
        }
        /// <summary>
        /// Configures Printer Attributes
        /// </summary>
        /// <param name="printerName"></param>
        private void ConfigurePrinterAttributes(PrintQueue printQueue)
        {
            UpdateStatus(string.Format("Configuring Bidirectional Support for Printer {0}", printQueue.Name));
            PrintQueueController.ChangeAttributes(printQueue, PrintQueueAttributes.EnableBidi, _activityData.EnableBidi);

            UpdateStatus(string.Format("Configuring Print after Spooling for Printer {0}", printQueue.Name));
            PrintQueueController.ChangeAttributes(printQueue, PrintQueueAttributes.Queued, _activityData.PrintAfterSpooling);
        }
Beispiel #4
0
        private void ExecuteHandler()
        {
            ExecutionServices.SystemTrace.LogDebug($"Plugin exec data print queues = {_printQueues.Count}");
            foreach (var x in _printQueues)
            {
                ExecutionServices.SystemTrace.LogDebug($"Queue={x.QueueName}");
            }

            // Check to make sure we have something in the pool...
            if (_printQueues.Count == 0)
            {
                var msg = "None of the selected print queues are available.";

                ExecutionServices.SystemTrace.LogDebug(msg);
                throw new PrintQueueNotAvailableException(msg);
            }

            // Pick a print queue and log the device/server if applicable
            PrintQueueInfo queueInfo = _printQueues.GetRandom();

            LogDevice(_pluginData, queueInfo);
            LogServer(_pluginData, queueInfo);

            // Connect to the print queue
            ExecutionServices.SystemTrace.LogDebug($"Connecting to queue: {queueInfo.QueueName}");
            PrintQueue printQueue = PrintQueueController.Connect(queueInfo);

            _serverName = printQueue.HostingPrintServer.Name.TrimStart('\\');
            ExecutionServices.SystemTrace.LogDebug($"Connected to queue: {printQueue.FullName}");

            // Select a document to print
            Document document = _documentIterator.GetNext(_pluginData.Documents);
            ActivityExecutionDocumentUsageLog documentLog = new ActivityExecutionDocumentUsageLog(_pluginData, document);

            ExecutionServices.DataLogger.Submit(documentLog);

            // Download the document and log the starting information for the print job
            Guid              jobId     = SequentialGuid.NewGuid();
            FileInfo          localFile = ExecutionServices.FileRepository.GetFile(document);
            PrintJobClientLog log       = LogPrintJobStart(_pluginData, localFile, printQueue, jobId);

            // Print the job
            PrintingEngineResult result = _engine.Print(localFile, printQueue, jobId);

            _printJobId = result.UniqueFileId;

            if (result == null)
            {
                throw new FilePrintException($"Failed to print {localFile}.");
            }

            // Log the ending information
            LogPrintJobEnd(log, result);
            ExecutionServices.SystemTrace.LogDebug("Controller execution completed");
        }
Beispiel #5
0
        /// <summary>
        /// Sets up the printer as a share
        /// </summary>
        public void EnableSharedQueue()
        {
            using (LocalPrintServer server = new LocalPrintServer(PrintSystemDesiredAccess.AdministrateServer))
            {
                using (PrintQueue queue = new PrintQueue(server, QueueName, PrintSystemDesiredAccess.AdministratePrinter))
                {
                    queue.ShareName = QueueName;
                    queue.Commit();

                    PrintQueueController.ChangeAttributes(queue, PrintQueueAttributes.Shared, true);
                }
            }
        }
        public PluginExecutionResult Execute(PluginExecutionData executionData)
        {
            if (!_setupDone)
            {
                AddOfficeRegistryEntries();
                _setupDone = true;
            }

            _mailMergeData            = executionData.GetMetadata <MailMergeActivityData>();
            _printQueueInfoCollection = executionData.PrintQueues;
            _userName  = executionData.Credential.UserName;
            _sessionId = executionData.SessionId;

            _tempDataSourceFileName = Path.Combine(Path.GetTempPath(), $"{_userName}_{Guid.NewGuid()}_tempDataSourceFile.doc");

            //install the local printer or remote print queue
            // Set up the list of print devices
            if (_printQueueInfoCollection.Count == 0)
            {
                return(new PluginExecutionResult(PluginResult.Skipped));
            }

            PrintQueueInfo printQueueInfo = _printQueueInfoCollection.First();
            PrintQueue     printQueue     = PrintQueueController.Connect(printQueueInfo);

            // Log the device/server that was used for this job, if one was specified
            LogDevice(executionData, printQueueInfo);


            if (_mailMergeData.PrintJobSeparator)
            {
                PrintTag(printQueue, executionData);
            }

            _defaultPrintQueue = printQueue.FullName;

            //generate the mail merge doc and print it to default print queue
            try
            {
                ExecutionServices.CriticalSection.Run(new Framework.Synchronization.LocalLockToken(printQueueInfo.AssociatedAssetId, new TimeSpan(0, 0, 30), new TimeSpan(0, 5, 0)), PrintMailMerge);
            }
            catch (Exception ex)
            {
                return(new PluginExecutionResult(PluginResult.Failed, ex.Message));
            }

            return(new PluginExecutionResult(PluginResult.Passed));
        }
        /// <summary>
        /// Installs the remote printers.  For Citrix these printers need to be installed on the
        /// client ahead of time so that they are autocreated on the server.
        /// </summary>
        private void InstallRemotePrinters()
        {
            TraceFactory.Logger.Debug("Installing remote printers");

            // The manifest includes all queues required for the entire session.
            // Only install queues for activities that are part of this manifest.
            var activityIds = SystemManifest.Resources.SelectMany(n => n.MetadataDetails).Select(n => n.Id);
            List <RemotePrintQueueInfo> remotePrintQueues = activityIds.Select(n => SystemManifest.ActivityPrintQueues[n]).SelectMany(n => n.OfType <RemotePrintQueueInfo>()).ToList();

            List <Guid> createdQueues = new List <Guid>();

            foreach (RemotePrintQueueInfo queueInfo in remotePrintQueues)
            {
                // Only install the printer once by checking the printQueueId list.
                if (!createdQueues.Contains(queueInfo.PrintQueueId))
                {
                    createdQueues.Add(queueInfo.PrintQueueId);
                }

                string printerName = queueInfo.GetPrinterName();

                if (!PrintQueueInstaller.IsInstalled(printerName))
                {
                    ChangeMachineStatusMessage("Installing queue {0}".FormatWith(printerName));

                    // Install the print queue using administrator first to ensure the driver gets down
                    // without any authorization issues.  Sleep for a few seconds, then try to install
                    // the queue for the given user.  It should use the already installed driver and eliminate
                    // any issues in getting the driver down on the box.
                    CallPrintUi(printerName, credential: AdminCredential);
                    Thread.Sleep(1000);
                    CallPrintUi(printerName, credential: _credential);
                }

                // Display the printers that have been installed
                List <string> queues = PrintQueueController.GetPrintQueues().Select(n => n.ShareName).ToList();

                TraceFactory.Logger.Debug("Printers after Install: {0}{1}".FormatWith
                                          (
                                              Environment.NewLine,
                                              string.Join(Environment.NewLine, queues))
                                          );
            }
        }
        /// <summary>
        /// Determines if the print job is rendered on the client or on the server.
        /// </summary>
        /// <param name="queues">The list of queues.</param>
        /// <returns>
        ///   <c>true</c> if Render Print Jobs on Client is set for the specified queue name; otherwise, <c>false</c>.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">queues</exception>
        public SerializableDictionary <string, string> GetJobRenderLocation(Collection <string> queues)
        {
            if (queues == null)
            {
                throw new ArgumentNullException("queues");
            }

            SerializableDictionary <string, string> values = new SerializableDictionary <string, string>();

            foreach (string queueName in queues)
            {
                PrintQueue queue    = PrintQueueController.GetPrintQueue(queueName);
                var        location = PrintQueueController.GetJobRenderLocation(queue);
                values.Add(queueName, location.ToString());
                TraceFactory.Logger.Debug("Render On Client {0}:{1}".FormatWith(queueName, location));
            }

            return(values);
        }
Beispiel #9
0
        private MonitoredQueueInfoCache GetQueueInfo(string queueName)
        {
            MonitoredQueueInfoCache cachedInfo = null;

            try
            {
                //Try to retrieve from the cache
                if (!_cache.TryGetValue(queueName, out cachedInfo))
                {
                    cachedInfo = new MonitoredQueueInfoCache(queueName)
                    {
                        PrintServer   = Environment.MachineName,
                        PrintServerOS = Environment.OSVersion.ToString()
                    };
                    _cache.Add(queueName, cachedInfo);
                }

                // Refresh queue data if older than 5 minutes
                if (cachedInfo.QueueSettingsRetrieved < DateTime.Now.AddMinutes(-5))
                {
                    PrintQueue queue = PrintQueueController.GetPrintQueue(queueName);
                    cachedInfo.Refresh(queue);

                    PrintJobRenderLocation location = PrintQueueController.GetJobRenderLocation(queue);
                    if (location != PrintJobRenderLocation.Unknown)
                    {
                        cachedInfo.RenderOnClient = (location == PrintJobRenderLocation.Client);
                    }
                    else
                    {
                        cachedInfo.RenderOnClient = null;
                    }

                    cachedInfo.QueueSettingsRetrieved = DateTime.Now;
                }
            }
            catch (Win32Exception ex)
            {
                TraceFactory.Logger.Error("Unable to get queue data for {0}".FormatWith(queueName), ex);
            }

            return(cachedInfo);
        }
        /// <summary>
        /// Installs the PrintDriver With LPR Queue Details as in activity Data
        /// </summary>
        private void InstallPrintDriverWithLPRQueue()
        {
            DriverDetails driver = CreateDriver(_activityData.PrintDriver, _pluginSettings["PrintDriverServer"]);

            UpdateStatus($"Installing driver from {driver.InfPath}");
            ExecutionServices.SystemTrace.LogDebug($"Installing driver from {driver.InfPath}");
            DriverInstaller.Install(driver);
            UpdateStatus("Driver Installation Completed");

            UpdateStatus(string.Format("Creating LPR Port connecting to HPAC Server :{0}, QueueName : {1}", _hpacServerIP, _activityData.LprQueueName));
            ExecutionServices.SystemTrace.LogDebug($"Creating LPR Port connecting to HPAC Server :{_hpacServerIP}, QueueName : {_activityData.LprQueueName}");
            string portName = string.Format("_IP {0}_{1}", _hpacServerIP, _activityData.LprQueueName);

            PrintPortManager.AddLprPort(portName, LprPrinterPortInfo.DefaultPortNumber, _hpacServerIP, _activityData.LprQueueName);
            UpdateStatus("Port Creation Completed");

            UpdateStatus(string.Format("Creating LocalPrintDevice with Driver :{0} and port : {1}", driver.Name, portName));
            ExecutionServices.SystemTrace.LogDebug(string.Format("Creating LocalPrintDevice with Driver :{0} and port : {1}", driver.Name, portName));

            string queueName = string.Format("{0} ({1})", driver.Name, portName);

            if (!PrintQueueInstaller.IsInstalled(queueName))
            {
                PrintQueueInstaller.CreatePrintQueue(queueName, driver.Name, portName, driver.PrintProcessor);
                PrintQueueInstaller.WaitForInstallationComplete(queueName, driver.Name);
                UpdateStatus("Print Device Installation Completed");
            }

            PrintQueue queue = PrintQueueController.GetPrintQueue(queueName);

            if (_activityData.IsDefaultPrinter)
            {
                PrintQueueController.SetDefaultQueue(queue);
                UpdateStatus("Setting the Installed Print Device as a default Print Device");
            }

            ConfigurePrinterAttributes(queue);
            UpdateStatus("Printer Attributes Configuration Completed");
        }
        /// <summary>
        /// Prints the specified file to the specified print queue.
        /// </summary>
        /// <param name="file">The file to print.</param>
        /// <param name="printQueue">The <see cref="PrintQueue" /> to print the file to.</param>
        /// <param name="printVerb">The <see cref="PrintVerb" /> to use.</param>
        /// <returns>A <see cref="FilePrintResult" /> object representing the outcome of the print operation.</returns>
        /// <exception cref="FilePrintException">An error occurred while printing the file.</exception>
        protected FilePrintResult PrintFile(FileInfo file, PrintQueue printQueue, PrintVerb printVerb)
        {
            OnStatusChanged($"Printing document using the {printVerb} verb.");

            // If the verb being used is the Print verb, the default printer must be changed.
            if (printVerb == PrintVerb.Print)
            {
                PrintQueueController.SetDefaultQueue(printQueue);
            }

            ProcessStartInfo processStartInfo = new ProcessStartInfo
            {
                FileName        = file.FullName,
                Verb            = printVerb.ToString().ToLower(CultureInfo.CurrentCulture),
                Arguments       = string.Format("\"{0}\"", printQueue.FullName),
                CreateNoWindow  = true,
                WindowStyle     = ProcessWindowStyle.Hidden,
                UseShellExecute = true,
                ErrorDialog     = false
            };

            return(PrintFileViaProcess(file, processStartInfo));
        }
Beispiel #12
0
        /// <summary>
        /// Retrieves the list of installed ports on this machine and pairs the port data with it's corresponding queue information.
        /// </summary>
        /// <returns></returns>
        private List <QueuePortData> GetQueueData()
        {
            Collection <StandardTcpIPPort> ports  = StandardTcpIPPort.InstalledPorts;
            List <QueuePortData>           result = new List <QueuePortData>();

            _installedPorts = new Dictionary <QueuePortData, StandardTcpIPPort>();

            StandardTcpIPPort port = null;

            foreach (PrintQueue queue in PrintQueueController.GetPrintQueues())
            {
                QueuePortData data = new QueuePortData(queue.Name, queue.QueuePort.Name);
                port = ports.Where(p => p.PortName == data.PortName).FirstOrDefault();
                if (port != null) //Only return the queues that have a port.
                {
                    data.PortAddress = port.Address;
                    data.PortNumber  = unchecked ((int)port.PortNumber);
                    result.Add(data);
                    _installedPorts.Add(data, port);
                }
            }

            return(result);
        }
Beispiel #13
0
        /// <summary>
        /// Installs the print queue
        /// </summary>
        private Status InstallPrintQueue(PluginExecutionData executionData)
        {
            if (executionData.PrintQueues.Count == 0)
            {
                return(Status.Skipped);
            }


            _printQueueInfo    = executionData.PrintQueues.First();
            _defaultPrintQueue = PrintQueueController.Connect(_printQueueInfo);

            // Log the device/server that was used for this job, if one was specified
            LogDevice(executionData, _printQueueInfo);

            //To check count of paper size,type and trays
            try
            {
                int paperSize  = GetCountFromRegistry("MediaSize");
                int paperType  = GetCountFromRegistry("MediaType");
                int inputtrays =
                    ((string[])
                     Registry.LocalMachine.OpenSubKey(
                         $@"System\CurrentControlSet\Control\Print\Printers\{ (object)_defaultPrintQueue.FullName}\PrinterDriverData").GetValue("InputSlot")).Count(
                        x => x.StartsWith("Tray", StringComparison.OrdinalIgnoreCase));

                ExecutionServices.SystemTrace.LogInfo($"Paper Sizes available for { (object)_defaultPrintQueue.FullName} are { (object)paperSize}");
                ExecutionServices.SystemTrace.LogInfo($"Paper Types available for { (object)_defaultPrintQueue.FullName} are { (object)paperType}");
                ExecutionServices.SystemTrace.LogInfo($"Trays available  for {_defaultPrintQueue.Name}  are {inputtrays}");
            }
            catch (NullReferenceException nullRefEx)
            {
                ExecutionServices.SystemTrace.LogInfo($"Something went wrong when trying to read values from registry, Please manually validate the supported paper sizes, types and trays supported. Exception: { (object)nullRefEx.Message}");
            }
            if (ValidatePrintingShortcut(_defaultPrintQueue.FullName))
            {
                try
                {
                    //this is a fix for defaultprintqueue.connected not working in windows vista due to UAC
                    foreach (string printerName in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
                    {
                        if (_defaultPrintQueue.FullName.Equals(printerName))
                        {
                            if (_activityData.IsDefaultPrinter)
                            {
                                PrintQueueController.SetDefaultQueue(_defaultPrintQueue);
                            }

                            ExecutionServices.SystemTrace.LogDebug($"Printer installed: { (object)printerName}");
                            return(Status.Passed);
                        }
                    }
                }
                catch
                {
                    return(Status.Failed);
                }
            }
            else
            {
                ExecutionServices.SystemTrace.LogInfo(
                    $"Failed to install the device: {_printQueueInfo.AssociatedAssetId}");
                return(Status.Failed);
            }

            return(Status.Passed);
        }
Beispiel #14
0
        /// <summary>
        /// Sets the client rendering mode for Vista and above.
        /// </summary>
        public void EnableClientRendering()
        {
            PrintQueue queue = PrintQueueController.GetPrintQueue(QueueName);

            PrintQueueController.SetJobRenderLocation(queue, IsRenderedOnClient ? PrintJobRenderLocation.Client : PrintJobRenderLocation.Server);
        }
Beispiel #15
0
        /// <summary>
        /// Start the activity.
        /// </summary>
        /// <param name="executionData">Serialized activity data.</param>
        public PluginExecutionResult ProcessActivity(PluginExecutionData executionData)
        {
            PrintingActivityData     data        = executionData.GetMetadata <PrintingActivityData>();
            PrintQueueInfoCollection printQueues = executionData.PrintQueues;

            // Initialize the document iterator, if it is not already created
            if (_documentIterator == null)
            {
                CollectionSelectorMode mode = data.ShuffleDocuments ? CollectionSelectorMode.ShuffledRoundRobin : CollectionSelectorMode.RoundRobin;
                _documentIterator = new DocumentCollectionIterator(mode);
            }

            // Check to make sure we have something in the pool...
            if (printQueues.Count == 0)
            {
                return(new PluginExecutionResult(PluginResult.Skipped, "None of the selected print queues are available.", "No available print queues."));
            }

            // Select a print queue and log the device/server if applicable
            PrintQueueInfo printQueueInfo = printQueues.GetRandom();

            LogDevice(executionData, printQueueInfo);
            LogServer(executionData, printQueueInfo);

            // Get the corresponding system print queue
            LogDebug(string.Format("Retrieving print queue for {0}", printQueueInfo.QueueName));
            PrintQueue printQueue;

            if (ExecutionServices.SessionRuntime.AsInternal().IsCitrixEnvironment())
            {
                printQueue = GetCitrixPrintQueue(printQueueInfo);
            }
            else
            {
                printQueue = PrintQueueController.Connect(printQueueInfo);
            }

            LogDebug(string.Format("Found queue: {0}", printQueue.FullName));

            if (data.JobThrottling)
            {
                // Make sure that there is enough room in the print queue for this job.
                if (!CheckJobCountInQueue(printQueue, data.MaxJobsInQueue))
                {
                    // Skip the activity.
                    return(new PluginExecutionResult(PluginResult.Skipped, "Print Queue cannot accept any more jobs.", "Print queue throttling."));
                }
            }

            LogDebug("Executing print controller");
            if (data.PrintJobSeparator)
            {
                PrintTag(printQueue, executionData);
            }

            // Select a document to print
            Document document = _documentIterator.GetNext(executionData.Documents);
            ActivityExecutionDocumentUsageLog documentLog = new ActivityExecutionDocumentUsageLog(executionData, document);

            ExecutionServices.DataLogger.Submit(documentLog);

            // Download the document and log the starting information for the print job
            Guid              jobId     = SequentialGuid.NewGuid();
            FileInfo          localFile = ExecutionServices.FileRepository.GetFile(document);
            PrintJobClientLog log       = LogPrintJobStart(executionData, localFile, printQueue, jobId);

            // Print the job
            var engine = new Print.PrintingEngine();

            engine.StatusChanged += (s, e) => StatusChanged?.Invoke(s, e);
            var result = engine.Print(localFile, printQueue, jobId);

            // Log the ending information
            LogPrintJobEnd(log, result);
            LogDebug("Controller execution completed");
            return(new PluginExecutionResult(PluginResult.Passed));
        }
Beispiel #16
0
        private static PrintQueue GetCitrixPrintQueue(PrintQueueInfo printQueueInfo)
        {
            // Special handling for Citrix session queues - they are connections to a remote server,
            // but don't show up when querying the local server for a list of queues.
            // Connect to the queue directly by parsing the queue name
            LocalPrintQueueInfo localPrintQueueInfo = printQueueInfo as LocalPrintQueueInfo;

            if (localPrintQueueInfo != null)
            {
                LogDebug("Attempting to parse Citrix session queue.");
                var match = Regex.Match(localPrintQueueInfo.QueueName, @"^\\\\([\S\s]+)\\([\S\s]+)$");
                if (match.Success)
                {
                    LogDebug("Parse success.");
                    var serverName = match.Groups[1];
                    var queueName  = match.Groups[2];

                    LogDebug($"Server Name: {serverName}");
                    LogDebug($"Queue Name: {queueName}");

                    PrintServer server = new PrintServer($@"\\{serverName}");
                    return(new PrintQueue(server, localPrintQueueInfo.QueueName));
                }
                else
                {
                    LogDebug("Parse failure.");
                }
            }

            // When Citrix auto-generates a print queue on the Citrix server, it creates a queue with the
            // same name as the local print queue on the client machine, but appends some session information
            // to the end.  To find the real name of the print queue on the Citrix server, we need to
            // find a print queue installed on the system that starts with the same text generated by the base class.
            LogDebug($"Looking for {printQueueInfo.QueueName}");

            List <string> queueNames = PrintQueueController.GetPrintQueues().Select(n => n.FullName).ToList();
            string        clientName = Environment.GetEnvironmentVariable("CLIENTNAME");

            RemotePrintQueueInfo remotePrintQueueInfo = printQueueInfo as RemotePrintQueueInfo;

            if (remotePrintQueueInfo != null)
            {
                string citrixQueueName = queueNames.FirstOrDefault(
                    n => n.StartsWith(remotePrintQueueInfo.QueueName, StringComparison.OrdinalIgnoreCase) &&
                    n.Contains(remotePrintQueueInfo.ServerHostName, StringComparison.OrdinalIgnoreCase) &&
                    n.Contains(clientName, StringComparison.OrdinalIgnoreCase));

                if (citrixQueueName != null)
                {
                    LogDebug($"Found Citrix queue {citrixQueueName}");
                    return(PrintQueueController.GetPrintQueue(citrixQueueName));
                }
                else
                {
                    LogDebug($"Did not find mapped queue.  Looking for directly attached queue.");
                    return(PrintQueueController.GetPrintQueue(remotePrintQueueInfo.GetPrinterName()));
                }
            }

            DynamicLocalPrintQueueInfo dynamicPrintQueueInfo = printQueueInfo as DynamicLocalPrintQueueInfo;

            if (dynamicPrintQueueInfo != null)
            {
                string citrixQueueName = queueNames.FirstOrDefault(
                    n => n.StartsWith(dynamicPrintQueueInfo.QueueName, StringComparison.OrdinalIgnoreCase) &&
                    n.Contains(clientName, StringComparison.OrdinalIgnoreCase));
                if (citrixQueueName != null)
                {
                    LogDebug($"Found Citrix queue {citrixQueueName}");
                    return(PrintQueueController.GetPrintQueue(citrixQueueName));
                }
                else
                {
                    throw new PrintQueueNotFoundException($"Could not find mapped queue for {dynamicPrintQueueInfo.QueueName}");
                }
            }

            // Default to the usual behavior
            return(PrintQueueController.Connect(printQueueInfo));
        }