I'm doing some code in C and I want my code to be able to determine whether its running as a windows service or as a normal application, AFAIK that windows services run on session 0 on windows vista,7 and server 2008. I'm not sure if we use the undocument interface of ntdll to query process information would help about it, like if we get the PEB.
Thanks in advance.
Enumerate the processes, use QueryServiceStatusEx and find if any of the processes match the current process ID
I am sure you should be calling StartServiceCtrlDispatcher if you are running a process as a service. Simply check the return code for ERROR_FAILED_SERVICE_CONTROLLER_CONNECT. This will tell you whether or not you are running the process as a service.
You can query the process token for SECURITY_SERVICE_RID.
Related
I have a Windows application of which I need multiple instances running, with different command line parameters. The application is quite unstable and tends to crash every 48 hours or so.
Since manual checking for failure and restarting in case of one isn't what I love to do I want to write a "manager program" for this. It would launch the program (all its instances) and then watch them. In case a process crashes it would be restarted.
In Linux I could achieve this with fork()s and pids, but this obviously is not available in Windows. So, should I try to implement a CreateProcess version or is there a better way?
When you call CreateProcess, you are returned a handle to the new process in the hProcess member of the process information struct that you pass to CreateProcess. You can use this handle to detect when the process terminates.
For instance, you can create another thread and call WaitForSingleObject(hProcess) and block until the process terminates. Then you can decide whether or not to restart it.
Or your could call GetExitCodeProcess(hProcess, &exitcode) and test exitcode. If it has the value STILL_ACTIVE then your process has not terminated. This approach based on GetExitCodeProcess necessitates polling.
If it can be run as a daemon, the simplest way to ensure it keep running is Non-Sucking Service Manager.
It will allow to run as win32 service applications not designed as services. It will monitor and restart if necessary. And the source code is included, if any customization is needed.
All you need to do is define each of your instances as a service, with the required parameters, at it will do the rest.
If you have some kind of security police limitation and can't use third party tools, then coding will be necessary. The answer from David Heffernan gives you the appropiate direction.
Or it can be done in batch, vbs or js without need of anything out of the system. WMI Win32_Process class should allow you to handle it.
I made a GUI application that must run in my DELL server to send queries for 24 hours.
In case where the application is stopped by random users, or whatever it is, I created a service program that detects when it stops running, and executes it again.
The problem is, in service, FindWindow() doesn't properly work (always returns nullptr) because Microsoft changed its OS service policies since XP. And my service program has no way to find if the program is on the process list or not.
I found some solutions on the internet, which is to "allow service to interact with desktop on service panel" but since it was a long time ago so doesn't quite fit into the current OS version.
Should I use IPC instead? or any other ways to fix?
I believe that there has got to be a way to do this, because executing a process from service is also possible by using CreateProcessAsUser().
Any advice will be truly appreciated.
Thanks in advance.
So I did what Remy Lebeau suggessted for me, and it properly works in Windows 7, and 2008.
Here's how I went step by step.
Create a named mutex in the global namespace in the GUI application.
::CreateMutex(nullptr, false, L"Global\\MyMutex");
Check periodically if the mutex has disappeared or not
by using CreateMutex(), and do not forget to take care of the reference count to the handle.
HANDLE hDetector = ::CreateMutex(nullptr, false, L"Global\\MyMutex");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// The GUI application is still running.
// ...
::CloseHandle(hDetector);
}
else
{
// The GUI application is not running.
// ...
::CloseHandle(hDetector);
}
See it work.
I need to track to a log when a service or application in Windows is started, stopped, and whether it exits successfully or with an error code.
I understand that many services do not log their own start and stop times, or if they exit correctly, so it seems the way to go would have to be inserting a hook into the API that will catch when services/applications request a process space and relinquish it.
My question is what function do I need to hook in order to accomplish this, and is it even possible? I need it to work on Windows XP and 7, both 64-bit.
I think your best bet is to use a device driver. See PsSetCreateProcessNotifyRoutine.
Windows Vista has NotifyServiceStatusChange(), but only for single services. On earlier versions, it's not possible other than polling for changes or watching the event log.
If you're looking for a user-space solution, EnumProcesses() will return a current list. But it won't signal you with changes, you'd have to continually poll it and act on the differences.
If you're watching for a specific application or set of applications, consider assigning them to Job Objects, which are all about allowing you to place limits on processes and manage them externally. I think you could even associate Explorer with a job object, then all tasks launched by the user would be associated with your job object automatically. Something to look into, perhaps.
I have a problem concerning a windows service that I have implemented. The service does what it has to and logs various information but when I try to stop it, it doesn't seem to stop and keeps logging.
I am not very familiar with services, so if anyone knows why this is happening please tell me.
Edit: I have tested the service on two servers and the weird thing is that on one server it stops normally, but on the other it doesn't. That is what I don't understand.
IN case you have any threads ensure that you exit those threads in your stop routine. Some threads may still be lingering which is why it does not stop.
One possible reason could be because of some remaining thread (as mentioned by 'ckv').
Have you set proper handler using RegisterServiceCtrlHandler function?
Also make sure that the SERVICE_STATUS structure that you use has its dwControlsAccepted set to accept shutdown or stop (by setting SERVICE_ACCEPT_SHUTDOWN & SERVICE_ACCEPT_STOP). and don't forget to update the service status (using SetServiceStatus function) once the service is up and running.
I have a C++ Windows application that was designed to be a Windows service. It executes an updater periodically to see if there's a new version. To execute the updater, _execv() is used. The updater looks for new versions, downloads them and stops the Windows service (all of these actions are logged), replaces the files, and starts the service again. Doing that in CLI mode (not going into service mode) works fine that way. According to my log files, the child process is launched, but the parent process (the Windows service) exits.
Is it even "allowed" to launch child processes in Windows services, and, why does the service exit unexpected then? My log files show no error (I am even monitoring for segfaults etc which is written to the log).
Why are you using _execv() rather than doing it the windows way and using CreateProcess()?
I assume you've put some debug into your service and you aren't getting past the point where you call _execv() in your service?
_execv replaces the existing process with a new one running the file you pass as the parameter. Under Unix (and similar) that's handled directly/natively. Windows, however, doesn't support that directly -- so it's done by having the parent process exit and arrange for a child process to be started as soon as it does.
IOW, it sounds like _execv is doing exactly what it's designed to -- but in this case, it's probably not what you really want. You can spawn a process from a service, but you generally want to use CreateProcessAsUser to create it under a specified account instead of the service account (which has a rather unusual set of rights assigned to it). The service process will then exit and restart when it's asked to by the service manager when your updater calls ControlService, CreateService, etc.