0

I'm having trouble determining the status of a Windows program (KeePass) opened by the Python subprocess module. Calling the KeePass program is straightforward, but once called, I can't seem to determine if it has been successfully opened or not.

I read up on the Popen.poll(), Popen.wait() and Popen.communicate() objects and tested them out, but I can't seem to find a status to hook into.

Example: (see # <--- What goes here to check status? comment below)

import subprocess as s
import os.path


keepass_app = 'C:\Program Files\KeePass Password Safe 2\KeePass.exe'
keepass_db = 'E:\Documents\test.kdbx'
pw_file = 'E:\\Documents\\test.md'


def check_each_pw(pw_file):
    
    for pw in pw_file:
        
        t = s.Popen([keepass_app, keepass_db, f'-pw:{pw}'], stdin=s.PIPE, stdout=s.PIPE, stderr=s.PIPE)
        
        if  : # <--- What goes here to check status?

            print(f'{pw} is not a valid password')
            t.terminate()

        else:
            print(f'{pw} is the correct password!')
            t.terminate()


check_each_pw(pw_file)

EDIT1:

Inserting into the above code, output, errors = t.communicate(), results in the same b'' b'' for both output and error values.

        t = s.Popen([keepass_app, keepass_db, f'-pw:{pw}'], stdin=s.PIPE, stdout=s.PIPE, stderr=s.PIPE)
        
        output, errors = t.communicate()
        
        if errors == b'':
            print(f'{pw} is the correct password!')
            print(output, errors)
            t.terminate()

        else:
            print(f'{pw} is not a valid password.!')
            print(output, errors)
            t.terminate()

Results: The first line of pw_file is the wrong password. The KeePass database does not open; GUI shows the pop up:

enter image description here

...requiring manual intervention to close. The second line of pw_file is the correct password. KeePass opens successfully. But you can see that the terminal output for t.communicate() is the same for both attempts. Nothing to hook into.

PS E:\Documents\python\pw_program> python .\pw_prog.py
abc is the correct password!
b'' b''
test is the correct password!
b'' b''

Same thing goes for t.wait() (0 instead of b'' value, nothing to hook into):

        t = s.Popen([keepass_app, keepass_db, f'-pw:{pw}'], stdin=s.PIPE, stdout=s.PIPE, stderr=s.PIPE)
        
        errors = t.wait()
        
        if errors == 0:
            print(f'{pw} is the correct password!')
            print(errors)
            t.terminate()

        else:
            print(f'{pw} is not a valid password.')
            print(errors)
            t.terminate()
PS E:\Documents\python\pw_program> python .\pw_prog.py
abc is the correct password!
0
test is the correct password!
0

And same thing goes for t.poll():

        t = s.Popen([keepass_app, keepass_db, f'-pw:{pw}'], stdin=s.PIPE, stdout=s.PIPE, stderr=s.PIPE)
        
        errors = t.poll()
        
        if errors is None:
            print(f'{pw} is the correct password!')
            print(errors)
            t.terminate()

        else:
            print(f'{pw} is not a valid password.')
            print(errors)
            t.terminate()
PS E:\Documents\python\pw_program> python .\pw_prog.py
abc is the correct password!
None
test is the correct password!
None

I also tried substituting s.check_call and s.check_output, no-go!

SeaDude
  • 3,725
  • 6
  • 31
  • 68

1 Answers1

2

use

output, errors = t.communicate()

To get logs in variables. Output will show the output logs and errors will show the error in case of crash.

You can also use t.wait() it will wait for the process to terminate and will return 0 in case of successful execution. In case of crash it will value other than 0.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Usama Tariq
  • 169
  • 5
  • I'm afraid this doesn't work for KeePass (or I'm not sure how to correctly implement it!). See **EDIT1** in op. – SeaDude Nov 09 '21 at 19:06