Like many program's updater I'm trying to make my own updater which will not allow users to run it by double click.
It can only be started from my main application by ShellExecute.
What should be the ideal approach for this ?
Printable View
Like many program's updater I'm trying to make my own updater which will not allow users to run it by double click.
It can only be started from my main application by ShellExecute.
What should be the ideal approach for this ?
Why on earth do you want people not to run a program??
Anyways, perhaps the updates that are running may not be launched by an exe, ever thought of that? :)
One thing you can do is add the updater.exe file to your main application resource as a bin resource when you will want to use it simply extract it to disc as exe, and launch it.
When it launched it will close your main application and will do whatever it takes for the update.
But keep in mind that each time you run the main application, make sure you delete the updater.exe so it won’t remain on the disc.
This thread might help. (it deals with bmp file but its the same thing for any type of file)
Cheers
Thats not my goal. Binding exe as resource with application - I did a lot earlier. You can find my old posts about this which helped other so this is not the way.
Im talking about the actual procedure which many software's updater uses. For example Garena (a virtual gaming client) updater uses the same mechanism. You cant run the updater by double clicking. It will show you error that "You can't run updater in this way."
Hmmm... Just a quick shot - there may be a far more elegant solution...
Why not simply define an undocumented command line option for the updater and pass that when invoking the updater from your main app? If the option is not present the updater refuses to run.
Yes thats a good idea. I will give a try and post here..
BTW. "hmm" is used in Germany too ?. I thought its only Indian shortcut to say "Yes" online.
hmm.. Okay
hmm, Sorry, my original post was not very helpful. I understood your question wrong. :blush:
Another option might be to have your installer check to see if your main app is already running. If not, issue an error, and close.
Viggy
Another (but similar) idea is to modify the environment variables passed to the child process when using CreateProcess to start your updater, to include a custom variable that your updater checks for.
This is one of the Microsoft-recommended ways to pass information from a parent process to a child process.
For an example, see "Changing Environment Variables" at http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx . Look at Example 2, which sends the child process an environment variable named "MyVariable".
Mike
So it would be logical to check in updater on its start what process ran it (by parent process id). And quit if it was not your main app. This is going to prevent from env variable frauds. :)Quote:
It can only be started from my main application by ShellExecute.
Nice idea Igor. But checking command line argument is much easier way. But of-course your procedure is more robust.
Anyways I stick to command line argument checking. A simple strcmp() can do it.
Why not just build your updater code as a DLL instead of an exe? That way, your main app would be able to run the updater but ordinary users wouldn't.
dll ?.. How a dll would kill and restart an application ?.
Similar to the suggestion by Mr Viggy. The updater could be written so that it would check for the existence of something that either got created or installed by the DLL. Because users can't run a DLL directly, this "something" could only exist if the main app triggered it. For example, the DLL could install a Windows service. Whenever the updater ran it would check to see if the service was running and would exit if it wasn't.
Or if the updater didn't need to have a GUI, the updater could be a service in its own right, installed by your main application or one of its DLLs.
The bottom line is that the updater needs to check for something that will only be present if the main app has somehow provided it. The main app can run a particular DLL which can be used to communicate between the main app and the updater. Or some other comms methodology could be set up (a pipe or socket connection maybe). Or the main app could install a Windows service. Or it could provide some undocumented command line parameters known only to it and the updater.
That's an excellent suggestion from Igor. It would allow you to write your installer as a DLL which your main app could spawn using rundll32. A power user (such as you) could also run it the same way (say, for testing purposes) but most average users wouldn't think of running it that way.
Yeah, nice idea Igor.
I will defining try it out, and sadly I didn't gracefully shutdown the main application. I used TerminateProcess.
Correct me where I am wrong.
Well, it's obvious. Your application surely have an Exit. So what's difficult in calling Exit on a signal from outside? In one of my projects I implemented the following: a dedicated thread starts and gets to wait on a named event. On waking up on the event the window message is sent to main window with the Exit command (menu command id in fact). Installer while running signals the event and waits until process quits. Nice and easy. Of course, the event is created for admin access only, and has a global namespace, as my main app is able to run both modes, interactive and service. ;)
Yes, my applications exit means a call to PostQuitMessage(0) and some cleanup codes. So I need to send a WM_QUIT message on receiving the signal.
Right ?
As long as some cleanup is required it would be better make the exit go usual way. If PostQuitMessage + cleanup occurs on WM_CLOSE, you need to send WM_CLOSE to your main window. Hope this is clear enough.