views:

77

answers:

5

In an application I am developing (in C), a loader app must first be run before the main application is executed. I have made it so the main app runs the loader app as a child when it is launched in order to automate this task. This all works well, except for the fact that the loader app only needs to be run one time during the user's current login session in order for the main app to work correctly, and having to run it every time the main app executes is a real pain. So what I'm asking is: is there a way to check if the loader has already been run using some Windows or C functionality? Ideally something like this would be great, although I have no idea if it is even possible:

if(thisapp.exe hasBeenExecuted)
    return;
else
    spawnl(app_path, app_name, args, NULL);

Or maybe something like having the main app create a dummy file that acts as a flag when the loader is run. Then on subsequent executions, checking if the file exists and running the loader if it does not. The only problem with this is automating it so the dummy file is erased when the computer is turned off (is there a way to do this?).

Some clarification: I cannot edit the loader app or replicate its functionality in the main app, I did not write it.

Thanks in advance for any help

+2  A: 

There are a couple ways to do this.

Your application could add an entry to the Run key. This makes it guaranteed to run at least once per session, when the user logs on. You could pass it a special command line arg in this case to distinguish it from relaunches.

Another option could be to store your state in the current user hive, and create the key with the REG_OPTION_VOLATILE flag. This causes the key only to be stored in memory and will not be flushed to disk when the hive is unloaded, which should be when the user logs off.

Michael
A: 

One suggestion that I have seen used in the past is to run an application from the user-hive (i.e. registry) on load which deletes your file (or alternately, creates it). The advantage is that this can be as simple as a shell script (batch file) which runs during startup (or user profile load, depending on where you hook) and should under most cases be run once (either at startup, or at user login). If you chose login, it can (will) be run every time the user logs into the machine after having logged out.

You could do it on user log out as well, though this is somewhat less reliable since you do not always know the state of the machine when the hive is unloaded (it could be crashed, out of power, etc).

Its not a full proof way of doing it, and it will only work on windows, but under most normal usage scenarios it would work.

As an alternate trick, you could write a timestamp to a file and when you load up, get the timestamp and check to see if its less than the amount of time the current user has been logged on for. If it is then you can skip the load as it most likely occurred during the current users session.

Again there are some downsides to this, but it should work reasonably well as well.

GrayWizardx
+1  A: 

You could also use the atom functions without having to read/write an enormous file

http://msdn.microsoft.com/en-us/library/ms649053%28VS.85%29.aspx

Arthur Kalliokoski
This worked perfectly, thank you! This works well in Windows XP, but do you know if functionality is altered at all in any other Windows distributions?
Nick Aberle
I'd guess that the win32 stuff would be the same for NT upwards. There was atom stuff all the way back to Win 3.x but I don't remember if there were different parameters or not.Try this (should still work in XP as is)http://ghirai.com/hutch/files/win32hlp_big.zip
Arthur Kalliokoski
+1  A: 

What does the loader app do, that means it needs to be run first?

It seems to me that the right answer is to check and see if that has been done, since that's what you really care about. Anything else is likely to be fragile and break in corner cases.

Brooks Moses
A: 

I have implemented this in the past using a Mutex.

For example:

int main( int argc, char argv[][] )  
{
    // if Mutex exists
    // {
    //     Don't allow a second instance to run:
    //     Notify user, log something, etc.
    //     return 0;
    // }
    // else
    // {
    //     Create Mutex, this is the first time running
    // }

    // Rest of your program runs from here . . .
}

-bn

bn