Re: CreateFile() to the same file as the .exe
"John Carson" <jcarson_n_o_sp_am_@netspace.net.au> wrote in message
news:et%23lUKMbGHA.404@TK2MSFTNGP04.phx.gbl...
"Jim Langston" <tazmaster@rocketmail.com> wrote in message
news:kYc5g.245$TI7.0@fe05.lga
I'm trying to use CreateFile() on the .exe that is calling the
CreateFile, and it is failing, no real surpise there. So I need to
find a work around.
What I am doing is writing an autoupdater for my game. It downloads
a file from the internet with version and zip file information,
compares the one on the local machine and adds to a set which files
to download. I then download each file from a web site. Then I
extract the zip files.
Everything is working except when my upzip class tries to extract to
the same file as the running program, the updater itself. CreateFile
fails.
So I need to find some work around for this and am not sure the best
method.
The only thing I can think of is running my launcher in a batch file,
and if it actually attempts to extract the same file as the launcher
(Abyssal.exe) to actually extract it as some other name (say
Abyssal.exe.tmp), and return from the program with a non zero result.
Then the batch file can check the returned value, see it's not zero,
and do a copy Abyssal.exe.tmp Abyssal.exe then run Abyssal.exe again.
I don't like the idea of running it from a batch file, however, and
was wondering how other auto updaters handled this.
Another method, I guess, is to create a very short .exe that simply
copies Abyssal.exe.tmp to Abyssal.exe then launches Abyssal.exe,
which Abyssal.exe could do itself using CreateProcess(). Does anyone
have any other, maybe better, ideas?
See here for a description of how Microsoft does it (at least with one of
their technologies):
http://windowsforms.net/articles/appupdater.aspx
I've got something cobbled together which seems to be working so far
although I'm not 100% complete. It's a modification of the first method
they tried.
When trying to update Abyssal.exe the file in the zip is actually
Abyssal.exe.new. The first thing that Abyssal.exe does when it runs is
checks for the existance of this file .new If it exists it spawns a process
using CreateProcess which runns AbyssalInit.exe and immediately returns.
AbyssalInit.exe checks for the existance of Abyssal.exe.new. If it exists
it makes sure the read-only attribute of Abyssal.exe is not set, then copys
using copyfile from Abyssal.exe.new to Abyssal.exe, then it runs
CreateProcess and runs Abyssal.exe
The only problems I can forsee with this is if Abyssal.exe does not end
quick enough after it spawns the process for AbyssalInit.exe, because if
it's still open the copyfile will fail. In my initial tests it's exiting
soon enough. However, deeper down in the program after I unzip the zip
files I'll want to look for Abyssal.exe.new and if it exists do the whole
thing again, spawning AbyssalInit.exe, but at this point Abyssal.exe will
have created many resources that will take time to be cleared out by the
destructors. I don't know if it will return in time to be copied over. If
this happens, I'll need to check for a running instance of Abyssal.exe and
wait until it closes before doing the copy file.
I must say, autoupdaters are a real pain. There are so many things that can
go wrong that have to be checked every step of the way to not hoze the
clients installation.
Download the manifest. Was it found?
Compare against existing manifest, does existing manifest exist?
Build a list of .zip files to download
Download the zipfiles, were they all found?
Unzip the zipfiles, was it successful?
Was the autoupdater itself effected?
Like I say, not easy. I looked for an opensource autoupdater and it wasn't
there. So I think when I'm finished with this thing I'll stick it up on
sourceforge or something.