How to wait for termination of itself - delphi

my currently running application (A1) needs to be terminated but as well as run some other application (A2). But I need to run application A2 after fully terminated of A1. Now I have something like this:
begin
Application.Terminate;
wait(2000); <<<<<<<
ShellExecute(A2)...
end;
To be more exact - I need to call installation (A2) and want to be sure A1 is not running, because A2 is installation of A1. Please imagine that termination could last more time or it shows some modal dialog...
Is there any easy way how to do it (wait for it)? Of course without communication with or changing of A2! A2 could be anything else in the future.
VladimĂ­r

I need to call installation (A2) and want to be sure A1 is not running.
This is impossible. You cannot execute code in a process that has terminated. Once the process has terminated there is nothing that can execute code.
You'll need a new process. Start the new process with the sole task of waiting on its parent to terminate, and then do whatever is needed once the parent has terminated.

If want to make a proper installer/updater program don't worry about when and how do you execute it but instead how it will detect if your application is running or not.
Now if your main application already has a mechanizm to prevent starting of multiple instances of your application you already have half the work done. How?
Such mechanizms publish the information about an instance of your application already running to be available by other programs.
Most common appraoch to do so is by registering a named Mutex. So when second instance of your application starts it finds out that it can't create a new Mutex with the same name becouse one already exists. So now in most cases second instance of your application sends a custom message to the first instance to bring that instance to the front (restore application) and then closes itself.
If you want to read more about different mechanizms to controling how many instances of your application can be running at the same time I suggest you check the next article:
http://delphi.about.com/od/windowsshellapi/l/aa100703a.htm
So how do you use such mechanizm for your installer/updater?
Just as you would check in second instance of your application to see if another instance is already running you check this in your installer/updater instead. You don't even need to do this schecking at the start of installer/updater. You can do it even later (downloading the update files first).
If there is an instance of your application running you broadcast a custom message. But this message is different from the one that one instance would send to another.
This will now tell your application that it is about to be updated so it should begin the closing procedure.
If you form this custom message in such a way that it also contains information about your installer/updater application.handle you give yourself the ability for your main application to send a return response in which it notifies the installer/updater in which state it is. For instnace:
asClosing (main application is just about to close)
asWaitinUserInput (main application is waiting for user to confirm save for instance)
asProcessing (main application is doing some lengthy processing so it can't shut down at this time)
And if there is no response in certain amount of time your installer could asume that your main application might be hung so it notifies the user that automatic closure of main application has failed and so that the user should close it manually and then retry the updating process.
Using such approach would allow you to start your installer/updater at any time during execution of your main application.
And not only that. You can start your installer/updater by double clicking its executable, by a shourtcut, by some other application or even by a windows task system.

Related

Why does OpenProcess() return a non 0 value when the process ID is no longer running

I'm starting a new instance of another application using CreateProcess from Example and I end up saving the PID so that I can later check if that process is still running.
I'm using to following method to check if it's running or not:
procedure TfrmRSM.Button1Click(Sender: TObject);
begin
var
ahandle := OpenProcess(PROCESS_ALL_ACCESS, true, aPID);
if ahandle = 0 then
ShowMessage('is not running')
else
ShowMessage('is running');
CloseHandle(ahandle);
end;
The code above should return 0 when the process is no longer running but it still returns a number greater than 0
I am closing the handle after using CreateProcess
Whats to propper way to check if a PID is running if the method I'm using is incorrect? I'm only able to find methods that use the application name.
I'm starting a new instance of another application using CreateProcess from Example and I end up saving the PID so that I can later check if that process is still running.
The correct way to handle this is to keep open the HANDLE that CreateProcess() gives you, and then you can query it via WaitForSingleObject() or GetExitCodeProcess() to see if the process has terminated or not, and then close the HANDLE when you no longer need it.
In comments, you mention that your launching app may terminate and be restarted separate from the target process. In that case, you could close the HANDLE if you still have it open, saving its PID and creation date/time somewhere you can get it back from, and then when your app restarts it can enumerate running processes (alternatively) to see if the target EXE is still running and has a matching PID and date/time, and if so then open a new HANDLE to that PID. Just be careful, because this does introduce a small race condition where the target process might terminate after you detect its presence and its PID could get recycled before you have a chance to open it. So you might need to re-validate the HANDLE's info again after opening it.
Otherwise, during your app's shutdown (or even before), you can off-load the open HANDLE from CreateProcess() to a separate helper process that stays running in the background monitoring the HANDLE, and then your main app can get the HANDLE back from that helper after restarting. Or, perform the actual CreateProcess() call in the helper to begin with, so the HANDLE monitoring stays within a single process at all times, and let your main app query the helper for status when needed.
I'm using to following method to check if it's running or not:
That will not work, as you don't know whether the PID is still valid, or even still refers to the same process you are interested in. Once that process has terminated, its PID can be recycled at any time for use with a new process.
The code above should return 0 when the process is no longer running but it still returns a number greater than 0
The only way OpenProcess() can return non-zero is if the specified PID is actually running. But that does not guarantee it is the same process you are interested in. At the very least, after OpenProcess() returns a non-zero HANDLE, you can query that HANDLE for its info (EXE file path, creation date/time, etc) to see if it is the same process you are expecting. If the info does not match, the PID was recycled.
Why does OpenProcess() return a non 0 value when the process ID is no
longer running?
This is probably an undefined behavior or the PID has been recycled by Windows.
I want to check if a process I created is still running later even
after I quit my application and opened it again.
You said you cannot change the process. One work around is to use an intermediate and very simple process to launch the target process. The intermediate process can use any IPC (for example shared memory of shared file) to talk to the main process to inform it about running target process. This intermediate process will run the target process and update a flag that the main process can query (In my example in shared memory).
The intermediate process can also simply keep a file open for exclusive access while the target process is running. The main process can try to open the file and if it succeed, then the target process is done (Intermediate process use WaitForSingleObjector WaitForMultipleObject to wait for target process termination).
To wait for a process to end, simply use WaitForSingleObject() on the process handle: when the process ends, the handle is signaled and the function returns WAIT_OBJECT_0. This ensures that you "look" at the handle the whole time it lives, instead of only inspecting it from time to time and otherwise leave it unattended.
Most likely you put this into a separate thread, and upon its ending you have your event to react to when the watched process ended. If you have multiple handles to look for, use WaitForMultipleObjects() - be aware that it can't handle more than 64 (MAXIMUM_WAIT_OBJECTS) handles at once.
Edit: when not being able to track a process handle entirely you can at least use GetProcessTimes() to check if the process you're looking at still started at the same time you looked at it last time - that should make it pretty distinctive: when the process handle is recycled by a new process then at least its starting time should differ.

Stopping current application and running update application

I am trying to write my own update source code to update my application from the web
basically I use two INI files. One on the web and one on the client side. The client side holds the current version number and the url to the server side ini. The server side ini holds the newest version and the url to the new download.
Anyways, all seems to work great. The file downloads great, but I would like to know the how one goes about closing the current application to run the new downloaded file (installer)
Why not simply run the updater and the immediately close the current application?
ShellExecute(nil, nil, PathToUpdater, nil, nil, SW_SHOWNORMAL);
Application.Terminate; // Or some other way
Surely the updater doesn't mind that the original process lives a few milliseconds into its lifetime?
The normal procedure is like this:
The main program detects that an update is ready.
The main program silently downloads the update to a temporary location. The download is performed in a background thread.
When the download is complete and verified, the main program restarts.
Whenever the program starts and notices that there is a new update waiting to be installed it terminates and runs a separate executable that performs the update.
When the update is complete, the program is restarted again.
The main benefit of this is that the user is not compelled to wait for the download to occur. A process which may take time and may fail. Thus giving the user as little downtime as possible.
There is a tricky scenario to handle. That's when the program starts the updater and then shuts itself down. If the main process doesn't close before the update opens the executable, then the updater can fail. The most elegant way to handle this is for the main program to pass its PID to the updater. The updater can then open a handle to that process and wait until it is signaled.
An alternative approach, quite similar, goes like this:
The main program detects that an update is ready and fires off a separate executable to perform the update. Or, the main program periodically fires off the updater to check whether or not there is an update available.
The update process silently downloads the update to a temporary location.
When the download is complete and verified, the updater signals the main process to terminate.
Once the main process has terminated (the updater waits for it to do so), the updater performs the update.
When the update is complete, the main program is restarted.
To be honest, the second approach seems more attractive to me. It has a much better separation of concerns. The main program is concerned with its business. The updater is concerned with its job. Obviously there has to be interaction and cooperation between them, but this is kept to a bare minimum.

How to check lock status and unlock if necessary for Database on Blackberry?

Since I've started developing my Blackberry app, the biggest problems I've encountered all had to do with SQLite Databases.
Right now I'm putting my app through a stress test, and when problems pop up I address them by printing out statuses to the console and taking care of things line by line. Right now (after mashing buttons on my app) I received a "Database is locked" error and I'm not sure what to do.
It seems that once the database is locked it's locked for good until it is unlocked........ my question is how can I unlock it?? First of all, how can I check to see if it's locked??
I'm sure our users won't be mashing buttons like I did, but you never know. I want to account for every possible scenario.
Thanks
EDIT: This is what happens in my application..... When I launch it starts a thread, this thread performs a cleanup on one of my tables based on how old certain pieces of data are (uses DELETE). The thread then continues to get a USER object from my DB (read only), it then uses this USER object as a parameter to call a web service. The data retrieved from the web service is INSERTED into my database. (It's a little more complex than that as a few read/write operations are performed at this time. After that, the thread fires a callback method to update my UI.
This all works fine. I can exit the app WHILE the thread is running and relaunch and a flag will prevent it from starting a new instance of the same thread (unless the other one is done of course).
Now my problem: My app's home screen is a list of buttons, when the user clicks one of these buttons another, more detailed list is loaded (this requires a READ ONLY call to the database). When I launch the app (firing the web service calling thread) and then click a button on the main screen right away, the table gets locked. (Not always, sometimes it takes 4 or 5 tries, sometimes more, sometimes less). But if I keep doing this it WILL eventually lock making it impossible to make any calls to my DB, hence no more UI (which depends on the DB).
The DB call that populates the UI on the second screen is READ ONLY, can't I have as many of these as I need?? What causes the DB to lock?? What's the difference between a DB lock and File System error (12)??
I seemed to have fixed the problem. I was under the impression that if a read/write connection was open then a read-only connection could be created safely.
This doesn't seem to be the case. If I have a read/write connection open then no other connections can open until that one is finished.
I basically created one read/write connection, set a flag to identify it as open, and during my read connection use the same Database object if the flag is open, or create a read only if it's closed.
So far so good.
Sqlite does not support concurrent modification. In practice on BlackBerry, this means you can only open the database from one part of the code at a time. To maintain this one-at-a-time access, you need to close the database when you are done with it, as #AnkitRox points out.
However you also need to guard against concurrent access. Even if your code properly closes the database, it is possible for two different threads to access the database. In that case, you will need one to wait. In Java-ME this is typically accomplished through the 'synchronized' keyword, and using the same lock object for all database access.
Check properly that, you are opening and closing database before and after execution of query respectively.
Because if Database is going to open without closing it properly, then it gives errors.

Sending a message to an application running on a secondary logged in user account

I'm trying to send a message to an application running under a different user account (a user that is also logged in with a different account on the computer, using quick user switch on XP and later, and executed the application).
The background is that my application can update itself, but in order to do that all running instances must be closed first.
The instances need to be shut down (instead of just killing the process), so the updater does that by sending a custom message to them (with SendMessage). In order to send a message I need a handle to the main window of the process.
This works fine using EnumWindows - as long as the instances are running under the same user account, because EnumWindows does not list windows belonging to a different user.
So I tried a different approach. I used CreateToolhelp32Snapshot to first list all running processes on the system, and then iterating through the threads calling CreateToolhelp32Snapshot again. With those thread ids I could then list their windows using EnumThreadWindows.
Once again this works fine, but.. once again only for the current logged in user. The problem here is that even though CreateToolhelp32Snapshot lists process ids belonging to a different user it does not list thread ids belonging to them. The code for this is a little lengthy, but if it's required I can edit it in - please leave a comment for that.
So, how could I get the main window handle of my application running on a different logged in user account?
Use something that's known to work across sessions; This kind of stuff is often used for desktop-service communications, so look for that if you want to google. Here's my suggestion:
Create an event that will only be used to trigger the "need to shut down" state. Use the CreateEvent function make sure you start your name with Global\ so it's valid across sessions.
On application startup create a thread that opens the named event (uses the same CreateEvent function, pay close attention to the ERROR_ALREADY_EXISTS non-error). That thread should simply wait for the event. When the event is triggered, send the required message to your main window. That thread can easily and safely do that because it's running inside your process. The thread will mostly be idle, waiting for the event to be triggered, so don't worry about CPU penalty.
Your application updateer should simply trigger the named event.
This is just one idea, I'm sure there are others.
Pipes are overkill. A global manual-reset event (e.g. "Global\MyApplicationShutdownEvent") which causes application instances to kill themselves should be enough.
At the risk of being scoffed at, have you looked at zeroMQ, this is a perfect use for it and it very reliable and stable.
There is a Delphi wrapper

Waiting for applications to finish loading [duplicate]

I have an application which needs to run several other applications in chain. I am running them via ShellExecuteEx. The order of running each of the apps is very important cause they are dependant on each other. For example:
Start(App1);
If App1.IsRunning then
Start(App2);
If App2.IsRunning then
Start(App3);
.........................
If App(N-1).IsRunning then
Start(App(N));
Everything works fine but there is a one possible problem:
ShellExecuteEx starts the application, and return almost immediately. The problem might arise when for example App1 has started properly but has not finished some internal tasks, it is not yet ready to use. But ShellExecuteEx is already starting App2 which depends on the App1, and App2 won't start properly because it needs fully initialized App1.
Please note, that I don't want to wait for App(N-1) to finish and then start AppN.
I don't know if this is possible to solve with ShellExecuteEx, I've tried to use
SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;
but without any effect.
After starting the AppN application I have a handle to the process. If I assume that the application is initialized after its main window is created (all of Apps have a window), can I somehow put a hook on its message queue and wait until WM_CREATE appears or maybe WM_ACTIVATE? In pressence of such message my Application would know that it can move on.
It's just an idea. However, I don't know how to put such hook. So if you could help me in this or you have a better idea that would be great:)
Also, the solution must work on Windows XP and above.
Thanks for your time.
Edited
#Cosmic Prund: I don't understand why did you delete your answer? I might try your idea...
You can probably achieve what you need by calling WaitForInputIdle() on each process handle returned by ShellExecute().
Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.
If your application has some custom initialization logic that doesn't run in UI thread then WaitForInputIdle might not help. In that case you need a mechanism to signal the previous app that you're done initializing.
For signaling you can use named pipes, sockets, some RPC mechanism or a simple file based lock.
You can always use IPC and Interpocess Synchronization to make your application communicate with (and wait for, if needed) each other, as long as you code both applications.

Resources