Jump to content
AmatrTatooArtst

Finding and Stopping Services

Recommended Posts

New to the forums, and to AutoIT guys.  I've been racking my brains searching through the forums for days on how I can do this and I'm coming up snake eyes.  here's my scenario

 

I need to write a script that searches for service "DataCommSvc"

If that service does not exist, it just continues on with the rest of the script

If the service exists but is not running, it just continues on with the rest of the script

If the service exists and is running, it needs to stop the service and place some kind of marker so that when the rest of the script is finished running it starts the service back up.

The best case scenario would be to be able to do this without running as admin.  I know that if I have to stop the service it has to be run as admin, but if I can get away with only running as admin in that one specific scenario where the service is running that would make things much easier.

 

Thanks in advance

Share this post


Link to post
Share on other sites

Hello there try to search in the forum before ask ;) (No offence of course but i found few so easy.) 

etc. 

 

About your admin problem. you can use Sheduled task to give admin rights to your *.exe compiled script. And give the rights one time to the task. 

 

If i 'm not false, there is no other way possible from my knowledge. 


My video tutorials : HERE ( In construction )  || My Discord : https://discord.gg/S9AnwHw

How to Ask Help ||  UIAutomation From Junkew || WebDriver From Danp2 || And Water's UDFs in the Quote

Spoiler

 Water's UDFs:
Active Directory (NEW 2018-10-19 - Version 1.4.10.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-10-31 - Version 1.3.4.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
 
Tutorials:

ADO - Wiki

 

Share this post


Link to post
Share on other sites

I have seen those, I can start and stop the services, my bigger issue is I want it to search to see if the service exists and is running first.  If not then it continues with the script.  If it is, I need it to set a marker of some sort so it can start the service back up when its complete.

Share this post


Link to post
Share on other sites

Here's my code, my thinking is that I can take the $status variable and create an if statement following to continue on with the code or stop the service as needed, and I can then create another if statement at the end based on the same value to start the service.  I can't get it to work though, the code came from another post and modified for what I am trying to do.  I'm using the messagebox just to try to see what kind of an output I'm getting from $Status but it errors out saying that $Status is not declared.  I'm probably making this way more complicated than it has to, trying to learn all this on the fly as I write and its pretty overwhelming.

 

$servicename = 'DataCommSvc'

$stdout = Run('sc.exe query ' & $servicename, '', @SW_HIDE, 2)
$data = _StdOut($stdout)

Func _StdOut($stdout)
    Local $data
    Local $Status
    While 1
        $data = StdOutRead($stdout)
        If @error Then $Status = 'Error'
        If $data Then
            $data = StringStripWS($data, 4)
            Select
                Case StringInStr($data, 'STATE : 1')
                    $Status = 'Stopped'
                Case StringInStr($data, 'STATE : 4')
                    $Status = 'Running'
                Case Else
                    $Status = 'Not Installed'
            EndSelect
        Else
            Sleep(100)
        EndIf
    WEnd
EndFunc

MsgBox(0, 'Service Status', $Status)

Share this post


Link to post
Share on other sites
Posted (edited)

here a cleaner way to interrogate the services :

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $iStatus = _CheckService("DataCommSvc")
MsgBox ($MB_SYSTEMMODAL,"",$iStatus)

Func _CheckService($s_ServiceName)

  Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
  Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
  If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
  If Not $colItems.count Then Return 0 ; Service not found
  For $oItem In $colItems
    If $oItem.State = "Running" then Return 1
    If $oItem.State = "Stopped" then Return 2
    If $oItem.State = "Not Installed" then Return 3
  Next

EndFunc   ;==>_CheckService

ps. when you post code, use <> before emoticon

Edited by Nine

Share this post


Link to post
Share on other sites
Posted (edited)

That's awesome Nine, I was able to modify that into the following

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $sStatus
Local $iStatus = _CheckService("DataCommSvc")
MsgBox ($MB_SYSTEMMODAL,"",$iStatus)

Func _CheckService($s_ServiceName)


  Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
  Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
  If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
    If Not $colItems.count Then Return 0 ; Service not found
    For $oItem In $colItems
      If $oItem.State = "Running" then $sStatus = 1
      If $oItem.State = "Stopped" then $sStatus = 2
      If $oItem.State = "Not Installed" Then $sStatus = 3
    Next

    If $sStatus = "1" Then
           Run(@ComSpec & " /c " & 'net stop DataCommSvc', "", @SW_HIDE)
        EndIf


EndFunc   ;==>_CheckService

This is working, if the service is running it will kill it.  The issue I have now is that no matter what state the service is in, I get a message box containing a 0.  I tried removing the following line of code

If Not $colItems.count Then Return 0 ; Service not found

but it still persists.  Any help to let me know what is causing this msgbox?

Edited by AmatrTatooArtst

Share this post


Link to post
Share on other sites

Nevermind, I found it.  Thanks for all the help.  I'm so close to having this project done, one more hurdle to get over.  I'm really liking AutoIT, between the help and the forums the support is phenomenal.  Thanks again.

Share this post


Link to post
Share on other sites

I made the changes you suggested, and I also added in a do until so that it keeps checking to make sure the service is closed before continuing.  It's telling me that the Do has no qualifying Until.  Any suggestions?

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $sStatus
Local $iStatus = _CheckService("DataCommSvc")

Do
   Func _CheckService($s_ServiceName)
     Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
     Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
     If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
       For $oItem In $colItems
         If $oItem.State = "Running" then $sStatus = 1
         If $oItem.State = "Stopped" then $sStatus = 2
         If $oItem.State = "Not Installed" Then $sStatus = 3
       Next

   If $sStatus = "1" Then
              Run(@ComSpec & " /c " & 'net stop DataCommsvc', "", @SW_HIDE)
           ElseIf $sStatus = "2" Then
              MsgBox($MB_Systemmodal, "DataCommSvc", "Service Stopped")
   EndIf
   Sleep(2000)
   EndFunc;==>_CheckService
Until $sStatus = "2"

 

Share this post


Link to post
Share on other sites

You can't put a function inside another function.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites
Posted (edited)

Not the right way to do it, you should not embed functions into any main script code, here what you should do :

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $sStatus, $Count = 0

$sStatus = _CheckService("DataCommSvc")
If $sStatus = 2 Then Exit MsgBox($MB_Systemmodal, "DataCommSvc", "Service already Stopped")
If $sStatus = 0 Or $sStatus = 3 Then Exit MsgBox($MB_Systemmodal, "DataCommSvc", "Service not installed")
; Status is necessarly 2
Run(@ComSpec & " /c " & 'net stop DataCommsvc', "", @SW_HIDE)
Do
    Sleep(500)
    $Count += 1
    If $Count > 40 Then Exit MsgBox($MB_Systemmodal, "DataCommSvc", "Unable to Stop Service")
Until _CheckService("DataCommSvc") = 2

MsgBox($MB_Systemmodal, "DataCommSvc", "Service has been Stopped")

Func _CheckService($s_ServiceName)
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
    If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
    If Not $colItems.count Then Return 0 ; Service not found
    For $oItem In $colItems
        If $oItem.State = "Running" Then Return 1
        If $oItem.State = "Stopped" Then Return 2
        If $oItem.State = "Not Installed" Then Return 3
    Next

EndFunc   ;==>_CheckService

 

Edited by Nine

Share this post


Link to post
Share on other sites

When I first tried to run this it said there was an undeclared variable, When I added this line back in it fixed that issue

Local $iStatus = _CheckService($Service)

Now when I run the code, regardless of what state the service is in, it always returns 0 - Service not Installed

I added another variable in for the service name so it only has to be changed once

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $Service = "DataCommSvc"
Local $sStatus, $Count = 0
Local $iStatus = _CheckService($Service)

$iStatus = _CheckService($Service)
If $sStatus = 2 Then Exit MsgBox($MB_Systemmodal, $Service, "Service already Stopped")
If $sStatus = 0 Or $sStatus = 3 Then Exit MsgBox($MB_Systemmodal, $Service, "Service not installed")
; Status is necessarly 2
Run(@ComSpec & " /c " & 'net stop ' & $Service, "", @SW_HIDE)
Do
    Sleep(500)
    $Count += 1
    If $Count > 40 Then Exit MsgBox($MB_Systemmodal, $Service, "Unable to Stop Service")
Until _CheckService($Service) = 2

MsgBox($MB_Systemmodal, $Service, "Service has been Stopped")

Func _CheckService($s_ServiceName)
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
    If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
    If Not $colItems.count Then Return 0 ; Service not found
    For $oItem In $colItems
        If $oItem.State = "Running" Then Return 1
        If $oItem.State = "Stopped" Then Return 2
        If $oItem.State = "Not Installed" Then Return 3
    Next

EndFunc   ;==>_CheckService

If I Just check the output without the count and send that to a message box it returns a 1 showing the proper status of running

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Local $Service = "DataCommSvc"
Local $sStatus
Local $iStatus = _CheckService($Service)

$iStatus = _CheckService($Service)
MsgBox($MB_Systemmodal, $Service, $iStatus)

Func _CheckService($s_ServiceName)
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
    If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
    If Not $colItems.count Then Return 0 ; Service not found
    For $oItem In $colItems
        If $oItem.State = "Running" Then Return 1
        If $oItem.State = "Stopped" Then Return 2
        If $oItem.State = "Not Installed" Then Return 3
    Next

EndFunc   ;==>_CheckService

 

Share this post


Link to post
Share on other sites
Posted (edited)

That Worked.  I made some changes because it is part of a larger code.  I removed the Exits from the status being stopped or not installed so it would continue the rest of the operation.  I then nested the do until and the message "service has been stopped" so that it only runs if the status is running.  I have tested it and it works, but I was hoping one of you could take a look at it to see if everything looks like good coding practices or if I could do something better.  Thanks a ton for everything, I've been working on this project for a week and I think it's finally completed!!

;==>Check if DataCommSvc Service is running
Opt("MustDeclareVars", 1)

Local $Service = "DataCommSvc"
Local $sStatus, $Count = 0

$sStatus = _CheckService($Service)
If $sStatus = 2 Then MsgBox($MB_Systemmodal, $Service, "Service already Stopped")
If $sStatus = 0 Or $sStatus = 3 Then MsgBox($MB_Systemmodal, $Service, "Service not installed")
;==>Status is necessarly 2
If $sStatus = 1 Then
Do
   Run(@ComSpec & " /c " & 'net stop ' & $Service, "", @SW_HIDE)
    Sleep(500)
    $Count += 1
    If $Count > 40 Then Exit MsgBox($MB_Systemmodal, $Service, "Unable to Stop Service")
Until _CheckService($Service) = 2

MsgBox($MB_Systemmodal, $Service, "Service has been Stopped")
EndIf

Func _CheckService($s_ServiceName)
    Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2")
    Local $colItems = $objWMIService.ExecQuery('SELECT * FROM Win32_Service WHERE Name = "' & $s_ServiceName & '"')
    If Not IsObj($colItems) Then Exit MsgBox(0, "", "Not an object")
    If Not $colItems.count Then Return 0 ; Service not found
    For $oItem In $colItems
        If $oItem.State = "Running" Then Return 1
        If $oItem.State = "Stopped" Then Return 2
        If $oItem.State = "Not Installed" Then Return 3
    Next

EndFunc   ;==>_CheckService

 

Edited by AmatrTatooArtst

Share this post


Link to post
Share on other sites
44 minutes ago, AmatrTatooArtst said:

see if everything looks like good coding practices

Don't declare all of your variables using Local, unless they are inside of a function. Using Local in the global scope (outside of a function) isn't the correct method, use Global in the global scope, and Local in the functions.

You could also rewrite the section that checks the return status message like this.

 

$sStatus = _CheckService($Service)
Switch $sStatus
     Case 2
          MsgBox($MB_Systemmodal, $Service, "Service already Stopped")
     Case 0, 3
          MsgBox($MB_Systemmodal, $Service, "Service not installed")
          ;==>Status is necessarly 2
     Case 1
          Do
               Run(@ComSpec & " /c " & 'net stop ' & $Service, "", @SW_HIDE)
               Sleep(500)
               $Count += 1
               If $Count > 40 Then Exit MsgBox($MB_Systemmodal, $Service, "Unable to Stop Service")
          Until _CheckService($Service) = 2
          MsgBox($MB_Systemmodal, $Service, "Service has been Stopped")
EndSwitch

Makes it a little easier to follow when you might have to look at this later.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...