FAQ:WinAPI VCPP:самообновление запущенной программы
Материал из Весельчак У
Версия от 16:03, 3 октября 2009; RXL (обсуждение | вклад) (Новая: ===Каким способом exe файл может заменить самого себя?=== К примеру, программа должна обновляется через In...)
Каким способом 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(); } // ... // ... }