Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.88/40: Рейтинг темы: голосов - 40, средняя оценка - 4.88
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028

Как сохранить настройки программы в ехе-шник?

09.11.2011, 12:23. Показов 7767. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Сохранить какие-либо настройки в реестр либо ini-файл затруднений не вызывают.
Но, реестр трогать(засорять) своей прогой вообще не хочу, и прога в идеале должна быть в одном файле, без всяких ini.
Как поступить?
Вопрос проще: как вообще модифицировать ехе-шник им самим - запустился, изменился, записался на диск, пусть даже с помощью временного файла.
Есть идеи?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.11.2011, 12:23
Ответы с готовыми решениями:

Как получить ЕХЕ-шник из JAVA?
Доброго времни суток. Я конечно понимаю, что тема поднималась не раз, но толком я ничего так и не нашел. Я пишу программку в...

Как вставить внешнюю программу в свой ехе'шник
Проблема такова: мне нужно в программу добавить файл (уже готовый,отдельный exe'шник) Что бы при нажатии кнопки вылезала программа (тот...

Как подключить к проекту чужой ехе-шник в качестве dll?
Допустим, чужую dll-ку к своему проекту я подключить могу. Сейчас у меня имеется некая программа, ехе-шник, в котором есть экспортные...

21
1090 / 588 / 121
Регистрация: 11.11.2008
Сообщений: 1,544
09.11.2011, 14:01
глянь тут
Как хранить динамические данные в exe файле?
Где хранить id программы?
2
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028
11.11.2011, 10:34  [ТС]
Кароч, вот что получилось:
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
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
117
118
119
120
121
122
123
124
125
126
127
128
              //Добавление данных в EXE файл и их чтение
              // Unit1.cpp
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString MyProc = "Project1.exe", TempProc = "Project1.tmp";
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
TMemoryStream *MemoryStream = new TMemoryStream();
CopyFile (MyProc.c_str(),TempProc.c_str(),false);
if (LoadFromFile(TempProc.c_str(), MemoryStream))
    Memo1->Lines->LoadFromStream(MemoryStream);
//else ShowMessage("Fail");
MemoryStream->Free();
}
//---------------------------------------------------------------------------
 
bool __fastcall TForm1::AttachToFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{
int iSize;
if (!FileExists(AFileName)) return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenWrite || fmShareDenyWrite);
try
{
MemoryStream->Seek(0, soFromBeginning);
FileStream->Seek(0, soFromEnd);
FileStream->CopyFrom(MemoryStream, 0);
iSize = MemoryStream->Size + 4;
FileStream->Write(&iSize, 4);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{
int iSize=0;
if (!FileExists(AFileName))return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenReadWrite, fmShareExclusive  );
try
{
FileStream->Seek(-4, soFromEnd);
FileStream->Read(&iSize, 4);
if (iSize > FileStream->Size || iSize==0)
    {
    FileStream->Free();
    return false;
    }
FileStream->Seek(-iSize, soFromEnd);
MemoryStream->SetSize(int (iSize - 4));
MemoryStream->CopyFrom(FileStream, iSize - 4);
MemoryStream->Seek(0, soFromBeginning);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  TMemoryStream *aStream = new TMemoryStream();
  Memo1->Lines->SaveToStream(aStream);
  CopyFile (MyProc.c_str(),TempProc.c_str(),false);
  AttachToFile(TempProc.c_str(), aStream);
  aStream->Free();
  TStringList *StringList = new TStringList();
  StringList->Add("@ECHO OFF");
  StringList->Add(":return");
  StringList->Add("ping -n 1 -w 1000 127.0.0.1 >NUL"); // пауза 1 сек.
  StringList->Add("move " + TempProc + " " + MyProc + " >NUL");
  StringList->Add("IF EXIST " + TempProc + " goto return");
  StringList->Add("del " + TempProc + ".bat");
  StringList->SaveToFile(TempProc + ".bat");
  StringList->Free();
  ShellExecute(Handle, "open", (TempProc+ ".bat").c_str() , "" , NULL, SW_HIDE);
}
//---------------------------------------------------------------------------
 
 
 
////////////////////////////////Unit1.h
 
//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TMemo *Memo1;
    bool __fastcall AttachToFile(const AnsiString AFileName, TMemoryStream *aStream);
    bool __fastcall LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    //void __fastcall SaveClick(TObject *Sender)
private:    // User declarations
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Может, коряво, я не профи, зато работает.
Builder 2009.
1
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028
14.11.2011, 08:30  [ТС]
Исправил и дополнил )))
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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
              //Добавление данных в EXE файл и их чтение
              // Unit1.cpp
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString MyProc,          // имя компилируемого файла (Project1.exe)
TempProc = "Project1.tmp";  // временный файл, необходимый для чтения/записи
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
MyProc = ExtractFileName(Application->ExeName);     // получаем имя файла
                                                    // (даёт возможность переименовывать ехе-шник)
TMemoryStream *MemoryStream = new TMemoryStream();
CopyFile (MyProc.c_str(),TempProc.c_str(),false);   // создаём копию
if (LoadFromFile(TempProc.c_str(), MemoryStream))   // читаем данные
    Memo1->Lines->LoadFromStream(MemoryStream);
//else ShowMessage("Fail");
MemoryStream->Free();
}
//---------------------------------------------------------------------------
 
bool __fastcall TForm1::LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{                           // чтение данных из файла
int iSize=0;
if (!FileExists(AFileName))return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenReadWrite, fmShareExclusive  );
try
{
FileStream->Seek(-4, soFromEnd);                    // читаем последние 4 байта (int),
FileStream->Read(&iSize, 4);                        // содержащие размер данных
if (iSize > FileStream->Size || iSize==0)
    {
    FileStream->Free();
    return false;
    }
FileStream->Seek(-iSize, soFromEnd);                // встаём на начало данных
MemoryStream->SetSize(int (iSize - 4));             // читаем, без последнего int
MemoryStream->CopyFrom(FileStream, iSize - 4);
MemoryStream->Seek(0, soFromBeginning);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
 
bool __fastcall TForm1::AttachToFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{                           // добавление данных в файл
int iSize;
if (!FileExists(AFileName)) return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenWrite || fmShareDenyWrite);
try
{
MemoryStream->Seek(0, soFromBeginning);     // дописываем данные в конец файла
FileStream->Seek(0, soFromEnd);
FileStream->CopyFrom(MemoryStream, 0);
iSize = MemoryStream->Size + 4;             // дописываем int iSize, размер данных
FileStream->Write(&iSize, 4);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{                       // сохранение результата, удаление временных файлов
  TMemoryStream *aStream = new TMemoryStream();
  Memo1->Lines->SaveToStream(aStream);                          // собираем данные
  AttachToFile(TempProc.c_str(), aStream);                      // пишем в конец файла
  aStream->Free();
                        // создаём и запускаем bat файл
  TStringList *StringList = new TStringList();
  StringList->Add("@ECHO OFF");
  StringList->Add(":return");
  StringList->Add("ping -n 1 -w 1000 127.0.0.1 >NUL");          // пауза 1 сек.
  StringList->Add("move " + TempProc + " " + MyProc + " >NUL"); // удалить исходный файл,
                                                                // записать на его место модифицированный
  StringList->Add("IF EXIST " + TempProc + " goto return");     // повторить, если неудачно
  StringList->Add("del " + TempProc + ".bat");                  // bat файл самоудаляется
  StringList->SaveToFile(TempProc + ".bat");
  StringList->Free();
  ShellExecute(Handle, "open", (TempProc+ ".bat").c_str() , "" , NULL, SW_HIDE);
}
//---------------------------------------------------------------------------
 
 
////////////////////////////////Unit1.h
 
//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TMemo *Memo1;
        bool __fastcall AttachToFile(const AnsiString AFileName, TMemoryStream *aStream);
        bool __fastcall LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        //void __fastcall SaveClick(TObject *Sender)
private:        // User declarations
public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
2
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028
10.01.2013, 14:51  [ТС]
Проект приложил.
Вложения
Тип файла: rar AttachToExe.rar (4.29 Мб, 53 просмотров)
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
10.01.2013, 15:14
ад какой то... может использовать ресурсы?

Добавлено через 8 минут
FindResource
LoadResource
UpdateResource
?
0
 Аватар для t1m0n
638 / 416 / 27
Регистрация: 03.11.2009
Сообщений: 1,855
10.01.2013, 15:53
и как антивирусники такое не блочат?
0
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
10.01.2013, 17:40
Цитата Сообщение от vxg Посмотреть сообщение
ад какой то... может использовать ресурсы?

Добавлено через 8 минут
FindResource
LoadResource
UpdateResource
?
Можно тут поподробнее.
Сам пытаюсь разобраться с дозаписью в ехешник.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
10.01.2013, 19:07
Попробуйте с этим разобраться... . (Даже интересно... - вдруг получится!?)
1
+1
345 / 178 / 53
Регистрация: 24.08.2010
Сообщений: 1,028
10.01.2013, 20:45  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
ад какой то
Цитата Сообщение от t1m0n Посмотреть сообщение
и как антивирусники такое не блочат?
Ребят, единственная мысль после таких высказываний: <cenzored /> — не мешки ворочать.
Год уже тема висит, хоть бы кто помог.
А <cenzored /> — много ума не надо.
Извините.
1
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
11.01.2013, 16:24
Сохранить какие-либо настройки в реестр либо ini-файл затруднений не вызывают.
Но, реестр трогать(засорять) своей прогой вообще не хочу, и прога в идеале должна быть в одном файле, без всяких ini.
Как поступить?
Вопрос проще: как вообще модифицировать ехе-шник им самим - запустился, изменился, записался на диск, пусть даже с помощью временного файла.
Есть идеи?
Автор писал в C++ Builder 9:
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
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
              //Добавление данных в EXE файл и их чтение
              // Unit1.cpp
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString MyProc,          // имя компилируемого файла (Project1.exe)
TempProc = "Project1.tmp";  // временный файл, необходимый для чтения/записи
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
MyProc = ExtractFileName(Application->ExeName);     // получаем имя файла
                                                    // (даёт возможность переименовывать ехе-шник)
TMemoryStream *MemoryStream = new TMemoryStream();
CopyFile (MyProc.c_str(),TempProc.c_str(),false);   // создаём копию
if (LoadFromFile(TempProc.c_str(), MemoryStream))   // читаем данные
    Memo1->Lines->LoadFromStream(MemoryStream);
//else ShowMessage("Fail");
MemoryStream->Free();
}
//---------------------------------------------------------------------------
 
bool __fastcall TForm1::LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{                           // чтение данных из файла
int iSize=0;
if (!FileExists(AFileName))return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenReadWrite, fmShareExclusive  );
try
{
FileStream->Seek(-4, soFromEnd);                    // читаем последние 4 байта (int),
FileStream->Read(&iSize, 4);                        // содержащие размер данных
if (iSize > FileStream->Size || iSize==0)
    {
    FileStream->Free();
    return false;
    }
FileStream->Seek(-iSize, soFromEnd);                // встаём на начало данных
MemoryStream->SetSize(int (iSize - 4));             // читаем, без последнего int
MemoryStream->CopyFrom(FileStream, iSize - 4);
MemoryStream->Seek(0, soFromBeginning);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
 
bool __fastcall TForm1::AttachToFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
{                           // добавление данных в файл
int iSize;
if (!FileExists(AFileName)) return false;
TFileStream *FileStream = new TFileStream(AFileName, fmOpenWrite || fmShareDenyWrite);
try
{
MemoryStream->Seek(0, soFromBeginning);     // дописываем данные в конец файла
FileStream->Seek(0, soFromEnd);
FileStream->CopyFrom(MemoryStream, 0);
iSize = MemoryStream->Size + 4;             // дописываем int iSize, размер данных
FileStream->Write(&iSize, 4);
FileStream->Free();
return true;
}
catch (...)
    {
    FileStream->Free();
    return false;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{                       // сохранение результата, удаление временных файлов
  TMemoryStream *aStream = new TMemoryStream();
  Memo1->Lines->SaveToStream(aStream);                          // собираем данные
  AttachToFile(TempProc.c_str(), aStream);                      // пишем в конец файла
  aStream->Free();
                        // создаём и запускаем bat файл
  TStringList *StringList = new TStringList();
  StringList->Add("@ECHO OFF");
  StringList->Add(":return");
  StringList->Add("ping -n 1 -w 1000 127.0.0.1 >NUL");          // пауза 1 сек.
  StringList->Add("move " + TempProc + " " + MyProc + " >NUL"); // удалить исходный файл,
                                                                // записать на его место модифицированный
  StringList->Add("IF EXIST " + TempProc + " goto return");     // повторить, если неудачно
  StringList->Add("del " + TempProc + ".bat");                  // bat файл самоудаляется
  StringList->SaveToFile(TempProc + ".bat");
  StringList->Free();
  ShellExecute(Handle, "open", (TempProc+ ".bat").c_str() , "" , NULL, SW_HIDE);
}
//---------------------------------------------------------------------------

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
////////////////////////////////Unit1.h
 
//---------------------------------------------------------------------------
 
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TMemo *Memo1;
        bool __fastcall AttachToFile(const AnsiString AFileName, TMemoryStream *aStream);
        bool __fastcall LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream);
        void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
        //void __fastcall SaveClick(TObject *Sender)
private:        // User declarations
public:         // User declarations
        __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Написал этот же код в Builder 6, создает копию, но не выполняет LoadFromFile(...)
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
11.01.2013, 16:39
C++
1
bool __fastcall TForm1::LoadFromFile(const AnsiString AFileName, TMemoryStream *MemoryStream)
- может, обозвать иначе?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
11.01.2013, 16:41
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от +1 Посмотреть сообщение
не мешки ворочать
согласен. стало интересно, полистал, действительно необычная задача, решение в файле.
Вложения
Тип файла: rar res_test.rar (200.2 Кб, 109 просмотров)
6
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
11.01.2013, 16:42
...при желании читайте/пишите ресурсы через поток.
1
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
11.01.2013, 16:59
Цитата Сообщение от vxg Посмотреть сообщение
...при желании читайте/пишите ресурсы через поток.
То-есть получается могу сделать запись в любом из ресурсов ехешника и потом вытянуть оттуда?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
11.01.2013, 18:02
да. однако сделать это с запущенной программой нельзя. поэтому в проекте делаются "движения". кроме того у меня не вышло добавить свой ресурс - пришлось писать в уже существующий.

Добавлено через 1 минуту
...точнее добавить ресурс я смог. я даже вижу его при перечислении имен. но открыть его не могу - поиск ресурса завершается неудачей

Добавлено через 2 минуты
...естественно разумно писать в свои ресурсы, а не в существующие (например, в файл формы)
1
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
11.01.2013, 18:44
Можно добавить комментарии, просто в программе многие вещи непонятны.
Там ведь идет обращение к ресурсам программы, но где, куда и как это происходит, а так же сохранение не до конца понятны.
И я так понял, можно записывать в ресурсы ехешника и потом к ним обращаться?
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
11.01.2013, 19:52
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
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
 
#include "main_form_unit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tmain_form *main_form;
//---------------------------------------------------------------------------
#include "global.h"
//---------------------------------------------------------------------------
static void close_app(const char *form_class)
{
    HWND hwnd = FindWindow(form_class, 0); //находим окно программы по имени класса
    if (hwnd)
    {
        DWORD id_proc;
        GetWindowThreadProcessId(hwnd, &id_proc); //получаем ID процесса программы
        if (id_proc)
        {
            HANDLE h_proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id_proc); //получаем хэндл процесса программы
            if (h_proc)
            {
                SendMessage(hwnd, WM_CLOSE, 0, 0); //посылаем окну программы сообщение "закрыть"
                WaitForSingleObject(h_proc, INFINITE); //ожидаем завершение процесса программы
                CloseHandle(h_proc); //закрываем хэндл процесса программы
            }
        }
    }
}
//---------------------------------------------------------------------------
__fastcall Tmain_form::Tmain_form(TComponent* Owner)
        : TForm(Owner)
{
    if (ExtractFileExt(Application->ExeName) == ".tmp") //если запущен tmp-файл то...
    {
        while (true)
        {
 
        close_app(EXE_FORM_CLASS); //закрываем exe-файл
 
        AnsiString exe = ChangeFileExt(Application->ExeName.c_str(), ".exe");
        if (!CopyFile(Application->ExeName.c_str(), exe.c_str(), FALSE)) //копируем tmp- в exe-файл
        {
            Application->MessageBox(("Can not copy file (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        STARTUPINFO si;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
 
        PROCESS_INFORMATION pi;
 
        if (!CreateProcess(exe.c_str(), 0, 0, 0, FALSE, 0, 0, 0, &si, &pi)) //запускаем exe-файл
        {
            Application->MessageBox(("Can not create process (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
 
        break;
        } //while (true)
 
        //выходим из программы
        can_close = true;
        Close();
        Application->Terminate();
    }
    else
    {
        close_app(TMP_FORM_CLASS); //закрываем tmp-файл
 
        AnsiString tmp = ChangeFileExt(Application->ExeName.c_str(), ".tmp");
        if (FileExists(tmp)) //если есть tmp-файл то...
        {
            DeleteFile(tmp); //удаляем его
 
            //выходим из программы
            can_close = true;
            Close();
            Application->Terminate();
        }
        else
        {
            Visible = true; //иначе - обычный запуск: показываем окно программы
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall Tmain_form::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    strcpy(Params.WinClassName, ExtractFileExt(Application->ExeName) == ".tmp"? TMP_FORM_CLASS : EXE_FORM_CLASS); //устанавливаем класс окна в зависимости от расширения
}
//---------------------------------------------------------------------------
void __fastcall Tmain_form::read_valClick(TObject *Sender)
{
    HMODULE h_m = LoadLibrary(Application->ExeName.c_str()); //загружаем модуль
    if (!h_m)
    {
        Application->MessageBox(("Can not load module (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
    }
    else
    {
        while (true)             
        {
 
        HRSRC h_res = FindResource(h_m, id->Text.c_str(), RT_RCDATA); //ищем ресурс
        if (!h_res)
        {
            Application->MessageBox(("Can not find resource (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        HGLOBAL h_b = LoadResource(h_m, h_res); //загружаем ресурс
        if (!h_b)
        {
            Application->MessageBox(("Can not load resource (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        void *p = LockResource(h_b); //блокируем ресурс (получаем указатель на содержимое ресурса)
        if (!p)
        {
            Application->MessageBox("Can not lock resource (error UNKNOWN)", "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        val->Text = AnsiString((char *)p, SizeofResource(h_m, h_res)); //выводим содержимое ресурса в текстовом виде
 
        break;
        } //while (true)
 
        if (!FreeLibrary(h_m)) //выгружаем модуль
        {
            Application->MessageBox(("Can not free module (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall Tmain_form::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    CanClose = can_close; //первое получение сообщения "закрыть" не приводит к закрытию, оно приводит к тому что мы...
 
    if (!can_close)
    {
        can_close = true;
 
        while (true)
        {
 
        AnsiString tmp = ChangeFileExt(Application->ExeName.c_str(), ".tmp");
        if (!CopyFile(Application->ExeName.c_str(), tmp.c_str(), FALSE)) //копируем exe- в tmp-файл
        {
            Application->MessageBox(("Can not copy file (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        HANDLE h = BeginUpdateResource(tmp.c_str(), FALSE); //начинаем изменение ресурсов
        if (!h)
        {
            Application->MessageBox(("Can not begin update resource (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        if (!UpdateResource(h, RT_RCDATA, id->Text.c_str(), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), val->Text.c_str(), val->Text.Length() + 1)) //изменяем ресурс
        {
            Application->MessageBox(("Can not update resource (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        if (!EndUpdateResource(h, FALSE)) //запоминаем изменения
        {
            Application->MessageBox(("Can not end update resource (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        STARTUPINFO si;
        ZeroMemory(&si, sizeof(STARTUPINFO));
        si.cb = sizeof(STARTUPINFO);
 
        PROCESS_INFORMATION pi;
 
        if (!CreateProcess(tmp.c_str(), 0, 0, 0, FALSE, 0, 0, 0, &si, &pi)) //запускаем tmp-файл
        {
            Application->MessageBox(("Can not create process (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
            break;
        }
 
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
 
        break;
        } //while (true)
    }
}
//---------------------------------------------------------------------------
static BOOL CALLBACK ef
(
    HANDLE hModule, // resource-module handle
    LPCTSTR lpszType,   // pointer to resource type
    LPTSTR lpszName,    // pointer to resource name
    LONG lParam     // application-defined parameter
)
{
    main_form->names->Lines->Add(lpszName); //выводим имена ресурсов
    return TRUE;
}
//---------------------------------------------------------------------------
void __fastcall Tmain_form::read_namesClick(TObject *Sender)
{
    names->Clear();
    
    HMODULE h_m = LoadLibrary(Application->ExeName.c_str()); //загружаем модуль
    if (!h_m)
    {
        Application->MessageBox(("Can not load module (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
    }
    else
    {
        if (!EnumResourceNames(h_m, RT_RCDATA, (ENUMRESNAMEPROC)ef, 0)) //перечисляем ресурсы
        {
            Application->MessageBox(("Can not enum resource names (error " + IntToStr(GetLastError()) + ")").c_str(), "Warning", MB_OK | MB_ICONEXCLAMATION);
        }
    }
}
//---------------------------------------------------------------------------
 
 
void __fastcall Tmain_form::namesDblClick(TObject *Sender)
{
    id->Text = names->SelText;
}
//---------------------------------------------------------------------------
Добавлено через 2 минуты
...при перечислении ресурсов забыл модуль выгрузить

Добавлено через 7 минут
технология такая. читаются ресурсы традиционным способом. записываются так:
-создаем копию программы
-меняем в ней ресурсы
-запускаем копию
-при запуске копии ищем основную программу
-посылаем ей сообщение закрыться
-ожидаем завершения программы
-копируем... копию (ну а как еще сказать ) в файл основной программы
-запускаем основную программу
-завершаем работу копии
-она ищет копию, посылает ей сообщение завершиться и ожидает завершения (если к тому времени копия еще жива)
-если основная программа находит файл копии она считает что это "служебный" запуск для "зачистки" - удаляем копию и завершаем работу
-если основная программа не находит файл копии она считает это обычным запуском - показывает основную форму
----
в принципе можно попасть на грабли - exe-файл удалится и останется tmp-файл... может даже недописанный. так же может быть опасным запуск копий программы.

Добавлено через 4 минуты
...еще в принципе можно завершать работу основной программы при запуске копии - тогда ей не придется долго ждать завершения основной программы (но close_app для безопасности вызывать обязательно).
...и наверное логичнее после запуска копии не закрывать ее, а оставлять это дело на совести основной программы
1
5 / 5 / 3
Регистрация: 18.10.2011
Сообщений: 156
19.01.2013, 20:29
У меня никак не заработает...
при завершении постоянно выскакивает "Stream Read Error"
0
Модератор
 Аватар для vxg
3409 / 2180 / 354
Регистрация: 13.01.2012
Сообщений: 8,458
19.01.2013, 22:49
Цитата Сообщение от Shalesbeer Посмотреть сообщение
не заработает
что?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.01.2013, 22:49
Помогаю со студенческими работами здесь

Как сохранить настройки программы в файл
Подскажите пожалуйста.Как сохранить настройки программы в какой либо файл и при следующем запуске программы загружать их?

Как сохранить настройки при закрытии программы?
Я совсем новичок в этом деле. Второй день блуждаю по форумам, но никак не смог найти ответ. Знаю, что в c# это можно реализовать с помощью...

Как сохранить настройки программы в ini файл
Надо сохранить пути к DLL у listbox сохранить выбранный процесс combobox и т.д или сразу всё... И потом при открытии прочитать ini

Как сохранить настройки программы в файл setting и считать их
Как сохранить настройки программы в файл setting и считать их =) Не хочется с текстовым файлом возиться

Как максимально просто сохранить настройки программы в файл
Добрый день! В проекте много текстбоксов и радиоботтонов для заполнения настроек. Пользователь выставлят эти настройки через...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru