1

I am trying to create a program that lists and saves all running services on my Windows machine to a txt file. I got it to work but it is not listing line by line like in my output in the Python shell. Also, there are added parenthesis I do not want. See output vs txt file screenshot below. Also, my code is below.

Output vs txt file

My Code so far:

import win32con
import win32service

#Define ListServices class
def ListServices():
    resume = 0
    accessSCM = win32con.GENERIC_READ
    accessSrv = win32service.SC_MANAGER_ALL_ACCESS

    #Open Service Control Manager
    hscm = win32service.OpenSCManager(None, None, accessSCM)

    #Enumerate Service Control Manager DB
    typeFilter = win32service.SERVICE_WIN32
    stateFilter = win32service.SERVICE_ACTIVE

    statuses = win32service.EnumServicesStatus(hscm, typeFilter, stateFilter)

    for (short_name, desc, status) in statuses:
        #Save output to txt file
        f=open('MyServices.txt', 'w')
        f.write(str(statuses))
        f.close()
        #Print output and append 'Running' at the end of each line
        print(desc, status, '----------> Running') 

ListServices();
Mureinik
  • 297,002
  • 52
  • 306
  • 350
WxRob87
  • 55
  • 1
  • 4
  • 1
    The `print` function will add a new line. But `f.write` does not add a new line. You'll need to add it yourself. See this answer: https://stackoverflow.com/questions/6159900/correct-way-to-write-line-to-file – Gohn67 Sep 15 '18 at 16:32
  • I tried adding this in place of the old write command: f.write(statuses + os.linesep) .... but that is giving me a "Traceback (most recent call last): File "C:\Users\Rob\AppData\Local\Programs\Python\Python37\test4.py", line 28, in ListServices(); File "C:\Users\Rob\AppData\Local\Programs\Python\Python37\test4.py", line 23, in ListServices f.write(statuses + os.linesep) TypeError: can only concatenate tuple (not "str") to tuple" error. Any help would be much appreciated as I'm not to great with programming. – WxRob87 Sep 15 '18 at 16:40
  • I think there's a bug in your code. I think you mean to use `status`? `statuses` is a tuple it appears. – Gohn67 Sep 15 '18 at 16:44
  • If you did want to use `statuses`, I guess you need to do `f.write(str(statuses) + os.linesep)`. Ie. convert the statuses tuple to a string first like you do in the code you posted. – Gohn67 Sep 15 '18 at 16:46
  • Thanks for your help! – WxRob87 Sep 15 '18 at 17:09

4 Answers4

1

write doesn't append a newline like print does, so you should take care of it yourself. Also, note that there's no reason to open and close the file on each iteration. Just leave it open as long as you need it:

with open('MyServices.txt', 'w') as f:
    for (short_name, desc, status) in statuses:
        f.write(str(statuses))
        f.write(os.linesep)
        #Print output and append 'Running' at the end of each line
        print(desc, status, '----------> Running') 
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • I replaced the code starting with 'for' on my last statement and replaced with your but got an error: Traceback (most recent call last): File "C:/Users/Rob/AppData/Local/Programs/Python/Python37/test5.py", line 26, in ListServices(); File "C:/Users/Rob/AppData/Local/Programs/Python/Python37/test5.py", line 22, in ListServices f.write(os.linesep) NameError: name 'os' is not defined – WxRob87 Sep 15 '18 at 16:49
  • 1
    @WxRob87 you need to add `import os` to your imports. – Mureinik Sep 15 '18 at 16:50
  • Okay so I added import os and the error is gone. However, the txt file still looks sloppy like my above screenshot. – WxRob87 Sep 15 '18 at 16:51
  • I figured it out. See below for what did the trick. You were the key to me figuring it out. Thanks a ton! – WxRob87 Sep 15 '18 at 16:58
1

Thanks for all your help guys!

This is what did the trick:

    with open('MyServices.txt', 'w') as f:
        for (short_name, desc, status) in statuses:
            f.write(str(desc))
            f.write(str(status))
            f.write('----------> Running')
            f.write(os.linesep)
            #Print output and append 'Running' at the end of each line
            print(desc, status, '----------> Running') 
WxRob87
  • 55
  • 1
  • 4
0

You need to add a newline character at the end of your string, like this:

f.write(str(statuses)+"\n")
bunbun
  • 2,595
  • 3
  • 34
  • 52
  • 1
    if `statuses` is the sort of object which can be added to `"\n"` it probably doesn't need the `str` call. OTOH, if it isn't, then this will fail, because we're doing the concatenation _before_ we convert to str. – DSM Sep 15 '18 at 16:39
  • Yes, it failed because of that. I will try removing str. – WxRob87 Sep 15 '18 at 16:44
  • ah yes, slight error, the \n should be after converting statuses to str. – bunbun Sep 16 '18 at 07:17
0

You have a few issues here.

First, you're overwriting your MyServices.text file each time in the loop. So you should open your file outside the loop.

Second, you are writing the statuses tuple in your code. Instead you should write out the individual line like you do in print

Third, f.write does not add a new line like print does. So you need to manually add a new line in your write function.

# Open MyServices.txt outside loop so you don't overwrite the file on each iteration
with open('MyServices.txt', 'w') as f:    
    for (short_name, desc, status) in statuses:
         # Write each status line individually and manually add a newline to the output.
         f.write("{}, {}, {}\n".format(short_name, desc, status))
         print(desc, status, '----------> Running') 
Gohn67
  • 10,608
  • 2
  • 29
  • 35