Terminating a process before trying to copy files - installation

I'm developing an NSIS installer, to update a program that runs in background. Obviously, I'd like to send the program termination signals, because otherwise I repeatedly get a "can't write" error. How can I do this, with a limited overhead on installer size?

If your app has a window with a unique class name, you could just send it WM_CLOSE/WM_QUIT or whatever message you need.
Or your app could register a local server COM object the uninstaller could call (The system plugin can call COM methods)
Another way to do this is for the program to create a named event and wait on it, the uninstaller would signal it, this would be the clue for the program to quit.
As a last resort, you could kill the process with one of several plugins: KillProcDLL, Processes plug-in, KillProc plug-in and NsProcess
Also, the Locked List plugin might be a better alternative.

Related

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

Catching CTRL+BREAK in a Windows application

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.

How can I spawn a process on Windows and see which files it uses?

I would like to write a C++ function, on Microsoft Windows, that spawns a process and returns, in addition to the process's termination status, a list of all the files the process read or wrote. It should not require any cooperation from the spawned application.
For example, if the program spawned is the Visual Studio C++ compiler, the function would produce a list containing the source file the compiler opened, all header files it read, and the .OBJ file it created. If it also contained things like .DLL files the program contained, that would be fine. But again, it should work regardless of the program spawned; the compiler is just an example.
A twist: if the process creates subprocesses, I need to monitor their file accesses as well.
A second twist: if the process tries to open a file, I would like to be able to make it wait until I can create that file—and only then let it resume and open the file. (I think this rules out ETW.)
I know this probably sounds like an ingredient for some horrible kludge. But if I can get this working, the end result will be really cool.
A second twist: if the process tries to open a file, I would like to be able to make it wait until I can create that file—and only then let it resume and open the file
You just put yourself into Hack City with that requirement - you're right that ETW would've been a far easier solution, but it also has no way to block the file call.
Basically, here's what you're going to have to do:
Create the process suspended
Create two named pipes in opposite directions whose names are well known (perhaps containing the PID of the process)
Hook LoadModule, and the hook will watch for Kernel32 to get loaded
When Kernel32 gets loaded, hook CreateFileW and CreateFileA - also hook CreateProcessEx and ShellExecute
When your CreateFile hook hits, you write the name to one of the named pipes, then execute a ReadFile on the other one until the parent process signals you to continue.
When your CreateProcessEx hook hits, you get to do the same process all over again from inside the current process (remember that you can't have the parent process do the CreateProcess'ing because it'll mess up inherited handles).
Start the child process.
Keep in mind that you'll be injecting code and making fixups to an in-memory image that may be a different bitness than yours (i.e. your app is 64-bit, but it's starting a 32-bit process), so you'll have to have both x86 and amd64 versions of your shim code to inject. I hope by writing this lengthy diatribe you have convinced yourself that this is actually an awful idea that is very difficult to get right and that people who hook Win32 functions make Windows OS developers sad.

Can I Get Notified When Some Process Starts?

I need to know (preferably with the least latency) when foo.exe is launched.
Right now, I have a thread that sits in a light loop (~10 Hz) and walks the process tree looking foo.exe.
This is less than elegant and I was wondering whether I could register with some part of the Windows API to get a callback when any process starts.
If no such facility is available, I am, of course, open to other methods of accomplishing this task more elegantly.
You can register yourself as a debugger for foo.exe through the Image File Execution Options. Anytime the system needs to launch foo.exe, it'll launch your app and pass foo.exe and its parameters to you. You will have to start the process yourself.
Note: as usual, some words of caution by Raymond Chen.
You can also set a system-wide message hook and for each new process your dll gets loaded, check if it's the one you care you just pass through, for foo.exe you notify yourself and then pass through. Unfortunately, that means you will be injecting your code in each process and you will be hurting the system perf a little bit. Not to mention that you can actually hose everybody if you have a bug in your code.
Possible options:
Is foo.exe under your control? If so modify the source code to send a signal.
Is foo.exe not under your control? Write an injection DLL and have it send a signal when it's loaded into the process with the right name.

How to exit SW quickly

I have a SW which reside in external HDD, it will run automatically when user plug external HDD, of course, the SW have to close automatically when user unplug the external HDD. I can receive the device lost message, however my SW will not be respond druing releasing all objects, if I call exit(0) directly, the SW will show a crash message. Is there any way to quickly exit SW?
The clean way to exit a Windows application is
PostQuitMessage(0);
This will send WM_QUIT to the application, causing the message loop to terminate.
The fastest way to terminate a process is to call TerminateProcess(). This simply stop the process from receiving any further time slices and releases all the resources allocated to it by windows.
This method of ending a process is not recommended though for various reasons. One of the for instance is that if you have an open file which you write to using the standard library, some data may still be buffered and not fully written to the file.
I'll assume you want to exit cleanly. If you don't need to exit cleanly, use PostQuitMessage. If you do, and it's a UI app, send WM_CLOSE to your main window.
You should clarify what objects your software "will not be respond during" when you quit, and why it ceases to respond
I assume you're looking for a way to keep your app from crashing when the user unplugs an external device. You can force the OS to copy your executable from movable media to the swapfile and execute it from there. The corresponding linker switch (for MSVC++) is /SWAPRUN:{NET|CD}.
Set it to CD and the OS will copy the executable to swap when it's executed from the external drive.

Resources