问题
I'm using Microsoft Visual Studio 2008 with a Windows target deployment. How would I make a file "update itself"? I've already got the "transmitting over a network" part down, but how do I make an executable write over itself?
Basically, I want to write an auto-updater for a directory that also includes the auto-updater, and the updater needs to update EVERYTHING in the directory.
Maybe a ways to pend the changes to the file for until the file lock is released would work. If I were to do that though, I'd probably follow it up with a hot-patch.
回答1:
Write a new executable and delete or save a copy of the old one -- you could send a diff over the network and have a third program, the update monitor or whatever, to apply it. It would be just a small script that could be started from the remote app when it realizes an update is available. The updater could rename itself to $UPDATER_OLD_VERSION or whatever, write an updated copy of itself with the appropriate name, and then when the new updater is run you check if there is a file named $UPDATER_OLD_VERSION in the app directory and delete it. All other files could just be updated/overwritten.
回答2:
This is how I did it recently. There is a brief overlap of the old program running and the new programming running. It makes use of the trick that you can rename the current executable and bring the new file in place before you shut down the old one. This is not 100% fail safe, but the only way this could "brick" your application is if CopyFile fails.
#include <windows.h>
#include <iostream>
#include <fstream>
void UpgradeService::UpgradeSelf() {
std::string temp = root + "\\myprogram_tmp.exe";
remove(temp.c_str()); // ignore return code
std::string src = upgradeFolder + "\\myprogram.exe";
std::string dst = root + "\\myprogram.exe";
rename(dst.c_str(),temp.c_str());
CopyFile(src.c_str(),dst.c_str(),false);
static char buffer[512];
strcpy(buffer,dst.c_str());
/* CreateProcess API initialization */
STARTUPINFO siStartupInfo;
PROCESS_INFORMATION piProcessInfo;
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
siStartupInfo.cb = sizeof(siStartupInfo);
::CreateProcess(buffer, // application name/path
NULL, // command line (optional)
NULL, // no process attributes (default)
NULL, // default security attributes
false,
CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE,
NULL, // default env
NULL, // default working dir
&siStartupInfo,
&piProcessInfo);
::TerminateProcess( GetCurrentProcess(),0);
::ExitProcess(0); // exit this process
// this does not return.
}
回答3:
You cannot generally modify an app while it is running. You will need to close down the original program and modify it from another location.
回答4:
I do this using an InnoSetup setup.exe that is launched silently and shuts my app down before it starts installing the new files. I had to add custom Pascal [Code] sections to ensure everything shuts down but it does the job.
回答5:
You can't overwrite a file while it's executing, but you CAN rename it. In my updater, I rename the existing exe to something meaningful (oldname_dateandtime), then write the new copy in. Then auto-shut our system down and restart it from a service. When the app starts, it's the new version running.
回答6:
When I made a updater, I should separate the program several. The main reason was just same as what you want to do. Simply say, B updates target application plus A and A updates B. I tried to find another way but what I did was made extra small and simple updater. :(
回答7:
I think you are talking about file versions and updaters. As you said you need autoupdater.So you need to create a service which monitors your install directory and compares the file version on your disk with server.
Once mismatch happens you can ask latest data from server . If the files going to be replaced are in use you have to mark them for deletion / unregistration during next reboot and you can mention these using registry.
You can copy all files in cache and later during reboot copy them to install directory.
来源:https://stackoverflow.com/questions/1009356/how-do-i-make-a-file-self-update-native-c