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
Related
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.
I want to know how the mechanism of debugger injection works. Why is "Image File Execution Options" so special?
I have two guesses.
CreateProcess will call an internal function that checks against the list of registry keys. If it is found, then it manipulates the arguments and calls the debugger exe instead.
There is some other service listening for CreateProcess calls and intercepts them. It kills the original call or message (if createprocess is a message or message-like), then it runs the new process as if the original caller called it.
My desire is to verify and update components before an application starts. I like the IFEO "feature" but i need to run the original process after the verification step so I need a way to run it without recursing into the updater. I hope that by learning more about the injection system I can get this system working.
This article explains how it works.
In Windows XP and 2003 the user-mode CreateProcess code reads the registry and, if required, launches the debugger instead.
In more recent versions of Windows this functionality has moved into kernel mode.
But neither case seems to involve a general interception mechanism for CreateProcess.
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.
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.
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.