Форум программистов, компьютерный форум, киберфорум
Наши страницы
Delphi: Сети
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/17: Рейтинг темы: голосов - 17, средняя оценка - 4.88
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
1

Delphi 7 Нужно сделать обновление программы через Ftp сервер

24.05.2013, 02:53. Просмотров 3183. Ответов 14
Метки нет (Все метки)

Народ нужна помощь!
Пишу в delphi 7 прогу 3 день (знаний ниуя) возникла проблема:
Нужно сделать обновление программы через Ftp сервер. Как это сделать?

Есть идеи:
1) Проверить есть ли на сервере файл с таким же названием + номер (больше нынешнего) Если такой файл там есть, то качаем и запускаем, тот закрывает и удаляет старый, копируется и переименовывается (встает на место старого)
НО! не знаю, как проверить наличие файла именно на FTP.
2) Качаем файл по маске стандартного имени + номера (любого) Уже на компе сравниваем номера, если больше, то дальше также как и в 1 пункте, удаляем, копируем ... Если же меньше удаляем скаченый
НО! не знаю как ввести маску в имя файла (как в cmd (имя*.exe) не катит)
3) Самый убогий! Изначальный файл постоянно качает лежащий на фтп файл и каждый раз заменяется (даже если они одинаковые) Честно мня, смущают лишние действия.
P.S. Основной код программы разделен на 2 части, 1 при запуске файла, 2 циклично повторяется (раз в 2 или 4 чеса) Запуск программы с виндой. При запуске пройдет первая часть затем (через 15 сек) вторая далее замена 15 сек на 2 часа и цикл. Поэтому 3 способ не катит, обновлять при запуске (в 1 части) слишком редко (если комп работает долго (я, свой вообще не выключаю)) А если такие махинации впихнуть во 2 часть то, сам код 2 части будет слишком часто (Т.Е. проходит 2 часть вырубается прога обновляется и снова запускается и через 15 сек снова 2 часть и снова перезапуск. В итоге слишком мудреный код писать)
P.P.S. А вот просто проверки как в 1 и 2 (для мня, первый способ лучше- не надо качать лишнего) раз в 2 чеса само то, если надо чтоб закинув новую версию она обновилась у всех быстро.
P.P.P.S. Помогите с моими вариантами, либо дайте свои, я все расписал, думаю, что суть ясна.
P.P.P.P.S. для FTP использовал idFTP.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.05.2013, 02:53
Ответы с готовыми решениями:

Нужно сделать обновление для программы
Нужно сделать обновление программы на Delphi 7. -Обновляться должна через...

Как в Delphi 7 отправить файл на ftp сервер
:confused: Кто-нибудь, подскажите, как в Delphi 7 отправить файл на ftp сервер

Обновление программы через сеть
Добрый день! Прошу помощи в решении проблемы. Реализовываю загрузку...

Здраствуйте очень нужна помощь!!!!нужно из этого кода сделать программу на DELPHI
unit Kurstik jumis; interface uses Windows, Messages, SysUtils, Variants,...

пожалуйста, нужно сделать через case, селектор
Написать программу, которая вычисляет дату следующего дня. Ниже представлен...

14
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 14:54 2
Цитата Сообщение от termir988 Посмотреть сообщение
Народ нужна помощь!
Пишу в delphi 7 прогу 3 день (знаний ниуя) возникла проблема:
Нужно сделать обновление программы через Ftp сервер. Как это сделать?

Есть идеи:
1) Проверить есть ли на сервере файл с таким же названием + номер (больше нынешнего) Если такой файл там есть, то качаем и запускаем, тот закрывает и удаляет старый, копируется и переименовывается (встает на место старого)
НО! не знаю, как проверить наличие файла именно на FTP.
2) Качаем файл по маске стандартного имени + номера (любого) Уже на компе сравниваем номера, если больше, то дальше также как и в 1 пункте, удаляем, копируем ... Если же меньше удаляем скаченый
НО! не знаю как ввести маску в имя файла (как в cmd (имя*.exe) не катит)
3) Самый убогий! Изначальный файл постоянно качает лежащий на фтп файл и каждый раз заменяется (даже если они одинаковые) Честно мня, смущают лишние действия.
P.S. Основной код программы разделен на 2 части, 1 при запуске файла, 2 циклично повторяется (раз в 2 или 4 чеса) Запуск программы с виндой. При запуске пройдет первая часть затем (через 15 сек) вторая далее замена 15 сек на 2 часа и цикл. Поэтому 3 способ не катит, обновлять при запуске (в 1 части) слишком редко (если комп работает долго (я, свой вообще не выключаю)) А если такие махинации впихнуть во 2 часть то, сам код 2 части будет слишком часто (Т.Е. проходит 2 часть вырубается прога обновляется и снова запускается и через 15 сек снова 2 часть и снова перезапуск. В итоге слишком мудреный код писать)
P.P.S. А вот просто проверки как в 1 и 2 (для мня, первый способ лучше- не надо качать лишнего) раз в 2 чеса само то, если надо чтоб закинув новую версию она обновилась у всех быстро.
P.P.P.S. Помогите с моими вариантами, либо дайте свои, я все расписал, думаю, что суть ясна.
P.P.P.P.S. для FTP использовал idFTP.
Я предпочитаю дистрибутив(ini-file). Программа должна проверить версию на серваке и у себя. Потом скачать ини с ссылками с фтп и грузится.
2) подумай головой.
3) Лучше удали код проверки в процессе программы или проверяй раз в день(так делают скайп, аимп и т.д.).
короче пиши код сам. Я сам сделал обновление с фтп.
0
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 16:07  [ТС] 3
Цитата Сообщение от саша40 Посмотреть сообщение
Я предпочитаю дистрибутив(ini-file). Программа должна проверить версию на серваке и у себя. Потом скачать ини с ссылками с фтп и грузится.
2) подумай головой.
3) Лучше удали код проверки в процессе программы или проверяй раз в день(так делают скайп, аимп и т.д.).
короче пиши код сам. Я сам сделал обновление с фтп.
Уже получал советы создать доп файл (создал txt =\ ). Теперь новая проблема-
после загрузки файла с FTP, он не открывается, из-за ошибки совместимости с системой.
Что-то не так с загрузкой файла, поскольку если качать его программой FileZilla, файл запускается без ошибок.

Использую команду:
Delphi
1
idftp1.Get(...,...);
-Txt файлы нормально качаются.
-Побывал несколько файлов.



Чась кода отвечающая за "Обновление программы":


Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Обновление программы 
  idftp1.Get('/Update/'+UN,ND+NND+UN);
  Memo1.Lines.LoadFromFile(ND+NND+UN);
  UVersion:=copy(Memo1.Lines[0],pos(':',Memo1.Lines[0])+1,length(Memo1.Lines[0]));
  if not (UVersion=Ver) then begin
  Timer1.Interval := 14400000;
  UFName:=copy(Memo1.Lines[1],pos(':',Memo1.Lines[1])+1,length(Memo1.Lines[1]));
  DeleteFile(ND+NND+'\'+UFName+'.exe');
  showmessage(ND+NND+'\'+UFName+'.exe');
  idftp1.Get('/Update/'+UFName+'.exe', ND+NND+'\'+UFName+'.exe');
  WinExec(Pchar(ND+NND+'\'+UFName+'.exe'), SW_SHOWNORMAL);
  idFTP1.Disconnect;
  Close;
  end;
Добавлено через 11 минут
Еще если это важно-
-Ftp на ucoz'e (сайт пустой использую как облачное хранилище для проги)
0
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 16:24 4
Ты скачивал так?
Delphi
1
idFTP1.Get('file.exe','C:\file.exe');
Добавлено через 10 минут
Может попробовать в архиве zip качать? А что, это идея. Понадобится компонент ZipForge.
1
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 17:07  [ТС] 5
Цитата Сообщение от саша40 Посмотреть сообщение
Ты скачивал так?
Delphi
1
idFTP1.Get('file.exe','C:\file.exe');
Добавлено через 10 минут
Может попробовать в архиве zip качать? А что, это идея. Понадобится компонент ZipForge.
Идея думаю хорошая (мне тоже приходила но я уперся в то, что не знаю где лежит этот компонент)
Пойду гуглить

Добавлено через 6 минут
ZipForge нашел, установил.
Как им пользоваться то? =\

Добавлено через 12 минут
Вот что получилось (точнее не получилось) zip не открывается?
Это из-за того, что он rar, или из-за того, что пути переменными прописаны?


Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//Обновление программы
  idftp1.Get('/Update/'+UN,ND+NND+UN);
  Memo1.Lines.LoadFromFile(ND+NND+UN);
  UVersion:=copy(Memo1.Lines[0],pos(':',Memo1.Lines[0])+1,length(Memo1.Lines[0]));
  if not (UVersion=Ver) then begin
  Timer1.Interval := 14400000;
  UFName:=copy(Memo1.Lines[1],pos(':',Memo1.Lines[1])+1,length(Memo1.Lines[1]));
  //Удаление старых файлов
  DeleteFile(ND+NND+'\'+UFName+'.exe');
  DeleteFile(ND+NND+'\'+UFName+'.rar');
  //Загрузка архива
  idftp1.Get('/Update/'+UFName+'.exe', ND+NND+'\'+UFName+'.rar');
  //Zip
  ZipForge1.BaseDir := ND+NND;
  ZipForge1.FileName:=ND+NND+'\'+UFName+'.rar';
  ZipForge1.OpenArchive(fmcreate);
  ZipForge1.ExtractFiles(UFName+'.exe');
  ZipForge1.CloseArchive;
  //Запуск файла
  WinExec(Pchar(ND+NND+'\'+UFName+'.exe'), SW_SHOWNORMAL);
  idFTP1.Disconnect;
  Close;
  end;
Добавлено через 5 минут
Исправил ошибки теперь код выполняется без ошибок и без эффекта
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  idftp1.Get('/Update/'+UN,ND+NND+UN);
  Memo1.Lines.LoadFromFile(ND+NND+UN);
  UVersion:=copy(Memo1.Lines[0],pos(':',Memo1.Lines[0])+1,length(Memo1.Lines[0]));
  if not (UVersion=Ver) then begin
  Timer1.Interval := 14400000;
  UFName:=copy(Memo1.Lines[1],pos(':',Memo1.Lines[1])+1,length(Memo1.Lines[1]));
 
  DeleteFile(ND+NND+'\'+UFName+'.exe');
  DeleteFile(ND+NND+'\'+UFName+'.rar');
 
  idftp1.Get('/Update/'+UFName+'.rar', ND+NND+'\'+UFName+'.rar');
  //Zip
  ZipForge1.BaseDir := ND+NND;
  ZipForge1.FileName:=ND+NND+'\'+UFName+'.rar';
  ZipForge1.OpenArchive(fmcreate);
  ZipForge1.ExtractFiles('*.*');
  ZipForge1.CloseArchive;
 
  WinExec(Pchar(ND+NND+'\'+UFName+'.exe'), SW_SHOWNORMAL);
  idFTP1.Disconnect;
  Close;
  end;
Добавлено через 8 минут
И да просто архив качается поврежденным

! C:\...\FV3408G4V02.rar: Unexpected end of archive
! C:\...\FV3408G4V02.rar: CRC failed in FV3408G4V02.exe. The file is corrupt

но файл зала качает нормально

В чем причина поломки файлов?
0
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 18:24 6
качать нужно zip архив, а не rar.
0
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 20:11  [ТС] 7
Цитата Сообщение от саша40 Посмотреть сообщение
качать нужно zip архив, а не rar.
И зип архивы побывал, но они тоже поврежденными качаются. Может это Ucoz косячит?
Архив (и ехе файлы), скаченные самой delphi, не открываются даже вручную. А FileZilla нормально качает.

Вот весь код если поможет

Delphi
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
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ShellAPI, IdFTP, xpman, ShlObj, IdTCPClient,
IdBaseComponent, IdComponent, IdTCPConnection,
IdExplicitTLSClientServerBase, RegisTry, ExtCtrls, StdCtrls, ZipForge;
 
type
TForm1 = class(TForm)
    IdFTP1: TIdFTP;
    Timer1: TTimer;
    Memo1: TMemo;
    ZipForge1: TZipForge;
    procedure Timer1Timer(Sender: TObject);
private
FIconData:TNotifyIconData;
protected
public
constructor Create(AOwner: TComponent); Override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
 
function GetWin(Comand: string): string;
var
  buff: array [0 .. $FF] of char;
begin
  ExpandEnvironmentStrings(PChar(Comand), buff, SizeOf(buff));
  Result := buff;
end;
 
constructor TForm1.Create(AOwner: TComponent);
begin
 
                  ///Блок\\\
// Создаем главную форму и блокируем ее показ
inherited Create(AOwner);
Application.ShowMainForm:=False;
end;
 
procedure TForm1.Timer1Timer(Sender: TObject);
const
  NF = '...exe';
  ND = 'C:\Program Files (x86)\...\';
  NND = '...';
 
  UN = 'UpdateFV3808G4.txt';
var
  AppData,NameC,UVersion,UFName,Ver:string;
  reg:TRegistry;
begin
  AppData := GetWin('%AppData%');
  NameC := copy(AppData,10,pos('\A',AppData)-10);
  Ver := '0.1';
 
 
                  ///Реестр\\\
//Авто-запуск
  reg := TregisTry.create;
  reg.RootKey := HKEY_CURRENT_USER;
  reg.lazywrite := false;
  reg.OpenKey('software\microsoft\windows\currentversion\run', true);
  reg.WriteString(' ... ',ND+NF);
  reg.CloseKey;
  reg.Free;
 
                  ///Подготовка программы\\\
  CopyFile(Pchar(Application.exeName),Pchar(ND+NF), true);
  CreateDir(ND+NND);
 
                  ///Сервер\\\
 
//Подготовка файлов
  //Update
  DeleteFile(ND+NND+UN);
 
//Подключение к серверу
  idFTP1.Disconnect;
  
  idFTP1.UserName := '....';
  idFTP1.Password := '....';
  idFTP1.Host := '...ucoz.org';
  try
  idFTP1.Connect;
//Ошибка
  except
  on E : Exception do
  ShowMessage('Update Error: '+E.Message);
  end;
  if idFTP1.Connected then begin
 
//Работа с сервером
 
//Обновление программы
  idftp1.Get('/Update/'+UN,ND+NND+UN);
  Memo1.Lines.LoadFromFile(ND+NND+UN);
  UVersion:=copy(Memo1.Lines[0],pos(':',Memo1.Lines[0])+1,length(Memo1.Lines[0]));
  if not (UVersion=Ver) then begin
  Timer1.Interval := 14400000;
  UFName:=copy(Memo1.Lines[1],pos(':',Memo1.Lines[1])+1,length(Memo1.Lines[1]));
  //Удаление старых файлов
  DeleteFile(ND+NND+'\'+UFName+'.exe');
  DeleteFile(ND+NND+'\'+UFName+'.zip');
  //Загрузка архива
  idftp1.Get('/Update/'+UFName+'.zip', ND+NND+'\'+UFName+'.zip');
  //Zip
  ZipForge1.BaseDir := ND+NND;
  ZipForge1.FileName:=ND+NND+'\'+UFName+'.zip';
  ZipForge1.OpenArchive(fmcreate);
  ZipForge1.ExtractFiles('*.*');
  ZipForge1.CloseArchive; 
  //Запуск файла
  WinExec(Pchar(ND+NND+'\'+UFName+'.exe'), SW_SHOWNORMAL);
  idFTP1.Disconnect;
  Close;
  end;
 
 
//Отключение от сервера
  idFTP1.Disconnect;
 
                  ///Таймер\\\
  Timer1.Interval := 14400000;
end;
 
end.
0
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 21:22 8
может надо пользоватся try expert? Я честно уже не знаю.

Добавлено через 1 минуту
Интересно и зачем такой большой интервал?

Добавлено через 2 минуты
Ошибки выдают на неожиданый конец архива, это значит ты его не докачала.
0
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 21:33  [ТС] 9
Цитата Сообщение от саша40 Посмотреть сообщение
может надо пользоватся try expert? Я честно уже не знаю.

Добавлено через 1 минуту
Интересно и зачем такой большой интервал?

Добавлено через 2 минуты
Ошибки выдают на неожиданый конец архива, это значит ты его не докачала.
А как использовать try expert?

Если он не докачивает файл а сразу пытается перейти к следующей команде, то как подождать?

Добавлено через 1 минуту
Цитата Сообщение от саша40 Посмотреть сообщение
ты его не докачала.
не докачал* Если понимаешь о чем я.
0
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 21:46 10
Цитата Сообщение от termir988 Посмотреть сообщение
А как использовать try expert?

Если он не докачивает файл а сразу пытается перейти к следующей команде, то как подождать?

Добавлено через 1 минуту


не докачал* Если понимаешь о чем я.
ой простите! Возможно тогда цыклом Try Finally end. Хотя спроси модераторов, они знают.
0
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 21:59  [ТС] 11
Цитата Сообщение от саша40 Посмотреть сообщение
ой простите! Возможно тогда цыклом Try Finally end. Хотя спроси модераторов, они знают.
Я до сих пор не понимаю как именно мне использовать Try Finally\Expert.
Прочел что Try Finally\Expert это операторы для 100% выполнении части кода записанным в Finally\Expert даже если код в try выдаст ошибку. И что мне сделать.
Нужно выждать полной загрузки архива, а затем его открыть. И как тут использовать Try Finally\Expert?
0
саша40
-111 / 293 / 47
Регистрация: 14.08.2012
Сообщений: 2,573
24.05.2013, 22:05 12
Цитата Сообщение от termir988 Посмотреть сообщение
Я до сих пор не понимаю как именно мне использовать Try Finally\Expert.
Прочел что Try Finally\Expert это операторы для 100% выполнении части кода записанным в Finally\Expert даже если код в try выдаст ошибку. И что мне сделать.
Нужно выждать полной загрузки архива, а затем его открыть. И как тут использовать Try Finally\Expert?
вот так:
Delphi
1
2
3
4
5
try
... //что-то делаем
finally 
...//действия на конец какого либо действия, например, конец архива, файла.
end;
Добавлено через 2 минуты
И вот так:
Delphi
1
2
3
4
5
6
7
try
...//что-то сделали
expert 
E: Expression;
...//действия в случае ошибки
ShowMessage('Текст ошибки:' + ' ' + E.Message);
end;
0
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
24.05.2013, 22:12  [ТС] 13
Цитата Сообщение от саша40 Посмотреть сообщение
вот так:
Delphi
1
2
3
4
5
try
... //что-то делаем
finally 
...//действия на конец какого либо действия, например, конец архива, файла.
end;
Добавлено через 2 минуты
И вот так:
Delphi
1
2
3
4
5
6
7
try
...//что-то сделали
expert 
E: Expression;
...//действия в случае ошибки
ShowMessage('Текст ошибки:' + ' ' + E.Message);
end;

Попробовал так:

Delphi
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
//Обновление программы
  idftp1.Get('/Update/'+UN,ND+NND+UN);
  Memo1.Lines.LoadFromFile(ND+NND+UN);
  UVersion:=copy(Memo1.Lines[0],pos(':',Memo1.Lines[0])+1,length(Memo1.Lines[0]));
  if not (UVersion=Ver) then begin
  Timer1.Interval := 14400000;
  UFName:=copy(Memo1.Lines[1],pos(':',Memo1.Lines[1])+1,length(Memo1.Lines[1]));
  //Удаление старых файлов
  DeleteFile(ND+NND+'\'+UFName+'.exe');
  DeleteFile(ND+NND+'\'+UFName+'.zip');
  //Загрузка архива
  try
  idftp1.Get('/Update/'+UFName+'.zip', ND+NND+'\'+UFName+'.zip');
  finally
  //Zip
  ZipForge1.BaseDir := ND+NND;
  ZipForge1.FileName:=ND+NND+'\'+UFName+'.zip';
  ZipForge1.OpenArchive(fmcreate);
  ZipForge1.ExtractFiles('*.*');
  ZipForge1.CloseArchive; 
  //Запуск файла
  WinExec(Pchar(ND+NND+'\'+UFName+'.exe'), SW_SHOWNORMAL);
  idFTP1.Disconnect;
  end;
  Close;
  end;
Архив поврежден. Я так сделал то? (кажись нет)

Добавлено через 2 минуты
Кстати код
Delphi
1
2
3
4
5
  ZipForge1.BaseDir := ND+NND;
  ZipForge1.FileName:=ND+NND+'\'+UFName+'.zip';
  ZipForge1.OpenArchive(fmcreate);
  ZipForge1.ExtractFiles('*.*');
  ZipForge1.CloseArchive;
Превращает архив в файл (с размером в 22 байта)
Опустошает архив, но файлы не сохраняются.
0
Maincore
14 / 14 / 2
Регистрация: 22.03.2012
Сообщений: 95
26.05.2013, 13:13 14
Скорей всего дело в том в каком виде передается файл; в бинарном или текстовом виде!
За это отвечает свойство TransferType, которое может принимать значения ftASCII и ftBinary.
2
termir988
3 / 3 / 2
Регистрация: 24.05.2013
Сообщений: 156
27.05.2013, 00:28  [ТС] 15
Цитата Сообщение от Maincore Посмотреть сообщение
Скорей всего дело в том в каком виде передается файл; в бинарном или текстовом виде!
Огромное спасибо, помогло.

Для людей у которых криво качаются файлы (на indy) измените значение трансфера на ftBinary. Это можно сделать в Object Inspector'e во вкладки TransferType.


Командой че то не получилось.
Delphi
1
idFTP1.transfertype:=ftBinary;
У меня ее вообще нету если посмотреть список (который открывается в этом положении idFTP1.) есть
Delphi
1
IdFTP1.TransferMode();
Но ей тоже не знаю как.
1
27.05.2013, 00:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.05.2013, 00:28

FTP сервер. Удаление каталога
все работает, исключение удаление каталога. Sz: Integer; s: String; begin...

Передача файла на FTP-сервер
Кто подскажет как оправить файл на фтп сервер из указаной папке на локальном...

Как залить файл на FTP-сервер?
Как залить файл на ftp сервер?


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

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

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