16 Replies Latest reply on Aug 20, 2015 2:44 AM by Daniel Johns

    Pharos Scripting Help Needed

    Cade Webb Wayfarer

      I am working with the PrintEndJobNotify script to let students know where they are printing to.

       

      Right now we display the print queues which are named (for exampple) Library-Printer1-PS or Library-Printer1-PCL or Library-Printer1-PCL-Wireless

       

      I would like to modify the script to only show the user friendly part of the queue.  I am trying to remove everything after the Printer1 (the -PCL, -PS, -Wireless, etc).

       

      We do not have more than 6 printers in one room so I I am thinking about

       

      In VBS I tried something like wscript.echo left ("Library-Printer1-PCL-HeldQ",InStr("BSS316-Printer1-PCL-HeldQ", "-")+8) which worked great.

       

      With Pharos:

       

      initialize a as string

      set a to the queue name

      initialize b as int

      set b to be the index of the “-“

      call Left and pass the queue and the variable b

       

      new a                       = PlugIn.Queue;

      new b                       = Find(a,"-") + 8;

      new c                       = Left(a,b);

       

      new sMessageSuccess         = "Print job '" +

                                      PlugIn.JobName +

                                      "' printed on printer '" +

                                      c +

                                      "'.";

       

      Pharos does not like the Find or Left functions even though they are listed in the documentation.  Any Pharos scripting guru's out there that could lead me in the right direction?

        • Re: Pharos Scripting Help Needed
          Steven English Guide

          Cade Webb,

           

          Make sure you have imported the String namespace at the top of the script, and the functions are called as namespace.function.  Also of note, sometimes the Pharos scripting language does not like to do too many things at a time.  If you have trouble with something not working that you think should after you know you are calling it properly, try breaking it down into smaller steps despite the appearance being less efficient.  See example below...

           

          import "String";
          new QueueName  = PlugIn.Queue;
          new ParsePos    = String.Find(QueueName,"-") + 8;
          new RenamedQ    = String.Left(QueueName,ParsePos);
          

           

          When broken down into smaller steps...

           

          import "String";
          new QueueName  = PlugIn.Queue;
          new ParsePos    = "";
          new RenamedQ    = "";
          String.Find(QueueName,"-") + 8;
          String.Left(QueueName,ParsePos);
          

           

          As mentioned, the import of the namespace is usually towards the top of the script since it must be processed before any String.Function can execute.

           

          Let me know if this helps.

           

          Regards,

          Steven

          • Re: Pharos Scripting Help Needed
            Cade Webb Wayfarer

            Ok So here is what I have for the script, syntax is fine now but I do not see a popup anymore.  The changes are listed in Bold.  Thank you for your help!

             

            // PlugIn Script: PrintEndJob - Notify User of Que

            //---------------------------------------------------------------------------------------

            //  Designed for:  Pharos 8.4

            //  Where:         Pharos Systems International.

            //  Last updated:  29-Apr-2013

            //

            //  Description:

            //    Notify the user if the print job succeeds or fails.

            //

            //  Important Notes:

            //      1) In order to work with Windows XP clients, you may need to

            //         adust this script.  Please read the comments above bTrySessionZero.

            //

            //---------------------------------------------------------------------------------------

            import "IO";

            import "List";

            import "Notify";

            import "PrintJob";

            import "String";

            import "Win32";

             

             

            //---------------------------------------------------------------------------------------

            // Script Info

            //---------------------------------------------------------------------------------------

            // Script name and version.

             

             

            new sScriptName       = "NotifyUser";

            new sScriptFullName   = "PrintEndJob - Notify User";

            new sScriptVersion    = "3";

             

             

            //---------------------------------------------------------------------------------------

            // Variables

            //---------------------------------------------------------------------------------------

             

             

            // Title to be shown on balloon messages.

            //

            new sMessageTitle           = "Printing status";

             

             

            // Number of seconds to display the notification if not dismissed by the user.

            //

            new iNotifyTimeout   = 30;

             

             

            // Success notifications

            //

            new QueueName  = PlugIn.Queue; 

            new ParsePos    = String.Find(QueueName,"-") + 8; 

            new RenamedQ    = String.Left(QueueName,ParsePos); 

             

             

            new bNotifyUserOfSuccess    = true;

            new bUseBalloonForSuccess   = true;

            new sMessageSuccess         = "Print job '" +

                                            PlugIn.JobName +

                                            "' printed on printer '" +

                                            RenamedQ +

                                            "'.";

             

             

            // Failure notifications

            //

            new bNotifyUserOfFailure    = true;

            new bUseBalloonForFailure   = true;

            new sMessageFailure         = "Print job '" +

                                            PlugIn.JobName +

                                            "' failed: ";

             

             

            // You do not need to edit these three values.

            new iErrorActionHide        = 1;

            new iErrorActionShowBalloon = 2;

            new iErrorActionShowMessage = 3;

             

             

            // Specific handling of errors.  Any errors with a matching substring from this

            // list will use the action specified instead of the default:

            // iErrorActionHide: Do not show the message even when error notifications are enabled.

            // iErrorActionShowBalloon: Force a balloon message for this error.

            // iErrorActionShowMessage: Force a message box for this error.

            // For default behaviour, do not include the error in this list.

            //

            new listErrorActions        =

            [

                ["Print job moved to spooled print queue. Information alert only.", iErrorActionHide],

                ["Logon ID and Password", iErrorActionShowMessage],

                ["print color", iErrorActionHide],

                ["color printing from this application", iErrorActionHide],

                ["cancelled because user does not have permission to print color with application", iErrorActionHide],

                ["No suitable printer available", iErrorActionShowBalloon]

            ];

             

             

            // This applies to jobs that do not contain Popup information.  If you know the

            // Popup Client is available, setting this to true will attempt to use the Windows

            // client name recorded by the spooler.  Set this to false if missing Popup data

            // means the user does not have the Popup Client installed.

            //

            new bFallbackToWindowsInfo  = true;

             

             

            // Windows XP users are generally logged in to session 0, which is invalid on

            // client systems since Vista.  Set this value to true if you have XP clients

            // that need to be notified.  The script will attempt to send notifications to

            // session 1 and then 0 to handle this.  This will only apply when not using the

            // Popup Client (e.g. printing via UNC/SMB).

            //

            new bTrySessionZero         = false;

             

             

            //---------------------------------------------------------------------------------------

            // Functions

            //---------------------------------------------------------------------------------------

             

             

            // Prints a nicely formatted message in the Print Server's log.

            // Note that this function uses a globally defined variable 'sScriptName'.

            function Log(sMessage)

            {

                IO.PrintLine("[" + sScriptName + "] " + sMessage);

            }

             

             

            // Exit the script with a logged message if a condition is true.

            // e.g. AbortIf(PlugIn.UserName == "offline", "Script ignores offline user");

            function AbortIf(bCondition, sReason)

            {

                if (bCondition)

                {

                    Log("Not notifying user: " + sReason);

                    exit;

                }

            }

             

             

            // Return the action to use for error messages, according to the

            // error handling rules in listErrorActions above.

            function GetErrorAction()

            {

                new iErrorAction = iErrorActionShowMessage;

                if (bUseBalloonForFailure)

                {

                    iErrorAction = iErrorActionShowBalloon;

                }

             

             

                new iCount = 0;

                new iMaxCount = List.Length(listErrorActions);

             

             

                while (iCount < iMaxCount)

                {

                    if (String.Find(PlugIn.Error, listErrorActions[iCount][0]) <> -1)

                    {

                        iErrorAction = listErrorActions[iCount][1];

                        Log("Error Action: " + iErrorAction);

                        iCount = iMaxCount;

                    }

                    iCount += 1;

                }

                return iErrorAction;

            }

             

             

            // Send a Notify message to sHost, with sTitle and sMessage.

            // bUseBalloon: set to true for a balloon box, false for a message box.

            // sTitle is ignored when bUseBalloon is false.

            // Returns true if the message was sent without error.

            function NotifyUser(sHost, sTitle, sMessage, bUseBalloon, iTimeout)

            {

                try {

                    if (bUseBalloon)

                    {

                        new iStyle = 1;

                        // Set an error style for a balloon if this is a failure message.

                        if (PlugIn.Failed)

                        {

                            iStyle = 3;

                        }

                        Notify.BalloonBox(sHost, sTitle, sMessage, iTimeout, iStyle);

                    }

                    else

                    {

                        Notify.MessageBox(sHost, sMessage, iTimeout);

                    }

                    Log("Notify message sent successfully.");

                    return true;

                }

                catch

                {

                    Log("The Notify message failed to send.");

                    return false;

                }

            }

             

             

            // Get the name of the submitting client machine from the Popup data.

            // If no Popup data is available and 'tryWindowsName' is true, use the

            // machine name recorded by the Windows Spooler.

            function GetClientHostname(tryWindowsName)

            {

                // Get the IP address/hostname of the computer the job was printed from.

                // First attempt to get the best value from Popup data.

                new sHostName = PrintJob.GetPopupData(

                        PlugIn.Queue,

                        PlugIn.JobID, 

                        "StaticNotifyIP");

                if (String.IsEmpty(sHostName) and tryWindowsName)

                {

                    // Popup data is not available, attempt to use the Windows client name instead.

                    new listPrintJobValues = Win32.GetJob(PlugIn.Queue, PlugIn.JobID, [2]);

                    sHostName = listPrintJobValues[0][1];

             

             

                    // Remove the machine name prefix (\\) if found at the start.

                    new sMachinePrefix          = "\\\\";

                    if (String.Find(sHostName, sMachinePrefix) == 0)

                    {

                        String.Delete(sHostName, 0, String.Length(sMachinePrefix));

                    }

                }

                return sHostName;

            }

             

             

            //---------------------------------------------------------------------------------------

            // PlugIn code

            //---------------------------------------------------------------------------------------

             

             

            Log("Solution: " + sScriptFullName);

            Log("Version: 3");

            Log("Copyright: Pharos Systems International");

             

             

            Log("Direct Queue? " + PlugIn.Direct);

            Log("Failed? " + PlugIn.Failed);

             

             

            // Don't attempt to notify Secure Release users, or MobilePrint users.

            AbortIf(not PlugIn.Direct, "This is a Secure Release job.");

            AbortIf(PlugIn.JobType != "Native", "This is a MobilePrint job.");

             

             

            new sFinalMessage = "";

            new bUseBalloon = false;

             

             

            if (PlugIn.Failed)

            {

                // An error occurred - check whether we should notify the user.

                AbortIf(not bNotifyUserOfFailure, "Not configured to send failure messages.");

                new iErrorAction = GetErrorAction();

                AbortIf(iErrorAction == iErrorActionHide, "Error message suppressed.");

             

             

                // Remove the extra details from the error message.

                new sError = PlugIn.Error;

                Log("Unmodified error message: " + sError);

                new iPos = String.Find(sError, ":") + 1;

                if (iPos > 0 and iPos < String.Length(sError))

                {

                    String.Mid(sError, iPos);

                }

             

             

                sFinalMessage = sMessageFailure + sError;

                bUseBalloon = iErrorAction == iErrorActionShowBalloon;

            }

            else

            {

                // Job printed successfully - check whether we should notify the user.

                AbortIf(not bNotifyUserOfSuccess, "Not configured to send success messages.");

                sFinalMessage = sMessageSuccess;

                bUseBalloon = bUseBalloonForSuccess;

            }

             

             

            // Make sure we have a valid hostname for the notification.

            new sHostName = GetClientHostname(bFallbackToWindowsInfo);

            AbortIf(String.IsEmpty(sHostName), "Missing hostname.");

             

             

            Log("Host Name: " + sHostName);

            Log("Message to be sent: " + sFinalMessage);

             

             

            // Check if we need to add a session identifier.

            if (String.Find(sHostName, ":S") < 0)

            {

                // Although we can tell if a Notify attempt failed, we can't tell if the user never

                // saw it because the session id was wrong.  So unfortunately we have to attempt to

                // send the message twice when including XP clients.  Note also that it is possible

                // that session 1 is not always correct for modern clients.

                // If there was an error sending a message to the client on session 1, it will be

                // a connection failure of some kind.  In that case, don't bother trying session 0.

                if (NotifyUser(sHostName + ":S1", sMessageTitle, sFinalMessage, bUseBalloon, iNotifyTimeout))

                {

                    if (bTrySessionZero)

                    {

                        NotifyUser(sHostName + ":S0", sMessageTitle, sFinalMessage, bUseBalloon, iNotifyTimeout);

                    }

                }

            }

            else

            {

                NotifyUser(sHostName, sMessageTitle, sFinalMessage, bUseBalloon, iNotifyTimeout);

            }

              • Re: Pharos Scripting Help Needed
                Steven English Guide

                Cade Webb,

                 

                I did not check the whole thing, but if you are not getting a popup on the workstation with the script, I recommend making sure that you can receive them at all.  Pharos Notify needs to be installed - which it will be if you deployed a print packaged - but the connection for the print job notification originates from the server.  Make sure the server can initiate a connection to the client by IP address on port 28201.  If a firewall or routing issue does not fix it, then isolate the issue between the script and the built-in notifications by removing the script and utilizing the cost information enabled via checkbox (informed print) to confirm that it popup notifications are received.

                 

                Regards,

                Steven

              • Re: Pharos Scripting Help Needed
                Cade Webb Wayfarer

                Steven,

                 

                The popup works out of the box (display queue name), it did not work when I modified the display text. 

                 

                Thanks,

                 

                Cade

                  • Re: Pharos Scripting Help Needed
                    Steven English Guide

                    Cade Webb,

                     

                    Did you try breaking the lines down into smaller pieces as originally suggested?

                     

                    Regards,

                    Steven

                     

                    When broken down into smaller steps...

                    import "String";  
                    new QueueName  = PlugIn.Queue;  
                    new ParsePos    = "";  
                    new RenamedQ    = "";  
                    String.Find(QueueName,"-") + 8;  
                    String.Left(QueueName,ParsePos);
                    
                      • Re: Pharos Scripting Help Needed
                        Cade Webb Wayfarer

                        I did

                         

                        instead of:

                         

                        // Success notifications

                         

                        new QueueName  = PlugIn.Queue;

                        new ParsePos    = String.Find(QueueName,"-") + 8;

                        new RenamedQ    = String.Left(QueueName,ParsePos);

                         

                         

                        new bNotifyUserOfSuccess    = true;

                        new bUseBalloonForSuccess   = true;

                        new sMessageSuccess         = "Print job '" +

                                                        PlugIn.JobName +

                                                        "' printed on printer '" +

                                                        RenamedQ +

                                                        "'.";

                        I tried:

                        // Success notifications

                         

                        new QueueName  = PlugIn.Queue; 

                        new ParsePos    = ""

                        new RenamedQ    = ""

                        String.Find(QueueName,"-") + 8

                         

                         

                        new bNotifyUserOfSuccess    = true;

                        new bUseBalloonForSuccess   = true;

                        new sMessageSuccess         = "Print job '" +

                                                        PlugIn.JobName +

                                                        "' printed on printer '" +

                                                        String.Left(QueueName,ParsePos)  +

                                                        "'.";

                         

                        Thanks,

                         

                        Cade

                          • Re: Pharos Scripting Help Needed
                            Steven English Guide

                            Cade Webb,

                             

                            I am not clear on whether or not that worked, but either way I think you are probably trying to do too much at one time by putting the String.Left in the success message.  That should be done outside of compilation of the message, and realistically, it would probably be best to wrap all of that in a try/catch in case you ever have a queue that doesn't have the hyphen in the name.

                             

                            The snippet below works as expected for me.  Note, I removed the +8 in String.Find since it did not seem to belong.

                             

                            Regards,

                            Steven

                             

                            // Success notifications
                            //
                            
                            new sQueueName  = PlugIn.Queue;  
                            new iParsePos    = ""; 
                            
                            try
                            {  
                                iParsePos = String.Find(sQueueName,"-");  
                                if(iParsePos >= 0)
                                {
                                    String.Left(sQueueName,iParsePos);
                                }
                                IO.PrintLine("[" + sScriptName + "] Changing queue name for success message from <" + PlugIn.Queue + "> to <" + sQueueName + ">");
                            }
                            catch
                            {
                                IO.PrintLine("[" + sScriptName + "] Parse character not found... leaving queue name unmodified.");
                            }
                            
                            new bNotifyUserOfSuccess    = true;
                            new bUseBalloonForSuccess  = true;
                            new sMessageSuccess        = "Print job '" +
                                                            PlugIn.JobName +
                                                            "' printed on printer '" +
                                                            sQueueName  +
                                                            "'.";
                            
                            // Failure notifications
                            
                              • Re: Pharos Scripting Help Needed
                                Steven English Guide

                                Cade Webb,

                                 

                                As a side note,  if you are using this on a direct queue as expected, why not just tell them which printer they are printing to instead of telling them a truncated queue name?  If you enable logs, you'll notice that the IO.PrintLine in the functioning sample above actually enters into the log before the first messages, so you might want to move that around or just comment it out.  Realistically though, it seems like it would make more sense to change it to notify based on the printer name instead, as the printers in modern versions of Pharos can be renamed at will from within the Pharos Administrator without requiring any kind of redeployment.  The only exception I could think of to this would be if you have other custom scripts in place looking at specific printer names, but that would be uncommon and seems unlikely.

                                 

                                Regards,

                                Steven

                        • Re: Pharos Scripting Help Needed
                          Cade Webb Wayfarer

                          The last code worked and gave a popup!  Thank you for all of your help. 

                           

                          If I want to add 8 characters to the string after the "-", Would it look like

                           

                          String.Left(sQueueName,iParsePos + 8)

                           

                          Thanks,

                           

                          Cade

                          • Re: Pharos Scripting Help Needed
                            Cade Webb Wayfarer

                            Everything works.  Thank you!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

                            • Re: Pharos Scripting Help Needed
                              Daniel Johns Tracker

                              In case any of you were wondering what was the exact reason why the earlier attempts didn't work, it was a misunderstanding about String.Left.  You were trying to use it as an expression, expecting the result to be the characters at the left of the string.  To quote what the Help says about it:

                               

                              Left(string_name, num_int);

                              // truncates string variable string_name to leave only its leftmost

                              // num_int characters remaining (no return value)

                               

                              This function modifies a variable; it doesn't return a value.  Consequently, using it on the right of an "=" or as a parameter did not give the intended result.

                              1 of 1 people found this helpful