List network printers with PHP

Asked

Viewed 1,850 times

3

I need all printers on the network to be listed in my application for configuration purposes, but so far I’m finding it difficult to do. At first 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 was unable to list the printers that are shared on the network.

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

In principle the printers should be listed in a list (select/option component - HTML) dynamically (preferably in order to detect any change in the network/printers) each time one enters the corresponding screen for the settings. Each printer belongs to a sector and on this screen each printer is configured for each sector. It is not prerequisite that it is Windows the server, it can be Linux, for example, where in the case under Linux until then I have not found anything regarding listing of the installed printers even if it is local.

Obs: The reason for choosing Windows was the fact that before I searched on Linux and found no solution. Under Linux it is possible to list printers installed on the server locally or on the network?

  • I don’t know what information is needed, if the server is windows it wouldn’t be easier to get the information via powershell or wmi and save it in a 'temporario' database that php would access?

  • Remember, only printers "available" to the S.O. where PHP is running that can be listed this way.

  • Yes, there are the appropriate settings in S.O so that it accesses the printers, and then it was tested with "test page" of the S.O. itself (in the case of Windows, but I am willing to Linux, if I find the solution in it).

1 answer

2


The printer will only appear if it is configured on the server, I don’t know about printers 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 the printers connected to the server. But it will not identify network printers that are not configured on the server because 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 (e.g. 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 setting does not work, you can try PHP-Printer () https://github.com/jiminald/PHP-Printer But apparently this extension has been discontinued (not even the documentation is available: http://php.net/manual-lookup.php?pattern=printer&scope=quickref).

Getting printers without extension, using command line only in windows:

When PHP alone cannot, 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 is to use a command line and handle 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 is 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 allows you to run via command line, such as 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.'"');
  • Thank you for your answer. I’ll do the tests. You had mentioned that in Linux the solution is similar. What in specific would have to be changed if it was on Linux, because the reason for choosing Windows was the fact that before I searched on Linux and I did not find any solution.

  • Under Linux, it is possible to list printers installed on the server locally or on a network?

  • 1

    When you say it’s similar, it’s because of the technique, you use an operating system command and treat it in php. The commands that allow finding a printer on linux is lpstat -d -p, but I have no machine to test the output and mount a script. To discover printers on the network not installed you can still use nmap -A on linux but need to filter as it will detect all the devices visible on the network.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.