The "Services" window enumerates all of the system services, but inspecting the properties of a given service doesn't show what is actually running behind the scenes.
Take, for example, the Apache2.4 service (shown in the image below), how can I see what executable is being run by this service and with what arguments?
Example from "Services" window
In the Command Prompt you can use the sc program with the qc command (query configuration) to get this information for any service.
For the example given,
> sc qc Apache2.4
will give you information about the service, one section of which is the BINARY_PATH_NAME which will detail the exact command (with arguments) run by the service.
Related
Lately I was having problem with WMI on one of the systems (win server 2019). Service list in Task Manager was empty and running Get-WmiObject Win32_Service from powershell was returning Generic failure. After fruitless hours of searching and trying to repair system I gave up and was ready to reinstall system. Then error was reproduced on another machine by accident and I was able to narrow down cause of the problem. After creating windows service with short name and short display name WMI brakes after system restart but only if that service is first (in alphanumeric order) on services list. To reproduce this effect you only need to run
sc create "A1" binpath="D:\foobar.exe" DisplayName="A1" start=disabled
binpath is irrelevant, service doesn't need to be started. DisplayName doesn't need to be identical to name. After that command you need to restart (before restart everything works). After that if you go to services list in task manager it will be empty (probably using WMI to query services list). Now you can run sc delete "A1" and reopen task manager. Everything is back to normal.
Problem was reproduced on Windows Server 2019 and Windows 10 (didn't tried on other versions).
Is this a known bug or what is happening here?
EDIT
I'm not asking about how to use sc. It's doesn't matter. I provided commands that someone can run to reproduce problem. You can create service with that parameters however you want.
You are using the sc command line arguments in the incorrect format.
From MSDN:
Optionvalue
Specifies the value for the parameter named by Optionname. See the Optionname reference for a list of supported values. When a string is to be input, the use of empty quotes means that an empty string is passed in. Note that there is a space between OptionValue and the equal sign.
The correct command should be:
sc create "A1" binpath= "D:\foobar.exe" DisplayName= "A1" start= disabled
I use sc.exe to stop/start services on a remote \server in a pre/post build batch. Unfortunately sc does not seem to deliver any information about the service being deactivated or not which leads to an accumulating timeout when using the sc start command on deactivated services. Does anyone know an alternative to check the deactivated state on a remote service in the command line?
This is what you are looking for..
How to test whether a service is running from the command line
look down for the WMI/WMIC options. You will need to modify the command line slightly to attach to a remote machine.
If you need to know the start mode property, add it to the command line like this:
wmic /locale:ms_409 service where (name="RemoteRegistry") get state, StartMode /Value
This produces:
StartMode=Disabled
State=Stopped
I am not marking as duplicate because your wording and needs are a little bit different.
I am having trouble when I have one Windows service try to install another Windows service.
Specifically, I have a TeamCity agent running tests for me on a Windows 2008 AWS instance. The tests are written in Java, which shell out to a .bat script to install a service (let's call it Service A), giving it a unique name each time.
The offending line is in the .bat script: sc create "%serviceName%" binPath= %binPath% DisplayName= "%serviceDisplayName:"=%" start= %serviceStartType%. I believe as long as the service name is unique that should work.
And indeed it does work if I run the tests manually on the command line, using an administrator account. Service A is installed, the test completes and Service A is uninstalled at the end.
I have tried running the TeamCity agent as LocalSystem, as Administrator, and as another user that is member of the administrators group. I have also tried disabling UAC completely.
Presumably the problem is access denied type errors, although that is not clear at this point. There are a few avenues to explore still, but it is a simple question really: are processes running as services forbidden from installing other services? Are there special things I have to do to configure the machine/ account to allow it to do this?
The point of the test it to install and use Service A, so workarounds are not relevant - Service A must be operated as a black box.
Thanks!
There are no restrictions on creating services with regards to how the creating process can execute, as long as the process has the appropriate permissions. That is to say, a process could be running as a service and create another service -- the only consideration here is the appropriate permission level.
The problem that often occurs with running batch scripts from within processes (as opposed to directly through user input on the command line) is that the environment expected isn't always the environment that is loaded. In this case, it appears that the env variables referred to in the batch script weren't properly set when running as a service, which of course then caused the service install failure. Correcting the environment loaded when the batch script is shelled out is the correct solution here.
We have a Windows Service application that can accept command line parameters like:
MyService -option
So far, when we want to start the service with a parameter, we either do it manually from the Service Properties dialog (in the Start parameters box) or with the command
sc start MyService -option
What we would like is a way to install the service "permanently" with this parameter, so that the users would just have to start/stop it without having to set the parameter each time.
BTW, adding the parameter in the ImagePath registry entry doesn't work, neither does installing like this:
MyService -option /install
Updated: Thank you for the answers so far which help me refine the question.
What I'd like to achieve is to set the parameter at the Service level itself (like with the properties) in case there are more than 1 service in the same executable. The binpath config option is merely updating the ImagePath entry in the registry. That cannot be service specific.
sc config MyService binPath= MyService.exe -option
Update
The individual service parameters are stored in the the registry at the key HKLM\SYSTEM\CurrentControlSet\Services\<serviceName>\Parameters. I'm not sure though how the parameters are passed to the service. I believe SCM reads these values then when it calls StartService it passes them to the ServiceMain callback.
How about putting the parameter in a config file?
According to the ServiceBase.OnStart documentation:
The arguments entered in the console are not saved; they are passed to the service on a one-time basis when the service is started from the control panel. Arguments that must be present when the service is automatically started can be placed in the ImagePath string value for the service's registry key (HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\). You can obtain the arguments from the registry using the GetCommandLineArgs method, for example: string[] imagePathArgs = Environment.GetCommandLineArgs();.
Arguments passed on the command-line via ImagePath are accessible in main() or via GetCommandLine(). You could install with command-line args and then in your ServiceMain, check to see if any arguments were passed in the lpszArgs parameter. If not, call GetCommandLine and see if any were passed that way.
Powershell can do this but you have to use .Net to achieve it.
new-Object System.ServiceProcess.ServiceController("$ServiceName",$ComputerName)).Start("$Parameter")
The only thing that worked for me was to add the parameter to the ImagePath on the registry like the following image :
If there is more than one service with the same executable then you would be installing them with different service names. You could refer to the service name instead of the parameters.
To get the service name you can use this
How can a Windows Service determine its ServiceName?
Use the SC (service control) command, it gives you a lot more options than just start & stop.
DESCRIPTION:
SC is a command line program used for communicating with the
NT Service Controller and services.
USAGE:
sc <server> [command] [service name] ...
The option <server> has the form "\\ServerName"
Further, help on commands can be obtained by typing: "sc [command]"
Commands:
query-----------Queries the status for a service, or
enumerates the status for types of services.
queryex---------Queries the extended status for a service, or
enumerates the status for types of services.
start-----------Starts a service.
pause-----------Sends a PAUSE control request to a service.
interrogate-----Sends an INTERROGATE control request to a service.
continue--------Sends a CONTINUE control request to a service.
stop------------Sends a STOP request to a service.
config----------Changes the configuration of a service (persistent).
description-----Changes the description of a service.
failure---------Changes the actions taken by a service upon failure.
qc--------------Queries the configuration information for a service.
qdescription----Queries the description for a service.
qfailure--------Queries the actions taken by a service upon failure.
delete----------Deletes a service (from the registry).
create----------Creates a service. (adds it to the registry).
control---------Sends a control to a service.
sdshow----------Displays a service's security descriptor.
sdset-----------Sets a service's security descriptor.
GetDisplayName--Gets the DisplayName for a service.
GetKeyName------Gets the ServiceKeyName for a service.
EnumDepend------Enumerates Service Dependencies.
The following commands don't require a service name:
sc <server> <command> <option>
boot------------(ok | bad) Indicates whether the last boot should
be saved as the last-known-good boot configuration
Lock------------Locks the Service Database
QueryLock-------Queries the LockStatus for the SCManager Database
EXAMPLE:
sc start MyService
I'm using an AutoIt script to start and automate a GUI application. I need to activate the script each hour.
Will AutoIt scripts (which perform actions on a GUI) work when used as a service? The script will be run as a service (not scheduled task).
You can easily make an autoit script run as a service using service.au3 written by archer of the autoit forums. Unfortunately or fortunately since it is a security measure. A service needs to start independent of the current user session (before login). It cant access send APIs for input manipulation of the current user session from there. It does sound much more like you need a scheduled task and not a service.
As mentioned above, a scheduled task is what you're looking for. To run a script as a service read this:
Q4. How can I run my script as a service?
This is also a question with multiple answers, and none of them are the only way to do it. The first question to ask yourself is whether or not you wish to install the service on other computers besides your own.
A1. If you only wish to install the service on your own computer, The easiest way to do this is to use Pirmasoft RunAsSvc. This program makes services easy to install and easy to remove when necessary.
A2. If you wish to make the service available to anyone running your script, you can use SRVANY.EXE and ServiceControl.au3. You can then use this code to install your script as a service:
#include "ServiceControl.au3"
$servicename = "MyServiceName"
_CreateService("", $servicename, "My AutoIt Script", "C:\Path_to_srvany.exe", "LocalSystem", "", 0x110)
RegWrite("HKLM\SYSTEM\CurrentControlSet\Services\" & $servicename & "\Parameters", "Application", "REG_SZ", #ScriptFullPath)
or use the following code to delete this service:
#include "ServiceControl.au3"
$servicename = "MyServiceName"
_DeleteService("", $servicename)
There is one caveat to setting up AutoIt as a service. If the service is not installed using the above code, it must have the "allow service to interact with the desktop" setting or else automation functions such as Control* or Win* functions will not function. To assure the service does indeed have this setting, use the following code:
RegWrite("HKLM\SYSTEM\CurrentControlSet\Services[ServiceName]", "Type", "REG_DWORD", 0x110)
Taken from the FAQ topic on the AutoIt Forums. www.autoitscript.com/forum/index.php?showtopic=37289)
It sounds like you're want to use a scheduled task instead of a service. Scheduled tasks can execute every hour, while you're logged in, and should also be able to interact with your desktop. Just remember that a task run as a normal user can not interact (send input) to a elevated program if you're using Vista/Windows Server 2008 with User Account Control enabled.