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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
GBIT
11 / 11 / 1
Регистрация: 05.10.2011
Сообщений: 219
#1

Код для обновления своего .exe на новую версию - C++

12.09.2013, 21:27. Просмотров 582. Ответов 8
Метки нет (Все метки)

Раскрываю сабж:
есть программа.exe, она в автозагрузке, она работает,
допустим я пишу новую версию этой программы и теперь мне нужно обновить программу на новую версию .exe,
я даю команду на обновление этой программе, а далее нужна идея как построить алгоритм обновления?

варианта вижу 2:
1й, простой, вариант. (алгоритм и реализация мне ясна)
Кликните здесь для просмотра всего текста
По команде обновиться, запускается другая программа updater.exe,
а обновляемая программа.ехе завершает работу,
updater.exe удаляет программа.ехе,
копирует новую версию программа.ехе, запускает ее,
завершает работу, программа.ехе удаляет updater.exe


2й, непонятный мне в реализации, вариант.
По команде обновиться, программа.ехе по хэндлу как-то должна себя переименовать в программа(old).ехе
скопировать новую версию программа.ехе,
удалить программа(old).ехе,
ждать пока компьютер перезагрузится и с новой загрузкой ОС запустить уже свежую версию.

по 2му варианту у меня вопрос: реализуемо ли такое? как реализовать?

Не по теме:

не нужная инфа: программа обновляется по сети

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.09.2013, 21:27
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Код для обновления своего .exe на новую версию (C++):

Как в exe, добавить версию последнего commit из git - C++
Я пока сделал так Есть bat который получает номер коммита, вызывает питоновский скрипт, который меняет версию в файле (*.rc) на нужный...

Как не отключая обновления запретить замену ядра на более новую версию? - Windows XP
win xp, sp 3, лицензионка постоянно вылетает бсод на ядро ntoskrnl.exe версии 5.1.2600.6368 , если заменить на более ранюю все окау, но...

Переписать код светофора под новую версию среды - Pascal ABC
program svetofor; uses graphabc,timers,CRT,events; var sv1,sv2,sv3:Timer; procedure Timerprocext(n:integer); begin if...

Как программно нажать клавишу F5 для обновления рабочего стола из своего приложения? - C#
Есть ли метод или функция эмулирующая нажатие клавиши F5 для обновления рабочего стола? Или примерно такой способ, только кодом C#

Как изменить версию .NET своего решения - C#
Переключил в своем решении требуемую версию .NET на 4.5.1, а ZipFile все равно не могу использовать, подскажите где еще посмотреть

Google выпустил первую версию своего языка программирования Go - Язык Go
Cостоялся официальный релиз первой стабильной версии экспериментального открытого языка программирования Go компании Google. Открытый...

8
ParanoiS
0 / 0 / 0
Регистрация: 12.09.2013
Сообщений: 4
12.09.2013, 23:44 #2
2-й вар-т вполне реален, есть стандартные функции форточек - ShFileOperation, например (это для решения проблемы автоапдэйта при запуске системы). Только не надо проге саму себя переименовывать. Качаешь newversion, а далее... В Делфи - примерно так:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
implementation uses ShellAPI;
 
function Rename_NewFile_To_Himself (
  FileName: string                      // новый файл
): boolean;
var
  fo:TSHFileOpStruct;
begin
  with fo do begin
    wFunc := FO_RENAME;
    pFrom := PChar(FileName); // новая версия файла
    pTo   := PChar(ParamStr(0));        // старый файл, т.е сама прога
    fFlags:=FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;
  end;
 
  // не помню кодов возврата, см. Help
 
  Result:=SHFileOperation(fo) = 0 {???} ;
end;
ну и потОм - перезагружай.
0
GBIT
11 / 11 / 1
Регистрация: 05.10.2011
Сообщений: 219
13.09.2013, 19:44  [ТС] #3
ParanoiS, ShFileOperation() решает!
Цитата Сообщение от ParanoiS Посмотреть сообщение
Только не надо проге саму себя переименовывать
попробовал без переименования - ошибка доступа появляется. Вышел из ситуации именно переименованием.
C++
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
// ShFileOperation()
// [url]http://msdn.microsoft.com/en-us/library/windows/desktop/bb762164(v=vs.85).aspx[/url]
// SHFILEOPSTRUCT
// [url]http://msdn.microsoft.com/en-us/library/windows/desktop/bb759795(v=vs.85).aspx[/url]
#include <windows.h>
#include <stdio.h>
 
int main()
{
 // rename программы
    SHFILEOPSTRUCT mStruct;
    
    int err=0;
 
    //Дескриптор окна диалогового окна для отображения информации о состоянии операции над файлами
    mStruct.hwnd =                      0;
    //Значение, которое указывает, какую операцию выполнять. Один из следующих значений:
    mStruct.wFunc =                 FO_RENAME;
    //Источник
    mStruct.pFrom =                 L"C:\\ip\\pro\\test.exe";
    //Назначение
    mStruct.pTo =                   L"C:\\ip\\pro\\test(old).exe";
    //Флаги, которые контролируют операции над файлами. Этот элемент может принимать комбинацию из следующих флагов.
    mStruct.fFlags =                    FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI ;
    //
    //myStruct.fAnyOperationsAborted =  
    //После возврата из функции, этот элемент содержит дескриптор объекта отображения имен, содержащий старые и новые названия переименованных файлов.
    mStruct.hNameMappings =         0;
    //указатель на название диалогового окна прогресса. Это строка с завершающим нулем.
    //myStruct.lpszProgressTitle =
 
    err=SHFileOperation(&mStruct);
    printf("err=%i\n",err);
    if(err!=0)
        MessageBox(0,L"Ошибка1",0,0);
    
 
// copy новую версию программы  
    SHFILEOPSTRUCT myStruct;
    
 
 
    //Дескриптор окна диалогового окна для отображения информации о состоянии операции над файлами
    myStruct.hwnd =                     0;
    //Значение, которое указывает, какую операцию выполнять. Один из следующих значений:
    myStruct.wFunc =                    FO_COPY;
    //Источник
    myStruct.pFrom =                    L"C:\\ip\\test.exe";
    //Назначение
    myStruct.pTo =                      L"C:\\ip\\pro\\test.exe";
    //Флаги, которые контролируют операции над файлами. Этот элемент может принимать комбинацию из следующих флагов.
    myStruct.fFlags =                   FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI ;
    //
    //myStruct.fAnyOperationsAborted =  
    //После возврата из функции, этот элемент содержит дескриптор объекта отображения имен, содержащий старые и новые названия переименованных файлов.
    myStruct.hNameMappings =            0;
    //указатель на название диалогового окна прогресса. Это строка с завершающим нулем.
    //myStruct.lpszProgressTitle =
 
    err=SHFileOperation(&myStruct);
    printf("err=%i\n",err);
    if(err!=0)
        MessageBox(0,L"Ошибка2",0,0);
 
    return 0;
}
0
ParanoiS
0 / 0 / 0
Регистрация: 12.09.2013
Сообщений: 4
06.10.2013, 20:39 #4
Сорри, инета небыло.

На фига?? Ты не понял, ща объясню. Цитирую твой код с изменениями во флагах. Обрати внимание на FOF_RENAMEONCOLLISION.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Дескриптор окна диалогового окна для отображения информации о состоянии операции над файлами
    mStruct.hwnd =                      0;
    //Значение, которое указывает, какую операцию выполнять. Один из следующих значений:
    mStruct.wFunc =                 FO_RENAME /*можно и FO_MOVE*/ ;
    //Источник
    mStruct.pFrom =                 L"C:\\... новая версия ...\\test.exe";
    //Назначение
    mStruct.pTo =                   L"C:\\... старая ...\\test.exe";
    //Флаги, которые контролируют операции над файлами. Этот элемент может принимать комбинацию из следующих флагов.
    mStruct.fFlags =                    FOF_RENAMEONCOLLISION | FOF_NOCONFIRMATION | FOF_SILENT | FOF_NO_UI;
    //
    //myStruct.fAnyOperationsAborted =  
    //После возврата из функции, этот элемент содержит дескриптор объекта отображения имен, содержащий старые и новые названия переименованных файлов.
    mStruct.hNameMappings =         0;
    //указатель на название диалогового окна прогресса. Это строка с завершающим нулем.
    //myStruct.lpszProgressTitle = NULL;
 
    err=SHFileOperation(&mStruct);
После этого должно быть так: заносится запись в реестр (в 9х - в файл) о том что необходимо замениить ЗАНЯТЫЙ файл, тоесть замена произойдёт после перезагрузки (в NT и выше - при входе в аккаунт).

Кста, а чё за ошибка? Возможно, конфликт ANSI/Unicode. Проверил?
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,486
06.10.2013, 21:08 #5
Цитата Сообщение от GBIT Посмотреть сообщение
программа.ехе по хэндлу как-то должна себя переименовать в программа(old).ехе
нехороший вариант. Наверное, реализуемо, но зачем? Надо попроще что-то делать.
0
GBIT
11 / 11 / 1
Регистрация: 05.10.2011
Сообщений: 219
06.10.2013, 21:16  [ТС] #6
Остановился на варианте:
program.exe переименует файл с которого запустилась в program(old).exe
копирует новую версию program.exe
перезагрузка компа
запускается обновленная program.exe
ищет program(old).exe, если есть удаляет его

все на api функциях просто и легко
0
kravam
быдлокодер
1697 / 884 / 45
Регистрация: 04.06.2008
Сообщений: 5,486
06.10.2013, 21:33 #7
Можно сделать так. Имеем, к примеру programma.exe, которая должна обновляться программой new.exe

По сигналу "обновиться" programma.exe делает следующее:

1) проверяет текущую директорию на наличие файла new.exe. Можно обойтись и без этого шага, но тогда нужно быть уверенным, что файл new.exe ЕСТЬ в текущей директории

2) если new.exe в текущей директории есть, тогда programma.exe должна запустить process.exe Последний может идти отдельным файлом. Но если хочется (я бы так и сделал) файл process.exe может идти секцией к programma.exe

3) programma.exe благополучно заканчивает свою работу.

4) process.exe делает следующее: переименовывает new.exe в programma.exe и самоубивается, перед этим уничтожив файл process.exe. Это тонкое место: на XP такой номер у меня проходил, как на других осях, не знаю. Впрочем, есть вариант: файл process.exe уничтожается программой programma.exe. То есть programma.exe запускается и первое, что делает- проверяет текущую директорию на наличие файла process.exe и в случае наличия последнего удаляет его. Всё.

Добавлено через 1 минуту
Цитата Сообщение от GBIT Посмотреть сообщение
program.exe переименует файл с которого запустилась в program(old).exe
вот это меня интересует. Нельзя ли пример?
0
Убежденный
Ушел с форума
Эксперт С++
15689 / 7199 / 1138
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
06.10.2013, 21:49 #8
Цитата Сообщение от GBIT Посмотреть сообщение
допустим я пишу новую версию этой программы и теперь мне нужно обновить программу на новую версию .exe
И сразу главный вопрос - как гарантируется, что программа будет иметь
достаточно прав, чтобы перезаписать себя в соответствующей папке ?
Например, доступ в Program Files на запись, куда обычно ставятся программы,
есть только у системы и администраторов. А ставить софт в другие папки,
доступные на запись для юзеров - это значит создавать дыры в системе
безопасности Windows.
0
GBIT
11 / 11 / 1
Регистрация: 05.10.2011
Сообщений: 219
07.10.2013, 11:48  [ТС] #9
Цитата Сообщение от kravam Посмотреть сообщение
пример
C++
1
2
3
4
5
char programm[MAX_PATH]="program";
char oldProgramm[MAX_PATH]="program(old)";
 
rename(programm,oldProgramm);
CopyFileA("\\\\192.168.0.1\\lan\\programm.exe",programm,false);
Убежденный, программа валяется в папке документов пользователя, по этому с правами проблем нет. Согласен, что место, мягко говоря, не подходящее для софта. Но программа и не предназначена для пользователя. Она для удаленного администрирования.
0
07.10.2013, 11:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.10.2013, 11:48
Привет! Вот еще темы с ответами:

Переход на новую версию - 1С
Скажите пожалуйста, если надо перейти с 1С 7.7 на 8.2, то для этого нужно использоваь специалные обратоки или достаточно набрать адрес...

Проверка на новую версию.. - Delphi
Помогите реализовать автоматическую проверку на обновление программы через интернет. Чтобы при запуске программы информация с...

Переход на новую версию джанго - Python
Вообщем есть веб-приложение на django 1.3, появилась необходимость перехода на более новую 1.6, есть ли инструменты для таких вещей? Или...

AS 2.0 Перевод бильярда в новую версию as - ActionScript
Необходима помощь в переводе игры бильярд с ас 2.0 на ас 3.0 в долгу не останусь


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru