Показать полную графическую версию : Скрипты Inno Setup. Помощь и советы [часть 6]
Dimon585h
02-12-2013, 19:37
Подскажите пожалуйста, у меня при создании инсталлятора, рядом с ним в папке появляется файл с таким же название и расширение "bin", как его засунуть в инсталлятор?
habib2302
02-12-2013, 19:41
Dimon585h,
[Setup]
DiskSpanning=false
Dimon585h
02-12-2013, 20:15
Подскажите пожалуйста, как изменить имя "удалятора", какое-нибудь другое, вместо unins000.
habib2302
02-12-2013, 20:42
Dimon585h,
1 вариант
[ Code]
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep=ssPostInstall then
begin
if not RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppID")}_is1', 'QuietUninstallString', '"' + ExpandConstant('{app}\Uninstall.exe') + '"' + #32 + '/SILENT') then Exit;
if RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppID")}_is1', 'UninstallString', '"' + ExpandConstant('{app}\Uninstall.exe') + '"') then
RenameFile(ExpandConstant('{app}\unins000.exe'), ExpandConstant('{app}\Uninstall.exe'));
if RegWriteStringValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppID")}_is1', 'UninstallDataFile', '"' + ExpandConstant('{app}\Uninstall.dat') + '"') then
RenameFile(ExpandConstant('{app}\unins000.dat'), ExpandConstant('{app}\Uninstall.dat'));
end;
end;
2 вариант
[_Code]
procedure CurStepChanged(CurStep: TSetupStep);
begin
if CurStep = ssPostInstall then
RenameFile(ExpandConstant('{app}\unins000.exe'), ExpandConstant('{app}\uninstall.exe'));
RenameFile(ExpandConstant('{app}\unins000.dat'), ExpandConstant('{app}\uninstall.dat'));
RegWriteStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppID")}_is1','UninstallString', ExpandConstant('{app}\uninstall.exe'));
RegWriteStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppID")}_is1','QuietUninstallString', ExpandConstant('{app}\uninstall.exe /SILENT'));
end;
Dimon585h
02-12-2013, 21:41
Подскажите пожалуйста, как сделать, если сам модпак находится на диске D, то и в адресе указывается не
C:\Games\Wold_of_Tanks
а
D:\Games\Wold_of_Tanks
Dimon585h, Прокрути колёсиком мыши вверх до того момента, когда крутить уже будет некуда.
В первом посте есть хороший пример:
Показать/скрыть: Ссылки на примеры скриптов: » Автовыбор диска установки (http://www.forum.oszone.ru/post-1217528-97.html) »
Там ещё много чего полезного есть.
Nightwishh
02-12-2013, 22:24
Всем здравствуйте, как сделать так чтобы лейблы не мелькали при переходе с одной страницы на другую? Спасибо!
Dimon585h
02-12-2013, 22:32
Как сделать чтобы, при выборе компонентов, все галочки были сняты и если можно, то все галочки были на первых пунктах.
Как сделать чтобы, при выборе компонентов, все галочки были сняты »Кажись у меня дежавю
Dimon585h, Удали ;Types:
Например:
[Components]
Name: a; Description: A; Types: custom
после удаления:
[Components]
Name: a; Description: A
Optitron
03-12-2013, 15:42
Добрый день. Подскажите пожалуйста, как сделать так, чтобы у каждого компонента путь установки по дефолту был разный.
как сделать так, чтобы у каждого компонента путь установки по дефолту был разный. »
[Components]
Name: a; Description: Папка 1
Name: b; Description: Папка 2
Name: c; Description: C:\Windows\Папка
Name: d; Description: C:\Program Files\Папка
Name: e; Description: C:\Папка
[Files]
Source: Папка\*; DestDir: {app}\Папка1; Flags: ignoreversion recursesubdirs createallsubdirs; Components: a
Source: Папка\*; DestDir: {app}\Папка2; Flags: ignoreversion recursesubdirs createallsubdirs; Components: b
Source: Папка\*; DestDir: {win}\Папка; Flags: ignoreversion recursesubdirs createallsubdirs; Components: c
Source: Папка\*; DestDir: {pf}\Папка; Flags: ignoreversion recursesubdirs createallsubdirs; Components: d
Source: Папка\*; DestDir: {sd}\Папка; Flags: ignoreversion recursesubdirs createallsubdirs; Components: e
Johny777
03-12-2013, 16:38
Raf-9600, Спасибо, но это не совсем то, в чём затык произошёл. Кроме этого функционала, нужно ещё чтобы после того как воспроизведение само завершиться (без клика пользователя по кнопке Стоп), кнопка Стоп становилась неактивной. »
вот пример. Перенёс отсюда http://programmersforum.ru/showthread.php?p=426736
попутно читал справку, чего и тебе советую, тк возможностей много, например регулировка громкости, отображение прогресса, перемотка, итд
http://www.un4seen.com/doc/#bass/BASS_StreamCreateFile.html
короче вот код конкретно по твоему вопросу:
[Files]
Source: bass.dll; Flags: dontcopy
[Code ]
type
HSYNC = DWORD;
SYNCPROC = Longint;
Pointer = Longint;
HSTREAM = DWORD;
const
BASS_SYNC_END = 2;
BASS_UNICODE = $80000000;
function BASS_ChannelRemoveSync(handle: DWORD; sync: HSYNC): BOOL; external 'BASS_ChannelRemoveSync@files:bass.dll stdcall';
function BASS_ChannelSetSync(handle: DWORD; type_: DWORD; param1, param2: DWORD; proc: SYNCPROC; user: Pointer): HSYNC; external 'BASS_ChannelSetSync@files:bass.dll stdcall';
function BASS_Init(device: LongInt; freq, flags: DWORD; win: HWND; clsid: Pointer): BOOL; external 'BASS_Init@files:bass.dll stdcall';
function BASS_StreamCreateFile(mem: BOOL; f: String; offset1: DWORD; offset2: DWORD; length1: DWORD; length2: DWORD; flags: DWORD): HSTREAM;
external 'BASS_StreamCreateFile@files:bass.dll stdcall';
function BASS_StreamFree(handle: HSTREAM): BOOL; external 'BASS_StreamFree@files:bass.dll stdcall';
function BASS_ChannelPlay(handle: DWORD; restart: BOOL): BOOL; external 'BASS_ChannelPlay@files:bass.dll stdcall';
function BASS_Free(): BOOL; external 'BASS_Free@files:bass.dll stdcall';
var
Channel: HSTREAM;
PlaySync: DWORD;
BassInitialized: BOOL;
StopBtn, PlayBtn: TButton;
// Процедура которая будет вызвана по окончанию проигривания файла
procedure ChannelEndSync(handle: HSYNC; Stream, data: DWORD; user: Pointer);
begin
// Вот здесь обрабатывайте окончание!
// Когда Channel доиграет до конца, то будет вызвана эта процедура
// Например освободим этот поток который проигрался
// Сперва удалим обработку
BASS_ChannelRemoveSync(Stream, Handle);
// Освободим поток
BASS_StreamFree(Stream);
// Очистим переменные
Channel := 0;
PlaySync := 0;
// Покажем пользователю что файл проигран до конца...
//MsgBox('Файл проигран!', mbInformation, MB_OK);
StopBtn.Enabled := False;
end;
// Просто процедура которая открывает файл и проигривает его
procedure BASS_PlayFile(const FilePath: String);
begin
if Channel = 0 then
begin
// Открываем файл...
Channel := BASS_StreamCreateFile(False, FilePath, 0, 0, 0, 0,
#ifdef UNICODE
BASS_UNICODE
#else
0
#endif
);
// Начинаем его воспроизведение
BASS_ChannelPlay(Channel, False);
// А вот здесь используем флаг BASS_SYNC_END и указываем на нашу процедуру
// ChannelEndSync котора будет запущена по окончанию проигривания файла
PlaySync := BASS_ChannelSetSync(Channel, BASS_SYNC_END, 0, 0, CallbackAddr('ChannelEndSync'), 0);
end else
begin
// Если файл уже играет, то отключаем его
BASS_ChannelRemoveSync(Channel, PlaySync);
BASS_StreamFree(Channel);
// Открываем файл...
Channel := BASS_StreamCreateFile(False, FilePath, 0, 0, 0, 0,
#ifdef UNICODE
BASS_UNICODE
#else
0
#endif
);
// Начинаем его воспроизведение
BASS_ChannelPlay(Channel, False);
// А вот здесь используем флаг BASS_SYNC_END и указываем на нашу процедуру
// ChannelEndSync котора будет запущена по окончанию проигривания файла
PlaySync := BASS_ChannelSetSync(Channel, BASS_SYNC_END, 0, 0, CallbackAddr('ChannelEndSync'), 0);
end;
end;
function InitBass(const _hwnd: HWND): BOOL;
begin
Result := BassInitialized;
if not Result then
begin
Result := BASS_Init(-1, 44100, 0, _hwnd, 0);
BassInitialized := Result;
end;
end;
procedure StopAndFree();
begin
if PlaySync <> 0 then
begin
BASS_ChannelRemoveSync(Channel, PlaySync);
PlaySync := 0;
end;
// Освободим поток
if Channel <> 0 then
begin
BASS_StreamFree(Channel);
Channel := 0;
end;
end;
function DeInitBass(): BOOL;
begin
Result := not BassInitialized;
if not Result then
begin
Result := Bass_Free();
BassInitialized := not Result;
end;
end;
/////////////////////////////////// demo /////////////////////////////////
procedure BtnClick(Sender: TObject);
var
uFilePath: String;
begin
case TButton(Sender) of
PlayBtn:
begin
uFilePath := '';
if GetOpenFileName('Choose audio file', uFilePath, ExpandConstant('{userdesktop}'), 'mp3 files (*.mp3)|*.mp3|All files (*.*)|*.*', 'mp3') then
if uFilePath <> '' then
BASS_PlayFile(uFilePath);
StopBtn.Enabled := True;
end;
StopBtn:
begin
StopAndFree();
StopBtn.Enabled := False;
end;
end;
end;
procedure InitializeWizard();
begin
BassInitialized := False;
InitBass(0);
//////////////////////////////////
WizardForm.OuterNotebook.Hide;
PlayBtn := TButton.Create(WizardForm);
with PlayBtn do
begin
Parent := WizardForm;
SetBounds(100, 100, 65, 25);
Caption := 'Play';
OnClick := @BtnClick;
end;
StopBtn := TButton.Create(WizardForm)
with StopBtn do
begin
Parent := WizardForm;
SetBounds(200, 100, 65, 25);
Caption := 'Stop';
OnClick := @BtnClick;
end;
end;
procedure DeinitializeSetup();
begin
DeInitBass();
end;
[/color]
Всем здравствуйте!
Подскажите плиз, как можно на момент запуска деинсталлятора узнать текущую директорию, где находится этот самый деинсталлятор. GetCurrentDir почему-то возвращает не директорию расположения, а систем32
Mailchik
03-12-2013, 19:22
Shkutu, #define AppId "My Application"
[Setup]
AppID={#AppId}
AppName=My Application
AppVersion=1.5
DefaultDirName={pf}\My Application
[Code]
var
UninsPath: string;
function InitializeUninstall(): boolean;
begin
if RegQueryStringValue(HKLM, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{#AppId}_is1',
'UninstallString', UninsPath) then begin
UninsPath := ExtractFilePath(RemoveQuotes(UninsPath));
MsgBox(UninsPath, mbInformation, MB_OK);
end;
Result := True;
end;
Raf-9600
03-12-2013, 19:53
Johny777, Спасибо! Никаких особых проблем не возникло. Единственная мелочь: в твоём коде проверка в процедуре BASS_PlayFile такая if Channel <> 0 then, а должно быть if Channel = 0 then.
Собственно вот как эта часть выглядит у меня:
// Просто процедура которая открывает файл и проигривает его
function BASS_PlayFile(const Sounds: array of String): boolean;
var
TempSoundName, uSoundPath: String;
i: integer;
begin
i := GetArrayLength(Sounds);
TempSoundName := Sounds[Random(i)];
// Не воспроизводим один файл два раза под ряд если их хотябы два.
if i >= 1 then
if TempSoundName = uSoundName then
BASS_PlayFile(Sounds)
else
uSoundName := TempSoundName;
if not FileExists(AddBackslash(RemoveBackslash(ExpandConstant('{tmp}'))) + 'BASS.dll') then ExtractTemporaryFile('BASS.dll');
uSoundPath := ExpandConstant(AddBackslash(RemoveBackslash(ExpandConstant('{tmp}'))) + uSoundName);
if not FileExists(uSoundPath) then ExtractTemporaryFile(uSoundName);
if Channel = 0 then
begin
// Открываем файл...
Channel := BASS_StreamCreateFile(False, uSoundPath, 0, 0, 0, 0,
#ifdef UNICODE
BASS_UNICODE
#else
0
#endif
);
// Начинаем его воспроизведение
Result := BASS_ChannelPlay(Channel, False);
// А вот здесь используем флаг BASS_SYNC_END и указываем на нашу процедуру
// ChannelEndSync котора будет запущена по окончанию проигривания файла
PlaySync := BASS_ChannelSetSync(Channel, BASS_SYNC_END, 0, 0, CallbackAddr('ChannelEndSync'), 0);
end else
begin
// Если файл уже играет, то отключаем его
BASS_ChannelRemoveSync(Channel, PlaySync);
BASS_StreamFree(Channel);
// Открываем файл...
Channel := BASS_StreamCreateFile(False, uSoundPath, 0, 0, 0, 0,
#ifdef UNICODE
BASS_UNICODE
#else
0
#endif
);
// Начинаем его воспроизведение
Result := BASS_ChannelPlay(Channel, False);
// А вот здесь используем флаг BASS_SYNC_END и указываем на нашу процедуру
// ChannelEndSync котора будет запущена по окончанию проигривания файла
PlaySync := BASS_ChannelSetSync(Channel, BASS_SYNC_END, 0, 0, CallbackAddr('ChannelEndSync'), 0);
end;
end;
El Sanchez
03-12-2013, 19:59
как можно на момент запуска деинсталлятора узнать текущую директорию, где находится этот самый деинсталлятор »
Shkutu,
function InitializeUninstall(): Boolean;
begin
Result := True;
MsgBox(ExtractFileDir(ExpandConstant('{uninstallexe}')), mbInformation, MB_OK);
end;
Спрашивал на руборде
Есть набор программ устанавливаемых через инно, среди компонентов допустим есть прога 1.exe
возможно ли
если пользователь выбрал установку этой программы, выходило сообщение
"Внимание! Прежде чем установить эту программу, необходимо установить бла бла бла... Выполнить необходимые условия?" и кнопки в этом сообщении
Да (я позже выполню) - тогда чекбокс автоматом с этой проги снимается и продолжается установка других компонентов (если они выбраны)
Нет (уже установлено) - тогда чекбокс автоматом с этой проги НЕ снимается и продолжается установка выбраной 1.exe и других компонентов (если они выбраны)
дали скрипт
[components]
Name: fuck; Description: lol;
Name: fuck2; Description: lol2;
[_code]
procedure CurPageChanged(CurPageID: Integer);
var i: integer;
begin
if Curpageid=wpWelcome then
if MsgBox('fuck',mbInformation,mb_YesNo)=idyes then
for i:=0 to WizardForm.ComponentsList.ItemCount-1 do
begin
MsgBox(WizardForm.ComponentsList.ItemCaption[i],mbinformation,mb_ok);
if WizardForm.ComponentsList.ItemCaption[i]='lol' then WizardForm.ComponentsList.Checked[i]:=False else WizardForm.ComponentsList.Checked[i]:=True;
end;
end;
при компоновке вываливается ошибка
http://i58.fastpic.ru/big/2013/1203/50/04dcac26b6103482dbeb5afd3bc95e50.jpg
как исправить или может какой другой есть скрипт?
Johny777
04-12-2013, 04:32
Raf-9600,
Единственная мелочь: в твоём коде проверка в процедуре BASS_PlayFile такая if Channel <> 0 then, а должно быть if Channel = 0 then. »
Не такая уж и мелочь. Благодарю! Я её проглядел.
Собственно вот как эта часть выглядит у меня. Не воспроизводим один файл два раза под ряд если их хотябы два. »
Ну давай теперь разбирать, что ты там написал :)
if i >= 1 then
означает "если длина массива больше-равно 1".
Не вижу смысла. Если длина массива 1, то рандом не нужен
Если больше одного, рандом уместен
те мы уже пишем
if i = 1 then uSoundName := Sounds[0]
else
if i > 1 then ипользуем рандом, но
ты хочешь чтоб файлы не проигрывались два раза подряд и рекурсивно вызываешь BASS_PlayFile() пока значения TempSoundName и uSoundName будут разными.
Да функция GetArrayLength() и Random() работают быстро, но мы не знаем сколько раз пройдёт рекурсия пока рандом не выдаст другое значение. Те тут крайне нестабильная секция кода с точки зрения скорости. Другими словами очень желательно другое решение. В данном случае модификация рандома. Вот кокретно для решения этой задачи наваял код:
алгоритм простой - чистая математика
функция function RandRange(const LeftInt, RightInt: Integer): Integer;
где LeftInt - левая граница
RightInt - правая
условие RightInt > LeftInt хотя бы на 1
например мы хотим получить случайные числа от 2 до 7 включительно.
функция
function NotRandRand(const LeftInt, RightInt: Integer; var LastResultInt: Integer): Integer;
где всё тоже самое кроме LastResultInt, в которую пишется значение последнего результата.
условие: переменная, которую отправляем в var LastResultInt: Integer должна быть глобальной (это съест всего лишь 4 байта памяти процесса), иначе ничего работать не будет!
как она работает думаю понятно по коду. Единственное скажу, что если последнее выпавшее число не равно левой границе и павой, то значит речь идёт о 2-х половинах
и тут мы доверим рандому case Random(2) of
например у нас числа 1...7. Вапало 5. --> в след. раз в Random(2) выпал 0 (рандом возвращает входное значение -1), то мы выполним RandRange(1, 5-1)
если выпала 1, то RandRange(5+1, 7)
короче говоря никаких повторов 222, 33, итд. Минимум через 1
вот код:
function RandRange(const LeftInt, RightInt: Integer): Integer;
begin
Result := Random( (RightInt + 1)-LeftInt ) + LeftInt;
end;
function NotRandRand(const LeftInt, RightInt: Integer; var LastResultInt: Integer): Integer;
begin
Result := RandRange(LeftInt, RightInt);
if Result = LastResultInt then
begin
if LastResultInt = LeftInt then
Result := RandRange(LeftInt+1, RightInt)
else
if LastResultInt = RightInt then
Result := RandRange(LeftInt, RightInt-1)
else
case Random(2) of
0: Result := RandRange(LeftInt, LastResultInt-1);
1: Result := RandRange(LastResultInt+1, RightInt);
end;
end;
LastResultInt := Result;
end;
procedure Test();
var
sArray: array [0..3] of String;
S: String;
i, e, L, R, LastInt: Integer;
begin
for i := 0 to 3 do
begin
sArray[i] := IntToStr(i+1) + ')' + #32;
case i of
0:
begin
L := 1;
R := 9;
end;
1:
begin
L := 7;
R := 8;
end;
2:
begin
L := 2;
R := 16;
end;
3:
begin
L := 0;
R := 1;
end;
end;
for e := 0 to 7 do
sArray[i] := sArray[i] + #32#32#32 + IntToStr(NotRandRand(L, R, LastInt));
LastInt := 0;
end;
S := sArray[0];
for i := 1 to 3 do
S := S + #13#10 + sArray[i];
MsgBox(S, mbInformation, MB_OK);
end;
procedure InitializeWizard();
begin
Test();
end;
процедура Test(); отладочная. Вот мой результат
http://img822.imageshack.us/img822/3613/tbfg.png (http://imageshack.us/photo/my-images/822/tbfg.png/)
обрати внимание на 2 и 4-ю строку. Как и следовало ожидать при RightInt - LeftInt = 1 значения чередуются
вот твой участок кода (обновлённый):
var
LastInt: Integer;
function BASS_PlayFile(const Sounds: array of String): boolean;
var
TempSoundName, uSoundPath: String;
Len: integer;
begin
Len := GetArrayLength(Sounds);
// Не воспроизводим один файл два раза под ряд если их хотябы два.
if Len = 1 then
uSoundName := Sounds[0];
else
if Len > 1 then
uSoundName := Sounds[ NotRandRand(0, Len-1, LastInt) ];
Хочу заметить. У меня лежит код (пока времени нет довести до ума :( ) настоящего рандома из микрофона ноутбука. Те шум окружающей среды. И там бывают подряд повторяющиеся значения. Те повтор для рандома это нормально, в противном случае это не рандом, а какой-то счётчик!
строка
if not FileExists(AddBackslash(RemoveBackslash(ExpandConstant('{tmp}'))) + 'BASS.dll') then ExtractTemporaryFile('BASS.dll');
не нужна (заметь у меня в коде её нет), тк BASS.dll итак извлекается для последующей её динамичной загрузки
=========================================================================================
ispolin, у меня компилятор на Свойство ItemCount не ругается. Использую расширенную версию(не самую новую - 5.4.3). В шапке есть ссылка на расширенную.
В шапке есть ссылка на расширенную. » Но нет ссылок на соответствующую (http://forum.oszone.net/post-2239520-1337.html) версию Inno для расширенной.
El Sanchez, Добавь пожалуйста ссылки на соответствующую версию хотя бы под спойлер "Расширенная версия Inno Setup от Restools".
Пример:
Рекомендуемая версия:
isetup-5.5.1.exe (http://files.jrsoftware.org/ispack/ispack-5.5.1.exe) - ANSI версия
ispack-5.5.1-unicode.exe (http://files.jrsoftware.org/ispack/ispack-5.5.1-unicode.exe) - Unicode версия
Сайт: http://restools.hanzify.org/
Скачать: Inno Setup Compiler (http://restools.hanzify.org/inno/InnoCompiler121216(7zip).zip) build 121216;
Inno ISCmplr Setup (http://restools.hanzify.org/inno/Inno_ISCmplr_Setup121002(7zip).zip) build 121002;
Рекомендуется к применению из-за огромного количества компонентов, функций и процедур, удобного интерфейса, наличия отладчика и Form Designer. Собран на основе исходников Inno Setup 5.5.1.
Инструкция по установке:
Установите ispack-X.X.X.exe или ispack-X.X.X-unicode.exe (X.X.X - номер актуальной версии);
Скачайте Inno Setup Compiler, распакуйте;
Из одноимённой папки, в соответствии с установленной версией (Ansi или Unicode), скопируйте два файла (Compil32.exe, Templates.dat) в каталог Inno Setup (по умолчанию: C:\Program Files\Inno Setup 5\). Появится сообщение с подтверждением о замене файла, нажимаем 'Да'.
Примечание: если у вас Unicode версия, то дополнительно примените твик реестра (файл CourierNew.reg) из папки UnicodeFontLink и перезагрузите компьютер.
Скачайте Inno ISCmplr Setup, распакуйте;
Из одноимённой папки, в соответствии с установленной версией (InnoSetup_ANSI или InnoSetup_Unicode), из подпапки FullVCL скопируйте все файлы в каталог Inno Setup (по умолчанию: C:\Program Files\Inno Setup 5\). Появится сообщение с подтверждением о замене файла, нажимаем 'Да'.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.