2

I have got a program which checks if there's a version update on the server. Now I have to do something like

if(update_avail) {
    system("updater.exe");
    exit(0);
}

but without waiting for "updater.exe" to complete. Otherwise I can't replace my main program because it is running. So how to execute "updater.exe" and immediately exit? I know the *nix way with fork and so on, how to do this in Windows?

Mat
  • 202,337
  • 40
  • 393
  • 406
gorootde
  • 4,003
  • 4
  • 41
  • 83
  • possible duplicate of [What is the closest thing windows has to fork()?](http://stackoverflow.com/questions/985281/what-is-the-closest-thing-windows-has-to-fork) – CharlesB Feb 06 '12 at 13:38

3 Answers3

5

Use CreateProcess(), it runs asynchronously. Then you would only have to ensure that updater.exe can write to the original EXE, which you can do by waiting or retrying until the original process has ended. (With a grace interval of course.)

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
4

There is no fork() in Win32. The API call you are looking for is called ::CreateProcess(). This is the underlying function that system() is using. ::CreateProcess() is inherently asynchronous: unless you are specifically waiting on the returned process handle, the call is non-blocking.

There is also a higher-level function ::ShellExecute(), that you could use if you are not redirecting process standard I/O or doing the waiting on the process. This has an advantage of searching the system PATH for the executable file, as well as the ability to launch batch files and even starting a program associated with a document file.

0

You need a thread for that Look here: http://msdn.microsoft.com/en-us/library/y6h8hye8(v=vs.80).aspx You are currently writing your code in the "main thread" (which usually is also your frame code). So if you run something that takes time to complete it will halt the execution of your main thread, if you run it in a second thread your main thread will continue.

Update: I've missed the part that you want to exit immediately. execl() is likely what you want.

#include <unistd.h>

int main(){

    execl("C:\\path\\to\\updater.exe", (const char *) 0);
    return 0;
}

The suggested CreateProcess() can be used as well but execl is conforming to POSIX and would keep your code more portable (if you care at all).

#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);

Update: tested on Win-7 using gcc as compiler

John
  • 7,507
  • 3
  • 52
  • 52
  • 1
    First, execl() is not part of Windows as far as I know, second, would you not need fork() too? These exist as far as I know on Windows only in Cygwin and MKS. – Prof. Falken Feb 06 '12 at 14:30
  • I've tested the code on Windows using GCC as compiler, worked fine that way. I don't have Visual C++ installed but why should they not support it, usually that works too ? fork() is another sort of thread (unix flavored and simple thread). execl replaces the process image with a new one. As I understood OP that was what he tried to do. – John Feb 06 '12 at 14:46
  • The GCC you use does not happen to be Cygwin? There are many references out there, but to give an SO one: http://stackoverflow.com/questions/23397/whats-the-best-way-to-duplicate-fork-in-windows – Prof. Falken Feb 06 '12 at 14:49
  • No, it's a normal mingw gcc compiler. I'd say pretty standard. Is my example not working for you ? – John Feb 06 '12 at 14:51
  • That code is not portable. On UNIX you have to have a fork() before it, or you will still use the same process and lock the exe. On Windows it seems to sort of possibly work, but only by accident. See for instance http://mingw-users.1079350.n2.nabble.com/fork-waitpid-and-setpid-td5731789.html Also execl() is not a Windows API, but something probably Mingw is adding. The link to MSDN you have provided says nothing about execl(), I don't know why you have included it. I haven't tested your code, I don't have the tools right now. Have YOU tested it in Visual Studio? I think execl() is mingw only – Prof. Falken Feb 06 '12 at 14:57
  • The user wanted to have his program to execute updater.exe and close without waiting. Using execl() exactly this will happen. execl() will execute updater.exe and the original program will not exist anymore because updater.exe is being moved into the process. It works on windows and linux that way. I don't use Visual Studio, I doubt it's not supporting it but does OP even use it ? – John Feb 06 '12 at 15:13
  • How do you know what OP is using? It only says Windows, not which compiler. Then only Windows APIs should be suggested. execl() will maybe update on Linux, but I am not sure about that. You could get "textfile busy". It will possibly work on Windows, but only because execl() *semantics* is different on Mingw than on Linux/POSIX. Did you read that link I gave you above? I will not argue this further... – Prof. Falken Feb 06 '12 at 15:17
  • You can not get "textfile is busy" because the file is not touched, it's the memory image that is replaced! About your link: setpid() is required for launching a forked application into the background which is NOT what happens when you use execl() because execl is not intended to be used in a forked process. I'm not even sure if that would work well. – John Feb 06 '12 at 15:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7389/discussion-between-amigable-clark-kant-and-john) – Prof. Falken Feb 06 '12 at 15:21