Подскажите, как после установки ассоциировать например файлы с расширением .abc с программой {app}\1.exe ???
» Inno Setup (создание инсталяционных пакетов)
maxdddca123
Цитата:
Код: [Registry]
Root: HKLM; Subkey: "Software\Classes\.w3m"; ValueType: string; ValueName: ""; ValueData: "WorldEdit.Scenario"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "Software\Classes\WorldEdit.Scenario\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\WorldEdit.exe,2"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "Software\Classes\WorldEdit.Scenario\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\World Editor.exe ""%1"""; Flags: uninsdeletevalue
Цитата:
Подскажите, как после установки ассоциировать например файлы с расширением .abc с программой {app}\1.exe ???
Код: [Registry]
Root: HKLM; Subkey: "Software\Classes\.w3m"; ValueType: string; ValueName: ""; ValueData: "WorldEdit.Scenario"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "Software\Classes\WorldEdit.Scenario\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\WorldEdit.exe,2"; Flags: uninsdeletevalue
Root: HKLM; Subkey: "Software\Classes\WorldEdit.Scenario\shell\open\command"; ValueType: string; ValueName: ""; ValueData: "{app}\World Editor.exe ""%1"""; Flags: uninsdeletevalue
NightW0lf
Чисто ради любопытства...
Не подскажешь, зачем нужно прописывать к exe-шке "%1"?
Чисто ради любопытства...
Не подскажешь, зачем нужно прописывать к exe-шке "%1"?
Есть Tasks. КАК проверить, что стоит галка или нет на определенном.
iTASmania_Inc
Цитата:
Это отвечает за то что будет открываться через данныю пограмму (в данном случаи World Editor.exe)
SpoinT
Цитата:
Если ты имешь ввиду то, что если галка стоит то должно что то выполняться то вот пример:
Код: [Tasks]
Name: "desktopicon"; Description: "Создать ярлыки на Рабочем столе"; GroupDescription: "Дополнительные ярлыки:";
[Icons]
Name: "{userdesktop}\Name"; Filename: "{app}\Name";Tasks: desktopicon; WorkingDir: "{app}";
Цитата:
Чисто ради любопытства...
Не подскажешь, зачем нужно прописывать к exe-шке "%1"?
Это отвечает за то что будет открываться через данныю пограмму (в данном случаи World Editor.exe)
SpoinT
Цитата:
Есть Tasks. КАК проверить, что стоит галка или нет на определенном.
Если ты имешь ввиду то, что если галка стоит то должно что то выполняться то вот пример:
Код: [Tasks]
Name: "desktopicon"; Description: "Создать ярлыки на Рабочем столе"; GroupDescription: "Дополнительные ярлыки:";
[Icons]
Name: "{userdesktop}\Name"; Filename: "{app}\Name";Tasks: desktopicon; WorkingDir: "{app}";
NightW0lf
Спасибо! Не знал, потому что не очень часто в реестр данные прописываю.
Не подскажете тогда, зачем ещё в иконках (DefaultIcon) после exe-шки надо 2 писать? Видимо, за формат иконки отвечает, а как узнать какой именно размер иконки и тип (XP, True Color) я даю файлам, открываемым через мою прогу?
Victor_Dobrov
И опять же только из любопытства
Не могли Вы переделать процедуру заполнения лист-боксов с HDD в скине Corona Skin, с учётом того, что в системе может присутствовать диск размером менее Мб? (Смонтирован из контейнера через TrueCrypt, если подобный диск (менее 1024Кб) присутствует в системе, то инсталлятор выдаёт сообщение насчёт математической ошибки)
Спасибо! Не знал, потому что не очень часто в реестр данные прописываю.
Не подскажете тогда, зачем ещё в иконках (DefaultIcon) после exe-шки надо 2 писать? Видимо, за формат иконки отвечает, а как узнать какой именно размер иконки и тип (XP, True Color) я даю файлам, открываемым через мою прогу?
Victor_Dobrov
И опять же только из любопытства
Не могли Вы переделать процедуру заполнения лист-боксов с HDD в скине Corona Skin, с учётом того, что в системе может присутствовать диск размером менее Мб? (Смонтирован из контейнера через TrueCrypt, если подобный диск (менее 1024Кб) присутствует в системе, то инсталлятор выдаёт сообщение насчёт математической ошибки)
iTASmania_Inc
Цитата:
Просто открой через любой редактор ресурсов (например PE Explorer) там будет пункт Icon Entry в этом разделе как раз и находиться все иконки под порядковым номером, этот порядковый номер и вписывается после (например) World Editor.exe,5.
Цитата:
Не подскажете тогда, зачем ещё в иконках (DefaultIcon) после exe-шки надо 2 писать? Видимо, за формат иконки отвечает, а как узнать какой именно размер иконки и тип (XP, True Color)
Просто открой через любой редактор ресурсов (например PE Explorer) там будет пункт Icon Entry в этом разделе как раз и находиться все иконки под порядковым номером, этот порядковый номер и вписывается после (например) World Editor.exe,5.
NightW0lf
Ещё раз огромное спасибо! Вот ламерство, сам пользуюсь PE Explorer и Restorator, иконки сколько раз менял, а индексов даже до сего дня в глаза и не видел!
Ещё раз огромное спасибо! Вот ламерство, сам пользуюсь PE Explorer и Restorator, иконки сколько раз менял, а индексов даже до сего дня в глаза и не видел!
maxdddca123 -- вобщем-то выше NightW0lf уже все объяснил. Только хотел бы обратить внимание, что более простой путь создания ассоциаций - воспользоваться возможностями ISTool, у которого в меню Project есть пункт Create Association, выбрав который можно в два клика создать вышеуказанную конструкцию не заботясь о синтаксисе
Ну а если ты не любишь простых решений, то набери в командной строке assoc /? затем ftype /? и изучай встроенные возможности винды
SpoinT
Цитата:
function IsTaskSelected(const Tasks: String): Boolean;
и
function WizardSelectedTasks(const Descriptions: Boolean): String;
iTASmania_Inc -- опять-таки NightW0lf уже все объяснил. Могу только добавить для лучшего понимания: %1 - это параметр, вместо которого будет подставлено имя открываемого файла. Например, в случае с файлом .txt имеем аналогичную запись NOTEPAD.EXE %1 , которая при запуске файла readme.txt примет вид NOTEPAD.EXE readme.txt
А все это я к тому, что можно не ограничиваться только %1, а прописать и другие параметры поддерживаемые программой (как например в том же блокноте, NOTEPAD.EXE /p %1 сразу отправит файл на печать)
Ну а если ты не любишь простых решений, то набери в командной строке assoc /? затем ftype /? и изучай встроенные возможности винды
SpoinT
Цитата:
Есть Tasks. КАК проверить, что стоит галка или нет на определенном.-- попробуй почитать в направлении :
function IsTaskSelected(const Tasks: String): Boolean;
и
function WizardSelectedTasks(const Descriptions: Boolean): String;
iTASmania_Inc -- опять-таки NightW0lf уже все объяснил. Могу только добавить для лучшего понимания: %1 - это параметр, вместо которого будет подставлено имя открываемого файла. Например, в случае с файлом .txt имеем аналогичную запись NOTEPAD.EXE %1 , которая при запуске файла readme.txt примет вид NOTEPAD.EXE readme.txt
А все это я к тому, что можно не ограничиваться только %1, а прописать и другие параметры поддерживаемые программой (как например в том же блокноте, NOTEPAD.EXE /p %1 сразу отправит файл на печать)
NightW0lf
а если мне надо процедурку запустить, а не тупо иконку создать?
Genri
спасибо!
а если мне надо процедурку запустить, а не тупо иконку создать?
Genri
спасибо!
Подскажите пожалуйста... Как создать новую страничку я примерно представляю, а вот как ее можно удалить? Проблема в том, что страничка должна быть видна только в том случае если стоит галочка на предыдущей - я создаю страничку в NextButtonClick по условию, но если она уже один раз создана в последствии соответсвенно никуда не пропадает... А это сказывается если нажимать кнопку "назад" и менять настройки... Заранее благодарен за помощь...
NightW0lf
Вопрос снимаю. Разобрался!
Вопрос снимаю. Разобрался!
Gerrr -- используй:
function ShouldSkipPage(PageID: Integer): Boolean;
т.е. не удаление странички, а ее пропуск. Соответственно там ты должен прописать условия, при каких эта страничка должна или не должна отображаться.
function ShouldSkipPage(PageID: Integer): Boolean;
т.е. не удаление странички, а ее пропуск. Соответственно там ты должен прописать условия, при каких эта страничка должна или не должна отображаться.
Genri
Спасибо
Спасибо
Нужна помощь: Как на wpSelectProgramGroup сделать две TRadioButton, первая - создает ярлыки для всех пользователей (то есть поместить ярлыки в папку "C:\Documents and Settings\All Users\Главное меню\Программы\My Program"), а вторая - создать ярлыки только для пользователя который запустил setup ("C:\Documents and Settings\User\Главное меню\Программы\My Program")
Ну так что, не кто не хочет написать руссификатор для Inno Script Generator?
А то мне ОЧЕНЬ НАДО.
А то мне ОЧЕНЬ НАДО.
Ohotnic
Бери Лингво и пиши
А если по теме, то я тоже сначала не мог врубиться, ничего непонятно, но посидев вечерок, поэкспериментировав, разобрался почти во всем. Главное терпение и желание
Бери Лингво и пиши
А если по теме, то я тоже сначала не мог врубиться, ничего непонятно, но посидев вечерок, поэкспериментировав, разобрался почти во всем. Главное терпение и желание
Unc1e
Цитата:
Код:
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
[Icons]
Name: "{code:MyConst}\My Program"; Filename: "{app}\MyProg.exe"
[Code]
var
CheckListBox: TNewCheckListBox;
function MyConst(Param: String): String;
begin
if CheckListBox.Checked[1] then
Result := ExpandConstant('{commonprograms}')
else
Result := ExpandConstant('{userprograms}');
end;
procedure InitializeWizard();
begin
CheckListBox := TNewCheckListBox.Create(WizardForm);
CheckListBox.Top := WizardForm.GroupEdit.Top + WizardForm.GroupEdit.Height + ScaleY(28);
CheckListBox.Width := WizardForm.GroupEdit.Width;
CheckListBox.Height := ScaleY(97);
CheckListBox.BorderStyle := bsNone;
CheckListBox.ParentColor := True;
CheckListBox.MinItemHeight := WizardForm.TasksList.MinItemHeight;
CheckListBox.ShowLines := False;
CheckListBox.WantTabs := True;
CheckListBox.Parent := WizardForm.SelectProgramGroupPage;
CheckListBox.AddGroup('Create shortcuts', '', 0, nil);
CheckListBox.AddRadioButton('For All Users', '', 0, True, True, nil);
CheckListBox.AddRadioButton('For Current User Only', '', 0, False, True, nil);
end;
Цитата:
Как на wpSelectProgramGroup сделать две TRadioButton, первая - создает ярлыки для всех пользователей ...., а вторая - создать ярлыки только для пользователя который запустил setup
Код:
[Setup]
AppName=My Program
AppVerName=My Program v.1.2
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
[Files]
Source: "MyProg.exe"; DestDir: "{app}"
[Icons]
Name: "{code:MyConst}\My Program"; Filename: "{app}\MyProg.exe"
[Code]
var
CheckListBox: TNewCheckListBox;
function MyConst(Param: String): String;
begin
if CheckListBox.Checked[1] then
Result := ExpandConstant('{commonprograms}')
else
Result := ExpandConstant('{userprograms}');
end;
procedure InitializeWizard();
begin
CheckListBox := TNewCheckListBox.Create(WizardForm);
CheckListBox.Top := WizardForm.GroupEdit.Top + WizardForm.GroupEdit.Height + ScaleY(28);
CheckListBox.Width := WizardForm.GroupEdit.Width;
CheckListBox.Height := ScaleY(97);
CheckListBox.BorderStyle := bsNone;
CheckListBox.ParentColor := True;
CheckListBox.MinItemHeight := WizardForm.TasksList.MinItemHeight;
CheckListBox.ShowLines := False;
CheckListBox.WantTabs := True;
CheckListBox.Parent := WizardForm.SelectProgramGroupPage;
CheckListBox.AddGroup('Create shortcuts', '', 0, nil);
CheckListBox.AddRadioButton('For All Users', '', 0, True, True, nil);
CheckListBox.AddRadioButton('For Current User Only', '', 0, False, True, nil);
end;
Ruud
Цитата:
[more=Посмотреть пример..]
; Скрипт для установки архивов, записанных на двух DVD. На примере показано извлечение из 7z SFX архивов.
; Не знаю, чем не устраивает встроенное сжатие, но раз у кого-то возникла такая потребность, попробовал реализовать.
; Я не Genri, но кое-что получилось, не хватает кнопки "Обзор", хотя она по большому счету здесь роли не играет
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
OutputBaseFilename=setup
Compression=none
OutputDir=C:\Output
SolidCompression=no
[Files]
;На диске рядом с инсталлятором размещаем папку EmptyFiles, в которую помещаем "файлы-пустышки" игры.
;Сначала выполняется первый архив (последовательность AfterInstall должна быть такой)
Source: "{src}\EmptyFiles\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs external; AfterInstall: InstallFirstArchive
;А затем второй
Source: "{src}\EmptyFiles\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs external; AfterInstall: CheckSelectedDisk
Code]
//На странице установки отключаем подтверждающее сообщение (чтобы небыло проблем с откатом)
procedure CancelButtonClick(CurPage: Integer; var Cancel, Confirm: Boolean);
begin
Cancel:=True;
If CurPage=12 then
begin
Confirm:=False;
end;
end;
//Устанавливаем первый 7z SFX (Pack1.exe) архив, находящийся на первом диске (рядом с инсталлятором)
//Никаких сообщений об ошибках и т.д. не применяем, т.к. вся ответственность должна лежать на распространителе
procedure InstallFirstArchive;
var
res:Integer;
s,s1:string;
begin
s:=ExpandConstant('{app}');
s1:=ExpandConstant('{src}')+'\Pack1.exe';
Exec(s1, '-y -o"'+ s + '"', '', SW_SHOWNORMAL, ewWaitUntilTerminated, Res);
end;
//Затем выводим соответствующее сообщение для вставки второго диска со вторым архивом
procedure CheckSelectedDisk;
var
res:Integer;
s,s2:string;
Confirm: Boolean;
begin
s:=ExpandConstant('{app}');
s2:=ExpandConstant('{src}')+'\Pack2.exe';
//Если второго архива рядом нету (мало ли в будущем игра будет записана на двуслойном диске)
if not Exec(s2, '-y -o"'+ s + '"', '', SW_SHOWNORMAL, ewWaitUntilTerminated, Res) then
//то тогда выводим сообщение
case MsgBox('Для дальнейшей установки требуется файл '''+ s2 +'''!'#13#13 +
'Вставьте второй DVD, содержащий архив, и нажмите "OK".' #13#13 +
'Нажмите "Отмена", чтобы прекратить дальнейшую установку.', mbInformation, MB_OKCANCEL)
of IDCANCEL:
begin
//Выполняем откат действий при отмене
Confirm:=False;
WizardForm.CancelButton.OnClick(WizardForm.CancelButton);
end
IDOK:
begin
CheckSelectedDisk;
end;
end;
end;[/more]
Цитата:
Я сделал 2 7z SFX архива,каждый из них будет записываться на DVD.Не подскажете,как сделать в инсталляторе запрос о вставке второго диска после распаковки первого архива.Вот примерно то, о чем ты просил:
[more=Посмотреть пример..]
; Скрипт для установки архивов, записанных на двух DVD. На примере показано извлечение из 7z SFX архивов.
; Не знаю, чем не устраивает встроенное сжатие, но раз у кого-то возникла такая потребность, попробовал реализовать.
; Я не Genri, но кое-что получилось, не хватает кнопки "Обзор", хотя она по большому счету здесь роли не играет
[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
OutputBaseFilename=setup
Compression=none
OutputDir=C:\Output
SolidCompression=no
[Files]
;На диске рядом с инсталлятором размещаем папку EmptyFiles, в которую помещаем "файлы-пустышки" игры.
;Сначала выполняется первый архив (последовательность AfterInstall должна быть такой)
Source: "{src}\EmptyFiles\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs external; AfterInstall: InstallFirstArchive
;А затем второй
Source: "{src}\EmptyFiles\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs external; AfterInstall: CheckSelectedDisk
Code]
//На странице установки отключаем подтверждающее сообщение (чтобы небыло проблем с откатом)
procedure CancelButtonClick(CurPage: Integer; var Cancel, Confirm: Boolean);
begin
Cancel:=True;
If CurPage=12 then
begin
Confirm:=False;
end;
end;
//Устанавливаем первый 7z SFX (Pack1.exe) архив, находящийся на первом диске (рядом с инсталлятором)
//Никаких сообщений об ошибках и т.д. не применяем, т.к. вся ответственность должна лежать на распространителе
procedure InstallFirstArchive;
var
res:Integer;
s,s1:string;
begin
s:=ExpandConstant('{app}');
s1:=ExpandConstant('{src}')+'\Pack1.exe';
Exec(s1, '-y -o"'+ s + '"', '', SW_SHOWNORMAL, ewWaitUntilTerminated, Res);
end;
//Затем выводим соответствующее сообщение для вставки второго диска со вторым архивом
procedure CheckSelectedDisk;
var
res:Integer;
s,s2:string;
Confirm: Boolean;
begin
s:=ExpandConstant('{app}');
s2:=ExpandConstant('{src}')+'\Pack2.exe';
//Если второго архива рядом нету (мало ли в будущем игра будет записана на двуслойном диске)
if not Exec(s2, '-y -o"'+ s + '"', '', SW_SHOWNORMAL, ewWaitUntilTerminated, Res) then
//то тогда выводим сообщение
case MsgBox('Для дальнейшей установки требуется файл '''+ s2 +'''!'#13#13 +
'Вставьте второй DVD, содержащий архив, и нажмите "OK".' #13#13 +
'Нажмите "Отмена", чтобы прекратить дальнейшую установку.', mbInformation, MB_OKCANCEL)
of IDCANCEL:
begin
//Выполняем откат действий при отмене
Confirm:=False;
WizardForm.CancelButton.OnClick(WizardForm.CancelButton);
end
IDOK:
begin
CheckSelectedDisk;
end;
end;
end;[/more]
Corona Skin & Check System Requirements - обложка для Inno Setup с проверкой системных требований.
Кроме визуального оформления добавляет инсталлятору следующие возможности:
Проверка системных требований. Подсчёт времени установки. Вывод даты сборки. Защита от многократного запуска. Деинсталляция программы перед установкой. Удаление оставшихся после деинсталляции файлов. Автонастройка процесса сборки. Шифрование. Поддержка файлов пользователя. Подсчёт объёма папок. Разные действия при левом/правом щелчке мыши. Запуск настроек системы клавишами F1-F12. Объём и кол-во скопированных файлов на прогрессбаре. Экран справки/скриншотов. Подтвержение на установку в системные папки. К инсталлятору добавляется всего 46 Кб (~225 Кб со всеми необязательными файлами).
Устранены все замечания, добавить линк на обложку в шапку?
Genri, то что надо, спасибо. А как добавить имя текущего пользователя в название второй RadioButton. Что-то типа того
CheckListBox.AddRadioButton('For Current User Only ({username})', '', 0, False, True, nil);
CheckListBox.AddRadioButton('For Current User Only ({username})', '', 0, False, True, nil);
Unc1e --
CheckListBox.AddRadioButton('For ' + GetUserNameString + ' Only', '', 0, False, True, nil);
Добавлено:
Можно и так как у тебя (через константу {username}). Только следует помнить, что в секции Code все константы нужно раскрывать функцией ExpandConstant :
CheckListBox.AddRadioButton('For ' + ExpandConstant('{username}') + ' Only', '', 0, False, True, nil);
CheckListBox.AddRadioButton('For ' + GetUserNameString + ' Only', '', 0, False, True, nil);
Добавлено:
Можно и так как у тебя (через константу {username}). Только следует помнить, что в секции Code все константы нужно раскрывать функцией ExpandConstant :
CheckListBox.AddRadioButton('For ' + ExpandConstant('{username}') + ' Only', '', 0, False, True, nil);
> Victor_Dobrov : Да, если можно.
Genri А как сделать неактивным CheckListBox, если стоит галочка на NoIconsCheck? А то кнопка "Обзор" и GroupEdit недоступны, а CheckListBox так и остается в действии.
Unc1e -- куда-нибудь в InitializeWizard добавляешь строку :
WizardForm.NoIconsCheck.OnClick:= @NoIconsOnClick;
... и добавляешь в код следующую процедуру :
procedure NoIconsOnClick(Sender: TObject);
begin
with WizardForm, WizardForm.NoIconsCheck do
begin
GroupEdit.Enabled:= Not Checked;
GroupBrowseButton.Enabled:= Not Checked;
CheckListBox.Enabled:= Not Checked;
end;
end;
WizardForm.NoIconsCheck.OnClick:= @NoIconsOnClick;
... и добавляешь в код следующую процедуру :
procedure NoIconsOnClick(Sender: TObject);
begin
with WizardForm, WizardForm.NoIconsCheck do
begin
GroupEdit.Enabled:= Not Checked;
GroupBrowseButton.Enabled:= Not Checked;
CheckListBox.Enabled:= Not Checked;
end;
end;
Этот человек знает все о Inno. Хвала и почет Genri
Хотел бы еще раз напомнить - благодарности (причем только заслуженные), я предпочитаю получать в личку. Чтоб не украли.
Hi all!
Такой волпросик...
Есть инталляция моего приложения. Инсталляция формируется для каждого пользователя заново. Между собой инсталляции отличаются путем назначения программы. Т.е. для пользователя "A" программа будет установлена в папку C:\Cool_Prog\A\, для пользователя "B" - в папку C:\Cool_Prog\B\ - это сделано для того, чтобы можно было поставить прогу на 1 комп для разных пользователей и чтобы они не конфликтовали. Но После установки для юзера А - при инсталляции для юзера Б инсталлер определяет, что уже такое приложение установлено по пути "C:\Cool_Prog\A\" и предлагает именно этот путь...
В итоге файлы пользователя "B" затирают файлы пользователя "А".
Подскажите как решить такую проблему?
Такой волпросик...
Есть инталляция моего приложения. Инсталляция формируется для каждого пользователя заново. Между собой инсталляции отличаются путем назначения программы. Т.е. для пользователя "A" программа будет установлена в папку C:\Cool_Prog\A\, для пользователя "B" - в папку C:\Cool_Prog\B\ - это сделано для того, чтобы можно было поставить прогу на 1 комп для разных пользователей и чтобы они не конфликтовали. Но После установки для юзера А - при инсталляции для юзера Б инсталлер определяет, что уже такое приложение установлено по пути "C:\Cool_Prog\A\" и предлагает именно этот путь...
В итоге файлы пользователя "B" затирают файлы пользователя "А".
Подскажите как решить такую проблему?
В шапку добавлена Обложка от Victor_Dobrov:
Corona Skin & Check System Requirements
Corona Skin & Check System Requirements
Genri, а также мастера своего дела, вопрос:
Почему при настройках градиента не сохраняются цвета?! (Inno Script Generator)
Постоянно голубой и черный.
Почему при настройках градиента не сохраняются цвета?! (Inno Script Generator)
Постоянно голубой и черный.
Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
Предыдущая тема: Mail.ru агент - вход не выполнен
Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.