Catching CTRL+BREAK in a Windows application - windows

Heres a simple question - is there anyway that a non-console (ie a CWinApp) application can receive and process CTRL+BREAK, it would appear SetConsoleCtrlHandler doesnt do the job nor the installation of signal handlers?
I unfortunately am working with a legacy CDialog based app which is run under the control of Microsoft HPC and HPC uses CTRL+BREAK to cancel the program (assuming i guess that nobody in their right mind would have a non-console app running in the background)
Cheers.

Calling AttachConsole with ATTACH_PARENT_PROCESS should do the trick. This will attach your process to the HPC console so that it can receive the control-break signal. You should probably do this before calling SetConsoleCtrlHandler.
If that doesn't work, try AllocConsole instead. If HPC doesn't have a console of its own, it might be assuming that the sub-process will have created a new console group (this happens automatically for console-mode applications) in which case it will be sending a control-break signal to the sub-process PID. If so, it shouldn't matter whether the console group was created automatically or explicitly.
You may wish to start by making sure that HPC is indeed sending a control-break signal (presumably via GenerateConsoleCtrlEvent) by checking that SetConsoleCtrlHandler works as expected for a console-mode application. If it is calling TerminateProcess instead then there is nothing you can do about it.

Related

Matlab onCleanup with Compiled applications (windows)

I have an application made with matlab compiler.
I want to do some shutdown activities whenever it ends. As it seems to be impossible to catch signals in matlab (or I'm not able to), I checked to use onCleanup (Matlab: Is it possible to create signal handlers (.m scripts)). It is working within matlab (native), but not within the compiled application.
I tried to end the application with CTRL-C and with taskkill (which only work with /f). In both cases the onCleanup-method was NOT executed.
For testing purposes here
function sigtest(varargin)
remainder=onCleanup(#()save('exit.mat'));
b=1;
while true
disp(datestr(now));
a=rand(round(5*b));%to be saved
pause(10);
b=a(1);
end
my source code, which I compiled via mcc -m -v sigtest.m.
As onether try, I inserted the lines
myexiter=addlistener(System.AppDomain.CurrentDomain,'ProcessExit',...
#(a,b)save('listexit.mat'));
after line 2, but also this .NET-Event is not working.
If you're registering shutdown activities within M-code, they're only going to work on a graceful shutdown of the process. The taskkill /f command will do a "forceful" shutdown, which I think will terminate the process immediately. The Matlab interpreter won't get a chance to run whatever cleanup code is still pending. I think Ctrl-C on a console application (which the compiled sigtest.m will be running as) will have the same effect. Same applies to the .NET-Event: if you forcefully kill the process, that callback never gets a chance to run.
If you want on-exit code, or any other cleanup stuff, to run, you need to find a way for the program to find out when it should exit and initiate a more graceful shutdown itself. For example, in your sigtest example, you could check stdin at the end of every pass through the loop, see if the user has typed 'quit', and if so call exit(). Then your onCleanup stuff should run.
In a GUI compiled Matlab application, this is more straightforward; you have GUI controls to exit the application. I don't know what the canonical way is to make a console compiled Matlab application responsive to user exit requests, or if there even is a good one. You might want to make this a GUI app if you think the user might want to request a graceful abort of its operation.

How do I launch an updater properly?

I've got a program that needs to be able to update itself. I have a second program that will perform the updates, downloading and installing. The updater will obviously need to be able to update the main program, and for that, the main program can't be running. So I want to have the main program launch the updater with a call to ShellExecuteEx, but the MSDN documentation has me a little confused.
It says that:
The SEE_MASK_NOASYNC flag must be specified if the ... process will
terminate soon after ShellExecuteEx returns. Under such conditions,
the calling thread will not be available to complete the DDE
conversation, so it is important that ShellExecuteEx complete the
conversation before returning control to the calling application.
Failure to complete the conversation can result in an unsuccessful
launch of the document.
And under SEE_MASK_NOASYNC, it says that the ShellExecuteEx call won't return until the operation is complete. What I want is to launch the updater and then immediately terminate the main program, so the updater can run without trouble. Is that the correct way to do it? And is there anything special I need to do to keep the launched updater from being marked as a "child process" that will be killed when the main process shuts down?
Do you have to call ShellExecute? I do something similar and launch via CreateProcess and it works fine.
(In reality, cmd.exe is launched which runs a batch file. The batch file waits, starts the updater and waits for it to finish, then waits a bit, then launches the main app again. Never had any trouble with it)
DDE won't be used to launch an EXE directly. (It's only used to launch certain types of files if they are regsitered as needing to be launched that way. If you're just running an EXE by name, DDE should be irrelevant.)
So you should specify SEE_MASK_NOASYNC (to make sure the ShellExecuteEx call finishes doing all it needs to do and your app is then free to end the thread as soon as the call returns) and the API should return very quickly.
here's a good CodeProject article about launching an updater:
http://www.codeproject.com/Articles/395572/Executable-Integration-Example-External-settings-a

On Windows, how does console window ownership work?

When a console application is started from another console application, how does console ownership work?
I see four possibilities:
The second application inherits the console from the first application for its lifetime, with the console returning to the original owner on exit.
Each application has its own console. Windows then somehow merges the content of the two into what the "console" visible to the user
The second application get a handle to the console that belongs to the first application.
The console is placed into shared memory and both applications have equal "ownership"
It's quite possible that I missed something and none of these four options adequately describe what Windows does with its consoles.
If the answer is close to option 4. My follow-up question is which of the two processes is responsible for managing the window? (Handling graphical updates when the screen needs to be refreshed / redrawn, etc)
A concrete example: Run CMD. Then, using CMD, run [console application]. The [console application] will write to what appears to be the same console window that CMD was using.
None of your four possibilities is actually the case, and the answer to your follow-on question, "Which of the two processes is responsible for managing the window?", is that neither process is responsible. TUI programs don't have to know anything about windows at all, and, under the covers, aren't necessarily even plumbed in to the GUI.
Consoles are objects, accessed via handles just like files, directories, pipes, processes, and threads. A single process doesn't "own" a console via its handle to it any more than a process "owns" any file that it has an open handle to. Handles to consoles are inherited by child processes from their parents in the same way that all other (inheritable) handles are. Your TUI application, spawned by CMD, simply inherits the standard handles that CMD said that it should inherit, when it called CreateProcess() — which are usually going to be CMD's standard input, output, and error (unless the command-line told CMD to use some other handles as the child's standard input, output, and error).
Consoles aren't dependent upon CMD. They exist as long as there are (a) any open handles to the console's input or output buffers or (b) any processes otherwise "attached" to the console. So in your example you could kill CMD, but only when you terminated the child process too would the console actually be destroyed.
The process that is in charge of displaying the GUI windows in which consoles are presented is, in Windows NT prior to version 6.1, CSRSS, the Client-Server Runtime SubSystem. The window handling code is in WINSRV.DLL, which contains the "console server" that — under the covers — Win32 programs performing console I/O make LPC calls to. In Windows NT 6.1, this functionality, for reasons covered by Raymond Chen, moved out of CSRSS into a less-privileged process that CSRSS spawns.
My guess is somewhere between 3 and 4. The console is a self-standing object, which has standard input, output and error streams. These streams are attached to the first process that uses the console. Subsequent processes can also inherit these streams if not redirected (e.g. running a command with redirect to a file.)
Normally there is no contention, since parent processes usually wait for their child process to complete, and asynchronous processes typically start their own console (e.g. try "start cmd" in a command prompt) or redirect standard output.
However, there is nothing to stop both processes writing to the output stream at the same time - the streams are shared. This can be a problem when using some runtime libraries since writes to standard output/error may not be immediately flushed, leading to mixed garbled output. In general, having to processes actively writing to the same output stream is usually not a good idea, unless you take measures to co-ordinate their output through concurrency primitives like Mutexes, Events and the like.
The way the SDK talks about it strongly resembles 1. It is an option with CreateProcess, described as follows:
CREATE_NEW_CONSOLE
The new process has a new console, instead of inheriting its parent's console (the default). For more information, see Creation of a Console.
Output however happens through handles, you'd get one with GetStdHandle(). Passing STD_OUTPUT_HANDLE returns the console handle, assuming output isn't redirected. Actual output is done through WriteFile() or WriteConsole/Output(). If both processes keep writing output to the handle then their output will be randomly intermingled. This is otherwise indistinguishable from what would happen when two programs write to the same file handle.
Logically, there's a screen buffer associated with a console. You can tinker with it with SetConsoleScreenBufferXxx(). From that point of view you could call it shared memory. The actual implementation is undiscoverable, handles abstract them away, like any Win32 API. It is sure to have changed considerably in Vista with the new conhost.exe process.
CMD 'owns' the console. When it creates a process for an app, that app inherits handles to the console. It can read and write those. When the process goes away, CMD continues ownership.
Note: I'm not entirely sure that 'ownership' is the right word here. Windows will close the Console when CMD exits, but that may be a simple setting.
Each application will run in it's own AppDomain. Each AppDomain should be running it's own console.
Ah, you're right. I was thinking about running executables within a process and forgot they start their own process - I didn't drill down far enough.
I think it's spelled out fairly well in the documentation.

Stop VB application from running in background

I have a console application (written in VB6 ) which is behaving strangely on my machine. I kick it off from the command line and what should be a two minute job drops straight back to the prompt - if I run this on another machine the executable will sit and wait until the job finishes before returning control back to the prompt. If I check process explorer I can see that the executable is running as a background process and other than this strange background-ness is running as expected.
Any thoughts on why this could be happening? (Running on 32-bit Windows XP Pro SP3.)
It's totally unclear whether this is an application you wrote and have the source code for. If that's the case, you need to get in and start debugging. At the least, use OutputDebugString to send information about what's going on to any number of potential viewers. Taking that a step further, consider rewiring the app using the Console module I wrote, along with vbAdvance to recompile. This combination will allow you the full power of the VB6 IDE to debug within. No more guessing about what's going on.
Then again, if it's not your app, I'm not sure what VB6 has to do with it and wish you the best of luck trying to figure out what's up.
It sounds to me as though the app isn't being recognised as a console app on one of your machines. Console apps weren't officially supported in VB6, although there are some well-known hacks for creating them (particularly the free add-in vbAdvance). Possibly your console app is a bit unreliable? If Windows thinks your app is a GUI rather than a console app, it won't wait for it to finish.
As a pragmatic workaround: try launching with start /wait rather than just using the exename. That forces the command prompt to wait for the program to finish, whether it's a GUI app or a console app.
Sounds like an error is occurring that is being 'swallowed' by the application. Do you have the source code?
Errors in VB6 apps are often due to some COM component not installed and/or registered.
Download SysInternals Process Monitor and this will show up accesses to ProgIDs that fail (uninstalled/unregistered COM components).
Check out: Process Monitor - Hands-On Labs and Examples.
Have you checked permissions? Is the application accessing any network based resources?

How to reload a crashed process on Windows

How to reload a crashed process on Windows? Of course, I can run a custom monitoring Win service process. But, for example, Firefox: it doesn't seem to install such a thing, but still it can restart itself when it crashes.
On Vista and above, you can use the RegisterApplicationRestart API to automatically restart when it crashes or hangs.
Before Vista, you need to have a top level exception filter which will do the restart, but be aware that running code inside of a compromised process isn't entirely secure or reliable.
Firefox constantly saves its state to the hard disk, every time you open a tab or click a link, or perform some other action. It also saves a flag saying it shut down safely.
On startup, it reads this all back, and is able to "restore" based on that info.
Structured exception handling (SEH) allows you to catch program crashes and to do something when it happens.
See: __try and __except
SEH can be very dangerous though and could lead to your program hanging instead. Please see this article for more information.
If you write your program as an NT service then you can set the first, second and subsequent failure actions to "Restart the service".
For Windows 2008 server and Windows Vista and Windows 7 you can use the Win32 API RegisterApplicationRestart
Please see my answer here for more information about dealing with different types of program crashes.
If I recall correctly Windows implements at least some subset of POSIX and so "must" have the signal interface (things like SIGKILL, SIGSEGV, SIGQUIT etc.).
I've never done this but on linux, but you could try setting the unexpected termination trap with signal() (signal.h).
From quick scan of docs it seems that very few things can be done while handling signal, it may be possible that even starting a new process is on forbidden list.
Now that I've thought about it, I'd probably go with master/worker pattern, very simple parent thread that does nothing but spawns the worker (that does all the UI / other things). If it does not set a specific "I'm gonna die now" bit but still dies (parent process always gets message / notification that spawned process died) then master respawns the worker. The main theme is keep master very simple and hard to die due to own bugs.

Resources