Форум программистов, компьютерный форум CyberForum.ru

Как правильно сделать самообновление программы? - C++

Восстановить пароль Регистрация
 
hknower
0 / 0 / 0
Регистрация: 04.01.2014
Сообщений: 55
04.05.2014, 15:44     Как правильно сделать самообновление программы? #1
Добрый день

Есть программа которая должна обновляться
Для ясности:
Файл программы старой версии - PROGRAM_NAME
Файл программы новой версии - PROGRAM_NAME_NEW
Решил разделить обновление на 2 этапа:

1) Старая версия программы (PROGRAM_NAME) запускает файл с новой версией программы (PROGRAM_NAME_NEW) с параметром update_stage_1:
Новая версия программы копирует свое содержимое в файл старой программы и запускает его с параметром update_stage_1
2) Запущенная уже обновленная программа (PROGRAM_NAME) удаляет PROGRAM_NAME_NEW/

Написал код, но непонятно что в нем неработает((

По-идее чтобы проверить код нужно чтобы в каталоге лежало 2 собранные программы.
test.exe собранная с PROGRAM_VERSION = 1
test_upated.exe собранная с PROGRAM_VERSION = 2

и запустить "test.exe update"

Где-то не отрабатывает. Подскажите пожалуйста где я ошибыюсь

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "stdafx.h"
#include <windows.h>
 
#define PROGRAM_VERSION         1
#define PROGRAM_NAME            L"test.exe"
#define PROGRAM_NAME_NEW        L"test_updated.exe"
 
HANDLE process_start(wchar_t* filepath , wchar_t* params);
void updating(wchar_t* argv_1);
 
int _tmain(int argc, _TCHAR* argv[])
{
    
    if(argc > 1)
    {
        updating(argv[1]);
        return 0;
    }
 
    printf("\nprogram_version=%d\n" , PROGRAM_VERSION);
 
    return 0;
}
 
void updating(wchar_t* argv_1)
{
    
    //Если хотим обновиться. Код запускается в программе которая требует обновление
    if(!wcscmp(argv_1 , L"update"))
    {
        //Тут обновление например скачивается из интернета и складывается в PROGRAM_NAME_NEW
        
        //Запускаем новую версю программы с параметром первого этапа обновления
        process_start(PROGRAM_NAME_NEW , L"update_stage_1");
        return ;
    }
 
    //Этот код отрабатывает в новой версии программы (test_new.exe)
    if(!wcscmp(argv_1 , L"update_stage_1"))
    {
        //Копируем содержимое себя (свего файла на диске - test_new.exe) в test.exe и 
        //запускаем test.exe с параметром update_stage_2
        long updater_len = 0;
        char* update_content = NULL;
 
        printf("\nupdate_stage_1");
 
        //Загружаем в память содержимое самого себя
        FILE* updater_fd = _wfopen(PROGRAM_NAME_NEW , L"rb");
 
        //Если не смогли открыть свой файл-выходим
        if(!updater_fd)
            return ;
 
        fseek(updater_fd , 0 , SEEK_END);
        updater_len = ftell(updater_fd);
        fseek(updater_fd , 0 , SEEK_SET);
        
        update_content = (char*)malloc(updater_len);
        fread(update_content , sizeof(char) , updater_len , updater_fd);
        fclose(updater_fd);
 
        //Записываем себя в оригинальный файл
        FILE* target_updater;
        while((target_updater = _wfopen(PROGRAM_NAME , L"wb")) == 0)
        {
            Sleep(1000);
        }
 
        fwrite(update_content , sizeof(char) , updater_len , target_updater);
        fclose(target_updater);
        
        //Запускаем уже обновленную программу с парметром update_stage_2 и завершаем работу
        process_start(PROGRAM_NAME , L"update_stage_2");
        return ;
    }
 
    //Этот код выполняется уже в обновленной программе
    if(!wcscmp(argv_1 , L"update_stage_2"))
    {
        //Удаляем PROGRAM_NAME_NEW
 
        printf("\nupdate_stage_2");
        
        while(DeleteFile(PROGRAM_NAME_NEW) == 0)
        {
            Sleep(1000);
        }
 
        return ;
    }
 
    //Если запускать с левыми парметрами просто будет прекращать работу
    return ;
}
 
HANDLE process_start(wchar_t* filepath , wchar_t* params)
{
 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 
    int bWait = 0;
    memset(&si,0,sizeof(si)); 
    si.cb = sizeof(si); 
    si.dwFlags = STARTF_USESHOWWINDOW; 
    si.wShowWindow = SW_HIDE; 
    
    if(CreateProcess(filepath , params , NULL , NULL, FALSE , CREATE_NEW_CONSOLE , NULL , NULL , &si , &pi))
    { 
        if (bWait) WaitForSingleObject(pi.hProcess, INFINITE);
            CloseHandle( pi.hProcess ); 
            CloseHandle( pi.hThread ); 
    } else{return 0;}
 
    return pi.hProcess;
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14213 / 6228 / 988
Регистрация: 02.05.2013
Сообщений: 10,385
Завершенные тесты: 1
04.05.2014, 21:13     Как правильно сделать самообновление программы? #2
Цитата Сообщение от hknower Посмотреть сообщение
Новая версия программы копирует свое содержимое в файл старой программы и запускает его с параметром update_stage_1
1) Давайте предположим стандартную ситуацию: ваша программа
установлена в Program Files, как и подобает "нормальным" программам.
А права на запись туда имеют только администраторы и система.
Что будете делать ? Требовать повышения прав до администратора
каждый раз при запуске ? Или сделаете невозможным обновление
программы неадминистраторами ? Или напишете службу, которая
выполняет обновление, действуя от имени системы ?

2) Перезаписать запущенный exe нельзя, сначала нужно остановить
его выполнение.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
04.05.2014, 21:26     Как правильно сделать самообновление программы? #3
Я предлагаю не компостировать мозг и выделить обновляемые части программы в подгружаемые dll. Также хороший вариант использовать скрипты(например на пайтоне) и подгружать их по мере обновления!
newbie666
Заблокирован
04.05.2014, 21:53     Как правильно сделать самообновление программы? #4
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Я предлагаю не трахать мозг и выделить обновляемые части программы в подгружаемые dll
полностью поддерживаю. Екзешник должен быть минимального размера, все функциональные модели - в отдельных dll_ках...
Если не хочешь так делать - гоу по классической схеме, делаешь какой - то дополнительный к своей программе экзешник, типа updater.exe, в основной программе по мере необходимости запускаешь этот апдейтер, посылаешь ему какой - нибуть мессаг, типа "готовься" и проверяй меня, как только я закроюсь - перезаписывай меня новой версией :-)
Но пять же, это если доступ на запись есть - иначе вообще собственно никак не обновишь
ValeryS
Модератор
6377 / 4843 / 442
Регистрация: 14.02.2011
Сообщений: 16,057
04.05.2014, 22:02     Как правильно сделать самообновление программы? #5
тут есть еще и такой аспект
пользователь не любит когда без его ведома кто то что то правит в системе
кстати по классификации УК РФ это вирус
1. Создание программ для ЭВМ или внесение изменений в существующие программы, заведомо приводящих к несанкционированному уничтожению, блокированию, модификации либо копированию информации, нарушению работы ЭВМ, системы ЭВМ или их сети, а равно использование либо распространение таких программ или машинных носителей с такими программами -
наказываются лишением свободы на срок до трех лет со штрафом в размере до двухсот тысяч рублей или в размере заработной платы или иного дохода осужденного за период до восемнадцати месяцев.
2. Те же деяния, повлекшие по неосторожности тяжкие последствия, -
наказываются лишением свободы на срок до семи лет.
выделено мной
http://www.az-design.ru/Projects/AZL.../ukrf273.shtml
значит вопрос о самомодификации программы без участия пользователя снимается
а если пользователь будет знать, зачем огород городить?
Убежденный
Системный программист
 Аватар для Убежденный
14213 / 6228 / 988
Регистрация: 02.05.2013
Сообщений: 10,385
Завершенные тесты: 1
04.05.2014, 22:08     Как правильно сделать самообновление программы? #6
Цитата Сообщение от ValeryS Посмотреть сообщение
пользователь не любит когда без его ведома кто то что то правит в системе
То, что программа что-то меняет, можно указать в стандартном license agreement.
Но тут другой момент - его никто не читает
Yandex
Объявления
04.05.2014, 22:08     Как правильно сделать самообновление программы?
Ответ Создать тему
Опции темы

Текущее время: 00:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru