Change default printer from CAL

A while ago Waldo has posted a way to print any document from CAL. Here he showed us how easy it is to print any document with any extension by simple using .NET.
Recently I used this to print merged PDF’s from CAL, but I ran into an issue.

I want to print this PDF’s on a certain printer.
Some products like Adobe cleams to support this by passing some parameters like:

AcroRd32.exe /t path “printername” “drivername” “portname”

But then you are related to specific software and what with the other extensions.
Do you realy want to create separate statements for every extension.
I don’t think so.

Thereby I search for a better way, and here it is.
Why don’t use .NET again to solve this issue.
Instead of passing the printer as a parameter, I will switch my default printer from CAL.

And this can be done with the following code.
First you need to declare some variables.

Where all the DotNet are running on client. You can choose to execute this on serverside so that the default printer of the service tier user will switch. This can be used if you want to print something in the background overnight for example.

And finally the code to switch the default printer.

In this code I’ll first check if the session can run DotNet. So for the webclient you need to use the server side printing.
Then I’ll search for all the installed printers.
And finally I’ll loop through the collection to find my requested printer.
When switching to the default printer you also want to know the current default printer. So that you can switch back after you print process.

To get the current default printer you need the following code.

Enjoy printing, but also think at the environment.
Only print if it is realy necessery and then think once more and mail the document?

6 thoughts on “Change default printer from CAL

  1. Hansen says:

    This was really informative. If we have use same code in Nav-2013 then how to replace foreach loop there ?

    Any ideas

    1. Punky says:

      Hello Hansen,

      instead of using the FOREACH you can use the FOR or WHILE statement with ManagementObjectCollection.Count.
      And loop through the records.

      Kind regards,

  2. Hansen says:

    Hi Punky

    Thanks for your quick feedback. I can use FOR or WHILE loop but I am facing an issue in fetching the objects from ManagemetObjectCollection

    Here is the code sample

    ManagementObjectCollection := ManagementObjectSearcher.Get();

    Count := ManagementObjectCollection.Count;

    varArray := varArray.CreateInstance(ManagementObjectCollection.GetType(), Count);

    where varArray is DotNet array of type => System.Array.’mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089′

    ManagementObjectCollection.CopyTo(varArray, 0);

    I get an error message that call is ambiguous between following methods i.e.
    => CopyTo(ManagementBaseObject[], int)
    =>CopyTo(System.Array, int)

    Can you tell me how to reterive the data from ManagementObjectCollection

  3. Hansen says:

    Hi Punky

    For NAV2013 I fixed it by using enumerator

    WITH ManagementObjectCollection DO BEGIN
    Enumerator := ManagementObjectCollection.GetEnumerator();
    WHILE(Enumerator.MoveNext()) DO
    ManagementObject := Enumerator.Current;
    PrinterNameTmp := FORMAT(ManagementObject.GetPropertyValue(‘Name’));

    IF PrinterNameTmp = PrinterName THEN BEGIN
    ManagementObject.InvokeMethod(‘SetDefaultPrinter’, ObjectArray);

Leave a Reply

Your email address will not be published. Required fields are marked *