List printers on the network with PHP

Question:

I need all the printers on the network to be listed in my application for its configuration purposes, but so far I'm having difficulties to do so. In principle I'm using Windows on the application server, but I think about using Linux over time. I did tests with php_printer.dll (Windows only), but I couldn't make a list of printers that are shared on the network.

For printing I use the component https://github.com/mike42/escpos-php but unfortunately with it I was also unable to list which printers are on the network. My client already has the Epson brand printers installed with an old application, where we are making a new system to replace the old one.

In principle, printers must be listed in a list (component select/option – HTML) dynamically (preferably, in order to detect any changes in the network/printers) every time you enter the screen referring to the appropriate settings. Each printer belongs to a sector and on this screen each printer is configured for each sector. It is not a prerequisite that the server is Windows, it can be Linux, for example, where in the case under Linux so far I have not found anything regarding the list of installed printers, even if it is local.

Note: The reason for choosing Windows was the fact that before I searched for Linux and didn't find any solution. In Linux is it possible to list the printers installed on the server locally or on a network?

Answer:

The printer will only appear if it is configured on the server, I don't know about printer discovery using php alone (maybe some operating system command).

As you are using windows, I will consider this environment, in linux the solution is similar.

Using the php_printer extension:

The php_printer extension is the standard way to get printers connected to the server. However, it will not identify network printers that are not configured on the server as it does not allow discovery.

I did the installation once following this tutorial (in English) :

http://basic-programming-tips.blogspot.ch/2013/07/php-phpprinterdll-installation-and.html

Go to the php.ini file directory (eg C:/PHP5/php.ini)

  1. open the file

  2. Search for ;extension=php_printer.dll

  3. Remove the ";"

  4. Restart the server.

If the above configuration doesn't work, you can try PHP-Printer https://github.com/jiminald/PHP-Printer But apparently this extension has been discontinued (not even documentation is available: http://php .net/manual-lookup.php?pattern=printer&scope=quickref ).

Getting printers without the extension, using just the command line in windows:

When PHP alone can't, we can use some command line interface, be it a java or python script or even a php script running with an older php. The technique consists of using a command line and treating the result string.

<?php
//Função para tratar o retorno 
function getPrinterProperty($key){
    $str = shell_exec('wmic printer get '.$key.' /value');

    $keyname = "$key=";
    $validValues = [];
    $fragments = explode(PHP_EOL,$str);
    foreach($fragments as $fragment){
        if($fragment == ""){
            continue;
        }
        if (preg_match('/('.$keyname.')/i', $fragment)) {
            array_push($validValues,str_replace($keyname,"",$fragment));
        }
    }
    return $validValues;
}
//Esplanação dos commandos:
// wmic /node:SERVER1 printer list status // Lista status das impressoras de um servidor remoto
// wmic printer list status // Lista status das impressoras  do servidor local
// wmic printer get // Obtem todas as propriedades da impressoa
// wmic printer get <propriedade> /value //Lista uma propriedade no formato chave=valor do servidor remoto
// wmic printer get <propriedade> /value //Lista uma propriedade no formato chave=valor do servidor local

//Obtém algumas propriedades, nesse caso vou pegar só algumas
$Name = getPrinterProperty("Name");
$Description =  getPrinterProperty("Description");
$Network = getPrinterProperty("Network");
$Local = getPrinterProperty("Local");
$PortName = getPrinterProperty("PortName");
$Default = getPrinterProperty("Default");
$Comment = getPrinterProperty("Comment");

$Printers = [];
foreach($Name as $i => $n){
    $Printers[$i] = (object)[
        "name" => $n,
        "description" => $Description[$i],
        "Portname" => $PortName[$i],
        "isDefault" =>($Default[$i] == "TRUE")? true : false,
        "isNetwork" => ($Network[$i] == "TRUE")? true : false,
        "isLocal" =>($Local[$i] == "TRUE")? true : false,
        "Comment" => $Comment[$i],
    ];
}

var_dump($Printers);

The expected return goes something like this:

array(7) {
  [0]=>
  object(stdClass)#1 (7) {
    ["name"]=>
    string(29) "Microsoft XPS Document Writer"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(11) "PORTPROMPT:"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
  [1]=>
  object(stdClass)#2 (7) {
    ["name"]=>
    string(22) "Microsoft Print to PDF"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(11) "PORTPROMPT:"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
  [2]=>
  object(stdClass)#3 (7) {
    ["name"]=>
    string(32) "HPC4C962 (HP Officejet Pro 8600)"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(45) "WSD-5277c4df-fd03-46fb-a957-1d8a0fd65b01.003c"
    ["isDefault"]=>
    bool(true)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(30) "This is a web services printer"
  }
  [3]=>
  object(stdClass)#4 (7) {
    ["name"]=>
    string(29) "HP Officejet Pro L7600 Series"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(12) "192.168.1.22"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
  [4]=>
  object(stdClass)#5 (7) {
    ["name"]=>
    string(24) "Foxit Reader PDF Printer"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(13) "FOXIT_Reader:"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
  [5]=>
  object(stdClass)#6 (7) {
    ["name"]=>
    string(3) "Fax"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(7) "SHRFAX:"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
  [6]=>
  object(stdClass)#7 (7) {
    ["name"]=>
    string(26) "Enviar para o OneNote 2013"
    ["description"]=>
    string(0) ""
    ["Portname"]=>
    string(4) "nul:"
    ["isDefault"]=>
    bool(false)
    ["isNetwork"]=>
    bool(false)
    ["isLocal"]=>
    bool(true)
    ["Comment"]=>
    string(0) ""
  }
}

How to request a print without plugin (windows)?

You can install some application that lets you run it via the command line, like Foxit Reader , and add it to the PATH environment variable, so you can run the command from anywhere. So you can use the code up there and run it like this:

<?php 

shell_exec('FoxitReader /t C:/Temp/file.txt "'.$Printers[0]->name.'"');
Scroll to Top