1

I have this function within a Python script that has been installed as a windows service with NSSM. When the Python script is run normally (i.e. not as a service), the file is printed. However, when it is installed as a service it does not print.

The print command is externally triggered over opc-ua from another device.

Is it even possible to print while the script is installed as a service? While installed as a service, I don't get any exceptions either. Sometimes I got KeyboardInterrupt exception while sleeping between loops.

Is there another way to print a file triggered externally over opc-ua?

I know I could for example create 20 different triggers in Windows task scheluler, that thus would be executed every 5 seconds and check the opc-ua variable. This seems like a very tedious process

Here is a section of my Python script:

def CheckOpcuaNode(latestPDF):
    client = Client("opc.tcp://192.168.202.90:4840/")
    try:
        client.connect()
        opcuaNode = client.get_node("ns=6;s=::AsGlobalPV:g_saveParameters.bPrintNow")
        Result = opcuaNode.get_value() 
        if Result == True:
             print("print file: %s" % str(latestPDF))
             os.startfile(latestPDF, "print")
             try:
                time.sleep(4)
             except KeyboardInterrupt:  # Ignore keyborditerruption
                print("ERROR KeyboardInterrupt while printing: %s" % sys.exc_info()[0])
             opcuaNode.set_attribute(ua.AttributeIds.Value, ua.DataValue(False))
    except:
            print("ERROR while checking if PDF shall be printed: %s" % sys.exc_info()[0])
    finally:
        client.disconnect()

def LatestPdf():
    return 'path\to\PDF\file.pdf'

if __name__ == '__main__':
while True:
    latestPdfFile = LatestPdf()
    if latestPdfFile != '':
        CheckOpcuaNode(latestPdfFile) # check If PLC has asked to print pdf file
    try:
        time.sleep(4)
    except KeyboardInterrupt:  # Ignore keyborditerruption
        print("ERROR KeyboardInterrupt between loops: %s" % sys.exc_info()[0])
5
  • What program is your script actually using to print the pdf? The problem may well be that that program needs an interactive session (for whatever reason) and doesn't expect to not have one.
    – Mokubai
    May 7, 2020 at 7:23
  • the machines default PDF reader is adobe acrobat. So os.startfile(latestPDF, "print") opened adobe acrobat and prints the file (at least when the script is executed regularly i.e. not as a service) May 7, 2020 at 7:25
  • @Furty I not sure I understood your question? Did you mean what kind of printer? Well on the machine that shall run this service in the end, a network printer is set as the default printer. Now that you mentioned it, on my current machine, I don't have any other printers available than print to PDF, so that might be a problem here since it expects input of user to specify a location to save the file. The service is installed so it runs as local system account. May 7, 2020 at 7:31
  • @Furty "accept the EULA"... Isn't that accepted when adobe acrobat was installed. However, the local system account does not have admin rights. When installing Adobe acrobat, I had to give admin credentials. May 7, 2020 at 7:36
  • Yes, printing can be enabled in services. No, you really shouldn’t. Printing is rather involved on Windows.
    – Daniel B
    May 7, 2020 at 8:36

2 Answers 2

0

Acrobat opening a window and then proceeding to print the file is your problem.

Services generally do not have access to a graphical environment. They are typically "non-interactive".

You might want to find a command line PDF printing tool or print directly from your Python script. Programming questions are off topic here so I cannot address that particular side of the problem (it belongs at Stack Overflow).

0
  1. run the service under a regular user account
  2. login under that user acccount to open Adobe Reader and accept EULA (needs to be done for each user) and connect the network printer (not possible with "local system account") plus make it the default

Troubleshooting: in your script call "wmic printer list brief >> c:\serviceprinters.txt" to see if the user profile loaded correctly / network printer is available

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .