So I wanted to create a windows service that runs a few commands in a batch file.
However, while I assume I can redirect stdout from the subprocess and read out an error message, I can't seem to find out how I would get that to display to the screen.
when starting a windows service, it gives errors when the service fails to start, so ideally I would like to just use the interface that pops up the other service errors rather than popping up some window of my own or writing a log file.
I used this to get started but it doesn't seem to have anything on error processing.
http://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus
He just outputs to a debugger. I can definitely do that, but ideally the person starting the service would want to know if there was an error starting.
Yes, you can redirect the STDOUT of the spawned process. MSDN has an article on that topic:
Creating a Child Process with Redirected Input and Output
You can use ReportEvent(), EventWrite(), or TraceEvent() to write log messages to the System Event Log (which is located within Windows' Control Panel), depending on which logging API you decide to use. Refer to MSDN for more details:
Event Logging
Windows Event Log
A service is a background task, it should not display its own UIs. Use the system Event Viewer to view log messages. The popup the user sees if the service fails to start is not displayed by the service itself, but by the Service Control Manager.
Starting with Windows Vista, services do not run in the same desktop session as logged in users (Session 0 Isolation), so they cannot display their own UI anymore. If your service must display a popup message, it can use WTSSendMessage() for that. For more complex UIs, it is best to implement that as a separate non-service GUI app that runs in the user's session, and then the service can launch/communicate with that app as needed.
Related
I'm trying to inject a dll into a testprogam and use AllocConsole() for debugging.
AllocConsole();
However, the console wont show up and I realized that the program I was trying to inject is running under SYSTEM and I was using an administrator account so the console wont show up on my desktop. Only the conhost process was created.
So... How to make a console from AllocConsole() show up on every accounts desktop?
The program is running as SYSTEM so likely it's a service running in the services session (session 0). It's not possible to allocate a console and show it in another session (e.g. the console session). It's not possible for a process to have a window (or console) that is visible in all sessions or even on multiple desktops.
If you don't know what Session Isolation is best start reading here: Application Compatibility - Session 0 Isolation
If you want to output simple debugging, an easy method is using OutputDebugString (and use a tool like DbgView to read the output) or writing to the eventlog. For more detailed output you could setup a named pipe or some other inter processs communication.
I need a certain process to be constantly running in every user’s computer. If that .exe is killed, I must be able to restart it and send an alert.
I immediately thought of building a Windows Service as the ideal solution, but I am facing a problem:
The process started by that service needs to be able to interact with the user, e.g. be able to show him a GUI.
my application also sets a keyboard hook in order to monitor the user's typing rhythms, and when I start the .exe from a service, that information is not accessible.
From the service I am able to launch the process "as the user" (using the LogonUser and CreateProcessAsUser functions), but still can’t see the GUI.
Is this possible? If not, what can I use to achieve the desired functionality?
tia
By default the GUI .exe will be run in the service session, which is separate from the interactive session of the user. You need to look into techniques for building an interactive service.
I have a service which constantly checks some application and assures that it wasn't closed. If this app closed - service launches it again.
The problem starts when user decides to log off the session. During logoff all applications are closing including the mine one. But the service is still running and constantly trying to start it again.
The questions is how to notify the service that user is going to log off and the application doesn't need to be restarted anymore? I've tried to make it using SERVICE_CONTROL_SESSIONCHANGE notification. But in accordance to MSDN they come to services when all apps already closed and logging off procedure completed. It is too late for me. Is there any way to programmatically find out that current session is in process of logging off?
My service launched under LocalSystem account.
Thanks.
p.s. I don't have the access to application source code. The goal need to be achieved without modifying it.
Have your service run two applications: the one it is a watchdog for, and a second one which you implement yourself. This second one can then respond to the log-off event by sending a message to the service (a la David Heffernan's answer), and the service will then know not to restart the watched job.
Open a communication channel between your app and your service and arrange for the app to tell the service that it is closing because of a logoff event.
You may not have access to the source code of the executable, but that doesn't mean that you can't affect the process. For instance, you could inject a DLL. Using SetWindowsHookEx, you'd catch the WM_ENDSESSION sent to the apps main window.
Why don't you create your service under the user that is running the App and tell it to startup automatic? In this case you should get the SERVICE_CONTROL_SHUTDOWN message when your user is logging off since the service would also be terminated.
How Can I execute a function when Windows shutdown. Here is my scenario, I am mounting a drive using WNetAddConnection2 function in my application. Now I want user to set the option if the drive will be mounted on next system startup or not.
If he selects , not to mount on next startup , then I need to remove the drive using WNetCancelConnection2 , but this should only happen when user shutdown the system.
I can only think of only solution. Create a service which will check the user option and then decide whether to mount the drive or not.
Are there any other ways to go ahead with it?
If you have a main window (even an invisible one) that can process messages, you can handle the WM_ENDSESSION message.
See: http://msdn.microsoft.com/en-us/library/aa376889(v=VS.85).aspx
If you can make your app into a Windows service (or have your app communicate state with one that you provide) you can perform required actions on receipt of SERVICE_CONTROL_SHUTDOWN in your service control handler function. This would decouple your app that handles user interaction from the shutdown handling, which requires something to be running all the time (what if the user logs off?).
explorer.exe is the GUI process of windows which usually only gets shut down if Windows shuts down (exceptions have to be made for certain error conditions). You could listen on the WM_DESTROY window message for the process ID of explorer.exe and dismount then.
The way I can think of is to:
Register your program to auto Start up (when PC starts). Here's a tutorial on howto.
Store the user option (as mentioned above) in a repository or registry (if you know how). When your app would have started, you can read your registry and act accordingly.
For shutdown, your application will have to hook itself on a SystemEvent to detect shutdown (then you can act accordingly). Here's an example on howto (C#). For C++, you can listen to WM_ENDSESSION message.
I hope that my 2 cents can help you.
I have a C++ Win32 application that was written as a Windows GUI project, and now I'm trying to figure out to make it into a Service / GUI hybrid. I understand that a Windows Service cannot / should not have a user interface. But allow me to explain what I have so far and what I'm shooting for.
WHAT I HAVE NOW is a windows application. When it is run it places an icon in the system tray that you can double-click on to open up the GUI. The purpose of this application is to process files located in a specified directory on a nightly schedule. The GUI consists of the following:
A button to start an unscheduled scan/process manually.
A button to open a dialog for modifying settings.
A List Box for displaying status messages sent from the processing thread.
A custom drawn window for displaying image data (the file processing includes the creation and saving of images).
A status bar - while a process is not running, it shows a countdown to the next scheduled scan. During a scan it also provides some status feedback, including a progress bar.
WHAT I'M SHOOTING FOR is a service that will run on boot-up and not require a user to login. This would consist of the scheduled file processing. However, when a user logs in I would still like the tray icon to be loaded and allow them to open up a GUI as I described above to monitor the current state of the service, change settings, start a scan manually, and monitor the progress of a scan.
I'm sure that I have seen applications like this - that function as a service even when I'm not logged in, but still give me a user interface to work with once I do log in.
I'm thinking that instead of having a single multi-threaded application that sends messages to the GUI thread from the processing thread, I need two applications - a Service to perform the processing and a GUI application to provide visual feedback from the Service and also send messages to the Service (for example, to start a scan manually). But I am new to Windows Services and have no idea how this is done.
It is also possible that I'm completely off base and a Service is not what I'm looking for at all.
Any help / ideas / suggestions would be greatly appreciated! Thank you.
You can't do this as a service.
You'll need to make your Windows Service as a normal service application. This will startup on system startup, and run the entire time the system is up.
You'd then make a completely separate GUI application, which "talks" to the service. This can be set to run when a user logs in, in the user's account.
In order to make them "talk" to each other, you'll need to use some form of IPC. Since these run on the same system (but in different accounts, typically), named pipes or sockets both work quite well.
There is a simple way of doing it.
You can’t have the service access any user’s session (session 1,2,3..) since services are isolated and can access session 0 only. This is a change from 2011.
You should write a win32 program to be launched by your service per each user who logs in using https://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx
The service can continue performing any task that isn’t user specific.