1

I am trying to create an .exe file that would be called repeatedly by windows to kill a certain process in case it is running too long (it is stuck). I want it to be general, so it requires three command line parameters: number of minutes (as a criteria for the process to be shut down), name of the owner of the process and exact name of the process.

I am writing in python-3.11 in vc code, using wmi library to access the information about the process. For creating the .exe file I use pyinstaller.

The program and also the .exe called from a terminal works as expected on my computer, but when my colege tries to run it it does not work. My colege does not have python on his machine and I want it to be running on machine without python installed.

The original code is following:

# Command line parameters: num_of_minutes user_name process_name

import sys
import wmi
from datetime import datetime
from datetime import timedelta

# Controll and taking arguments, if they are wrong or missing, the program ends
if len(sys.argv)<4:
    print('Wrong number of arguments, expecting parameters number_of_minutes owner process_name')
    sys.exit()
else:
    try:
        in_num_of_minutes = int(sys.argv[1])
        in_user_name = str(sys.argv[2])
        in_process_name = str(sys.argv[3])
    except:
        print('Program has difficulties reading the arguments, expecting parameters number_of_minutes owner process_name')
        sys.exit()

# Initialize wmi connection
c = wmi.WMI()

# Go through all running processes
for process in c.Win32_Process():
    # print(f' {process.ProcessId:<10} {process.Name} {process.GetOwner()}')
    if (process.Name == in_process_name) and (in_user_name in process.GetOwner()):
        created = process.CreationDate.split('.')[0]                                 # When was it created, it is in a weard format
        how_long_dt = datetime.now() - datetime.strptime(created, '%Y%m%d%H%M%S')    # How long has it been running, datetime format
        minutes = how_long_dt.total_seconds()/60                                     # Kolik minut běží
        # print(minutes)
        if minutes>in_num_of_minutes:
            print(f'Closing process with ID {process.ProcessId} and name {process.Name} run by {process.GetOwner()[2]}, that was running for {round(minutes,4)} minutes.')
            process.Terminate() # Shout down the process

I created an .exe file using the following command in the terminal:

pyinstaller --onefile ShutDownProcess.py

After that I tried to run this on my computer and shut down notepad running under my account. It works. I also tried to enter wrong number of arguments or string instead of a number for the first argument, it prints the messages and ends the process as expected.

Then I gave the .exe to my colegue, who tried to run it on his machine. The program with correct parameters runs for a while and then ends with no output, action or exception.

I tried uncommenting the printing of the processes that the program runs through to find out if the wmi is working. I created new .exe file. It also runs on my computer. On my colegues computer it lists running processes and either ends or throws exceptions without shouting the program it is supposed to shout. I am confused by this behaviour. I thought the problem might be in the wmi package, but the wmi connection is working for some time, so it is accesible (included in the .exe), but then it sends exceptions and ends the process. It seems to me that there are two problems. One is that printing the process information runs into some trouble. Other one is that the program doesn'n execute the if cycle that is supposed to terminate the process. The exception text is following:

Traceback (most recent call last):
    File "wmi.py", line 458, in __call__
    File "<COMObject <unknown>>", line 2, in ExecMthod_
pywintypes.com_error: (-2147352567, 'Exception occured.', (0, 'SWbemObjectEx', 'Not found', None, 0, -2147217406), None)


During handling of the above exception, another exception occured:

Traceback (most recent call last):
    File "ShutDownTheProcess.py", line 27, in <module>
    File "wmi.py", line 473, in __call__
    File "wmi.py", line 258, in handle_com_error
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147352567, 'Exception occured.', (0, 'SWbemObjectEx', 'Not found', None, 0, -2147217406), None)>
[20212] Failed to execute script 'ShutDownProcess' due to unhandled exception!

I do not quite understand what this log means, I tried to search for the corresponding lines in the wmi.py, but I do not get what is happening there.

Then I thied to make another .exe, where the terminate command is commented, so it only prints the processes. I behaves on my colegues computer the same way as previous .exe.

Last attempt was to change the process.Terminate() command to

killing_command = 'taskkill /pid ' + str(process.ProcessId)
os.system(killing_command)

This still behaves as the previous .exe (with printing). Works on my computer, doesn't work on colegues.

I am out of ideas and still do not know what I am doing wrong. I would appretiate some adwice.

  • One note, I tried to modify the code to use **psutil** instead of **wmi** library and that helped to produce working exe using pyinstaller. Therefore I assume that the roots of the problem are in the **wmi** library and not in pyinstaller. – Andy Kučerová Apr 28 '23 at 07:53

0 Answers0