FAQ:WinAPI VCPP:самообновление запущенной программы
Материал из Весельчак У
Каким способом exe файл может заменить самого себя?
К примеру, программа должна обновляется через Internet и хочет обновить свой exe-файл. Но так как он в данный момент запущен, это будет, естественно, невозможно сделать напрямую. Один из способов - сделать копию экзешника и из него обновиться
// путь к старому файлу
#define def_exeNAMEup "c:\\myprog_toupdate.exe"
// путь к новому файлу (уже "скачали":) )
#define def_exeNAMEdnld "c:\\myprog_downloaded.exe"
#define def_keyUdate "/update"
void CTESTFAQApp::UpdateItself()
{
// добыча полного имени экзешника
CString csFullExeName;
{
CString csAppName = GetCommandLine();
csAppName.Delete(0,1);
csAppName.Replace('\"', '\0');
csFullExeName = (const char*)csAppName;
}
// теперь csFullExeName - содержит искомый путь
// делаем копию экзешника с другим именем
CopyFile(csFullExeName, def_exeNAMEup, 0);
// передаём в параметры нового процесса ключ и путь к текущему файлу
CString csParams = def_keyUdate;
csParams += " ";
csParams += csFullExeName;
// запускаем копию
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(def_exeNAMEup, def_keyUdate, 0, 0, 0, 0, 0, 0, &si, &pi))
{
// завершаем текущий процесс
ExitFromMyApp();
}
}
void CTESTFAQApp::ExitFromMyApp()
{
exit(0);
}
BOOL CTESTFAQApp::InitInstance()
{
// смотрим, не запущено ли для апдейта?
CString txt;
txt = m_lpCmdLine;
if (txt.Find(def_keyUdate) == 0)
{
// делаем айдейт
txt.Replace(def_keyUdate, "");
txt.TrimLeft();
CString csFullExeName = txt;
// берём откуда то уже скачанный файл обновления
// ...
CString csFull_Downloaded_ExeName = def_exeNAMEdnld;
// копируем файл (обновляем старый то есть)
CopyFile(csFull_Downloaded_ExeName, csFullExeName, 0);
// запускаем обновлённого мученника
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(csFullExeName, 0, 0, 0, 0, 0, 0, 0, &si, &pi))
ExitFromMyApp();
}
// ...
// ...
}