Check if windows shell has finished loading startup programs - c++

How can i programatically check if the windows shell (explorer) has loaded all startup programs & the user login process is over ?

There is a somewhat documented event you can wait for, but it is signaled when explorer has started loading. On XP this event is called "msgina: ShellReadyEvent" and "ShellDesktopSwitchEvent" on Vista. I linked to the sources of some alternative shells in a post related to this event.
Another alternative would be to listen for the Taskbar Creation Notification message. It can fire more than once so you would need to keep track of that.
On Vista+ there is one last alternative that might just work: Programs set to run at startup are part of a job object so they cannot run at high priority. If your program runs at startup you could maybe check for this, either by using IsProcessInJob or SetPriorityClass+GetPriorityClass in a loop. (SetPriorityClass will lie about its return value IIRC)

Related

Blocking processes to start on startup from a service & continue running service after some processes are down.

I have a C++ windows service running on system privileges and I need to make some changes in some of my DLLs that are loaded to several windows processes (explorer.exe, etc.).
The only time to do so is when these processes are down. I'm trying to make to impact to the UX minimal, so I don't wan't to force quit those or to popup any annoying message boxes and ask the user to do so.
I have tried to start this task on the startup of my service, the issue is several of these processes start before I finished it.
I'm trying to understand if there is a way to delay the start of processes on Windows startup, until I finish my task. Is there any event or anything familiar that I can set that will block those?
The other option is to do the needed task on shutdown. I did not find a way to do so yet, and all the related questions seem a bit old (how to delay shutdown and run a process in window service
), and regard to older version of windows.
This solution needs to be compatible with Windows versions greater than 7.
You can do this by using MoveFileEx and setting MOVEFILE_DELAY_UNTIL_REBOOT which will replace the file at the next reboot.
This should be well before any other processes have started, but without more details on your usecase its hard to tell if this'll work for you. Either way, searching for this flag should give you lots of information about this kind of issue.
According to the documentation, this has been supported since XP.

How to write a Windows application that doesn't immediately release control to the calling application

I am writing a small application (.exe) that does some tasks and then returns an exit status. It is meant to be run regularly from another application (which I have no control over) that uses the status code to determine further action.
It works just fine if I compile and link it as a console app. However, that makes the console window flash briefly on the screen every time it is run, which is a little bit annoying. I tried to make it a Windows app, but the problem then is that Windows releases control to the calling application (or the OS) immediately after start. Thus, any exit status my application generates is returned too late and is never seen by the calling application.
Is there a way to force my app to stay in the foreground, so to speak, and not release control before it actually exits? I tried to force the entry point to be the "main" function instead of "WinMain", but that didn't help.
It isn't a question of whether the child "releases control" or not - Windows is a preemptive multitasking operating system, so all processes run at once. If the parent process waits for the child to exit, it is because the programmer told it to wait for the child to exit.
It isn't easy to make a program wait for console programs but not non-console programs. The command shell (cmd.exe) works this way when run interactively, but there isn't any API that does this as far as I know. Assuming that it isn't deliberate - which would be very strange in this context - the only explanation I can think of is that the program is running an interactive command shell and feeding in your command via standard input. That's the wrong thing to do, but I have seen people trying to do it that way before.
Presumably you can choose the command line that the parent executes. Try this:
start /wait myapp.exe
(That's how you would do it in an interactive command shell.)
If that doesn't work, you may have to consult the author of the parent process for advice.

Intercept signal / event when 'Stop Debugging' button is pressed in Visual Studio

Background: I am writing a QA automation platform for an API which outputs formatted results to a specified directory. In addition, I have developed a GUI application for analyzing these results. A user may run the second application trying to analyze test results while our automated build system is running the first application modifying / generating new test data. To avoid thrashing, I have each application acquire file locks when making modifications, and releasing them when they are done. Upon normal program termination, if the running application has acquired a lock on the data directory it is released.
Problem: I need to be able to release the aforementioned file locks when either tool exists prematurely (user pressing CTRL-C, user stopping the application in debugger, or due to buggy API / application logic being tested). To handle this, I have implemented a signal handler using sigaction which handles intercepting fatal signals (tested and working), and have implemented a ctrl-c handler via the Win32 function SetConsoleCtrlHandler. However, I cannot seem to find a way to intercept the event of a user pressing the Stop Debugging button in Visual Studio. I assume this event generates something like SIGKILL / SIGSTOP (which cannot be handled through sigaction) but I would also hope there is some std library or Win32 functionality to intercept this event and perform some cleanup. Do you guys know of a way to handle this event or even what exactly this button does to kill a running application?
If you're using boost, you can use boost::interprocess::windows_shared_memory.
It is guaranteed to be released when the process ends.
Boost is just a neat wrapper around the windows API in this case. It wraps the Windows Named Shared Memory API.

Closing an application properly: an Alternative to TerminateProcess

I'm facing an issue with TerminateProcess() function.
The application I'm currently writing a JobScheduler app that schedules and launches job at a specific time.
For this purpose, I'm using CreateProcess() to execute my JobLauncher.
The JobLauncher process then launches a console program (using createprocess ) which effectively executes the job executable, waits for its termination and monitors the duration, user and kernel times elapsed etc.
In order to kill the job from the JobScheduler I firstly started using TerminateProcess() but it does not allow me to close the executable itself properly. I mean i found no way to hook any termination event.
Until I find a better way than a brutal TerminateProcess(), I wrote an intermediate solution using the GenerateConsoleCtrlEvent() in the calling program.
In the job application that launches the target job executable, I installed a handler using SetConsoleCtrlHandler().
And in the handler, I can terminate the process of the job and notifies my thirdparties properly.
This is the better solution I found for now.
Is there a better way to programmaticaly and properly close a process ?
Do you this solution is completly absurd ?
I'm not a "system-level" specialist developer though...
Z.
This well know Windows console problem and you can find some solutions here.
We used on internal console utility which has name "Kamikaze". It worked as described here and for me it's a best solution cause there is no problem with porting between Windows versions and Windows architectures (x86, x64).

Monitoring open programs with Win32

I've searched the web, and various forums, but I can't find one thing, how to continually monitor open programs and then close another program (not the one being monitored) if something happens to the program being monitored.
For example, say that there is an already open Notepad window, and then the user or some other program opens a Windows Explorer window. I want to know how to close the Notepad window without interacting with the Windows Explorer window (other than realizing that it is indeed open), as well as closing the Notepad window if the user closes the Windows Explorer window.
Thanks in advance! :D
On windows, you can use PSAPI (The Process Status API) to know when processes are started and terminate. The EnumProcesses function can give you this information.
A more reliable method to determine that a process terminated (since process ids can be reused) is to wait on its process handle (you will need the SYNCHRONIZE access right) which you can obtain using OpenProcess and the process' id obtained from EnumProcesses.
To terminate a process, there is always TerminateProcess. To call TerminateProcess, you will need a handle to the process with the PROCESS_TERMINATE access right. All of this assumes that you have the privileges needed to perform these actions on the process to be terminated.
One thing to be aware of is that processes and programs - or at least what the user regards as a program - are not necessarily the same thing.
If you use the PSAPI to get a list of all the processes running, you'll see a lot of background process that don't correspond to open windows at all. There's also cases where a single process can have multiple top-level windows open. So while you have simple cases like notepad where once notepad.exe process corresponds to one Notepad window, you also have cases like:
Word, where one word process handles all the word documents currently open (one process, many windows)
Explorer, where a single exploere.exe process handles all the open explorer windows, and also things like control panel windows and the task bar.
Chrome (and other browsers), where each tab gets its own process (many processes, one window!)
Using TerminateProcess is perhaps not the best way to close an app: it's not directly equivalent to clicking the close button. It forcibly terminates the entire process there and then, without giving it any chance to clean up. If you do this on Word, when it restarts, it will go into 'recovery mode', and act as though it hadn't shut down cleanly the last time. It's best left as a last resort if a process has stopped responding. Also, if you TerminateProcess on a process like Word or Explorer, you'll end up closing all windows owned by that process, not just one specific one.
Given all of this, if you want to essentially write some sort of program manager, you might be better off taking a window-centric approach rather than a process centric one. Instead of monitoring running processes, monitor top-level application windows.
There are several ways to listen for changes to windows; SetWinEventHook with EVENT_CREATE/DESTROY is one way to listen for HWNDs being created or destroyed (you'll need to do filtering here, since it will tell you about all HWNDs - and more! - but you only care about top-level ones, and only app ones at that). SetWindowsHookEx may have other options that could work here (WH_CBT). You can also use EnumWindows to list the windows currently present (again, you'll need to filter out owned dialogs and tooltips, currently invisible HWNDs, etc).
Given a HWND, you can get process information if needed by using GetWindowThreadProcessId.
To close a window, sending WM_SYSCOMMAND/SC_CLOSE is the best thing to try first: this is closer to clicking the close button, and it gives the app a chance to clean up. Note that some apps will display a "are you sure you wish to close?" dialog if you haven't saved recently - again, it's consistent with clicking the close button with the mouse.
The most well-known way of doing this on Windows is to use the Process Status API. You can use this API to enumerate processes However, this API is annoying in that it doesn't guarantee you get the full list or processes.
A better way to enumerate processes is using the Tool Help Library, which includes a way to take a complete snapshot of all processes in the system at any given time.
You need the Microsoft PSAPI (Processes API), for example to see the open processes you can use the openProcess function.