Показать полную графическую версию : Скрипты Inno Setup. Помощь и советы [часть 6]
nik1967, возможно у Вас личка переполнена, Вы видели мое сообщение?
_____________________________
Вопрос знающим: как прописать для файла *.exe старт при загрузке системы?
как прописать для файла *.exe старт при загрузке системы? »
Для текущего пользователя
[Registry]
Root: HKCU; SubKey: Software\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: My Program; ValueData: {app}\MyProg.exe; Flags: uninsdeletevalue uninsdeletekeyifempty
Для всех пользователей
[Registry]
Root: HKLM; SubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: My Program; ValueData: {app}\MyProg.exe; Flags: uninsdeletevalue uninsdeletekeyifempty
Пример:
[Setup]
AppName=My Program
AppVersion=1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
OutputBaseFilename=setup
[Tasks]
Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:AdditionalIcons}; Flags: unchecked
[Files]
Source: compiler:Examples\MyProg.exe; DestDir: {app}; Flags: ignoreversion
[Icons]
Name: {group}\My Program; Filename: {app}\MyProg.exe
Name: {commondesktop}\My Program; Filename: {app}\MyProg.exe; Tasks: desktopicon
[Run]
Filename: {app}\MyProg.exe; Description: {cm:LaunchProgram,My Program}; Flags: nowait postinstall skipifsilent
[Registry]
Root: HKLM; SubKey: SOFTWARE\Microsoft\Windows\CurrentVersion\Run; ValueType: string; ValueName: My Program; ValueData: {app}\MyProg.exe; Flags: uninsdeletevalue uninsdeletekeyifempty
Dimon585h
29-11-2013, 19:09
Подскажите ещё, надо сделать так, чтобы инсталлятор сканировал выбранную папку на нужный файл и если он есть, то разрешал установку дальше, а если нет, то не разрешал и надо выбрать папку где есть.
sergey3695
29-11-2013, 20:03
Dimon585h, есть один старый пример проверки файла по md5 и путь тут берется из реестра. если файл не найден,то нужно указать его. Думаю в твоем случае это нужно.
#define Key "HKLM\SOFTWARE\7-Zip"
#define Subkey "Path"
#define Filename "7zFM.exe"
#define MD5 "6c14c21147452b73ddd51a1af9be0a87"
[Setup]
AppName=MyApp
AppVerName=MyApp
DefaultDirname={pf}\MyApp
[CustomMessages]
DirBrowseMessage=Пожалуйста, укажите расположение программы MyApp
[code ]
var
Root: Integer; DestDir, Key, Subkey: String;
function GetRegPath(): String;
var str1, str2: string;
begin
str1:=Copy('{#Key}', 1, Pos('\', '{#Key}')-1);
case AnsiUppercase(str1) of
'HKLM': Root:= HKLM; 'HKCU': Root:= HKCU;
'HKCR': Root:= HKCR; 'HKU': Root:= HKU;
'HKCC': Root:= HKCC;
end;
Key:=Copy('{#Key}', Pos('\', '{#Key}')+1, Length('{#Key}'));
Subkey:='{#Subkey}'; Result:='';
If RegQueryStringValue(Root, Key, Subkey, str2) then
if str2<>'' then Result:=str2
end;
Function CheckPath(Path, Filename, MD5: String): Boolean;
begin
Result:= False;
If FileExists(AddBackslash(Path)+Filename) then
if AnsiUpperCase(GetMD5OfFile(AddBackslash(Path)+Filename))=AnsiUppercase(MD5) then Result:=True;
end;
Function GetPath(): Boolean;
var Check, Cancel: Boolean;
begin
DestDir:=GetRegPath(); Check:=CheckPath(DestDir, '{#Filename}', '{#MD5}');
if Check = False then
begin
repeat
Cancel:=BrowseForFolder(ExpandConstant('{cm:DirBrowseMessage}'), DestDir, False);
Check:=CheckPath(DestDir, '{#Filename}', '{#MD5}');
until (not(Check=False))or(not Cancel);
end;
if (Check = True) then Result:=Check else Result:= Cancel;
end;
Function InitializeSetup(): Boolean;
begin
Result:= GetPath;
end;
procedure InitializeWizard();
begin
WizardForm.DirEdit.Text:= DestDir;
end;
sergey3695, Это перебор.
надо сделать так, чтобы инсталлятор сканировал выбранную папку на нужный файл и если он есть, то разрешал установку дальше, а если нет, то не разрешал и надо выбрать папку где есть. »
Эх, кто ищет - тот найдёт (http://forum.oszone.net/post-2193282-933.html). Лишь бы желание только было.
[Code]
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
case CurPageID of
wpSelectDir:
begin
Result := FileExists(ExpandConstant('{app}\MyProg.exe'));
if not Result then MsgBoxEx(WizardForm.Handle, 'Ошибка! Приложение' + #32 + ExpandConstant('{#SetupSetting("AppName")}') + #32 + 'не найдено на данном компьютере', 'Ошибка', MB_OK or MB_ICONWARNING, 0, 0);
end;
end;
end;
Dimon585h, И удали посты #1551 и #1561, ни к чему плодить близнецов.
tuz-veta
29-11-2013, 21:35
Так че поможет кто или нет? :dont-know
Для текущего пользователя »
Спс. Именно такой способ я и искал.
А есть ли способ заставить программу автоматом закрываться при завершении работы Windows? Просто программа записывает данные в конфиг при выходе, а при жестком завершении работы (убийство процесса) не записывает в конфиг изменения.
Вот смотрю я, и удивляюсь. Писать по несколько одинаковых постов с просьбой, пальцы не устают. А нажать http://tools.oszone.ru/Vadikan/img/thankyou.gif у пальчика силы иссякли?
Dimon585h, dima.dmitrienko.71@fb - А Johny777, а saurn-а, чего не поблагодарили? Не вижу! Подумайте, как долго бы вы ждали ответа на свой вопрос. Посты: #662 (http://forum.oszone.net/post-2169372-662.html), #933 (http://forum.oszone.net/post-2193282-933.html), #1324 (http://forum.oszone.net/post-2239106-1324.html).
И иногда полезно читать (http://forum.oszone.net/faq.php?faq=vb_board_usage#faq_thanks) справочку (http://forum.oszone.net/faq.php) на форуме.
tuz-veta
30-11-2013, 12:48
Жалко что на мой вопрос нет ответа!
Mailchik
30-11-2013, 14:28
tuz-veta, скройте MessageBox
[Code]
#ifdef UNICODE
type
PChar = PAnsiChar;
#endif
const
BM_CLICK = $00F5;
function FindWindowEx(Parent, Child: Longint; ClassName, WindowName: PChar): Longint;
external 'FindWindowExA@user32.dll stdcall';
var
tmr: TTimer;
procedure Timer(Sender: TObject);
var
hWnd: Longint;
begin
hWnd := FindWindowByWindowName(SetupMessage(msgNoUninstallWarningTitle));
if hWnd > 0 then
PostMessage(FindWindowEx(hWnd, 0, 'Button', PChar(SetupMessage(msgButtonYes))), BM_CLICK, 0, 0);
end;
procedure InitializeWizard;
begin
tmr := TTimer.Create(WizardForm);
with tmr do begin
Enabled := False;
Interval := 5;
OnTimer := @Timer;
end;
end;
procedure CurPageChanged(CurPageID: Integer);
begin
tmr.Enabled := CurPageID = wpSelectComponents;
end;
Всем привет.
Johny777 пример очень даже :clapping: http://forum.oszone.net/post-2259324-1482.html можно ли как-то прикрутить ко всей этой прелести, какие файлы копируются и полный путь копирования, и рамер в мегабайтах? А то я что-то долго уже этим не занимался и конкретно "отупел" :gulp:
Ну и ещё, если конечно позволите, вопрос к знатокам. Как в инсталлятор портируется (если можно так сказать) электронная подпись? И как вписывается имя издателя?
Johny777
30-11-2013, 23:11
Tco 03,
можно ли как-то прикрутить ко всей этой прелести, какие файлы копируются и полный путь копирования, и рамер в мегабайтах »
О чём речь? Уже ж есть! Ты на прототип функции обратного вызова посмотри _FILE_CALLBACK:
_FILE_CALLBACK =
function
(
const Msg: Integer; //сообщение статуса копирования
const srcFilePath: String; //путь к текущему исходному файлу
const dstFilePath: String; //путь к текущему файлу назначения
const FileBytes: Extended; //размер текущего файла в байтах
const FileBytesCopied: Extended; //сколько байт текущего файла скопировано
const OverallBytes: Extended; //размер всех файлов в байтах
const OverallBytesCopied: Extended //сколько байт всех файлов скопировано
): Boolean; //чтоб отменить копирование нужно вернуть False
только размер в байтах (так кстати и надо), которые уже не проблема математически перевести в нужную тебе единицу измерения памяти! :)
Как в инсталлятор портируется (если можно так сказать) электронная подпись? »
хз
И как вписывается имя издателя? »
справка --> директивы секции [Setup] --> VersionInfo*** директивы ?
=========================================================================
Raf-9600,
Т.е. мне нужно сделать чтобы кнопка "Стоп" (прерывающая воспроизведение) была активной только если что-то воспроизводиться. »
в начале функции
function PlayRandDemoSound(const Sounds: array of String): boolean;
напиши StopSoundBtn.Enabled := True;
в procedure InitializeWizard(); впиши StopSoundBtn.Enabled := False;
ну и в событии StopSoundBtn.OnClick закатай в конце
TButton(Sender).Enabled := False;
О чём речь? Уже ж есть! Ты на прототип функции обратного вызова посмотри _FILE_CALLBACK: »
Я имею в виду реализовать вот такой вид. Чтобы, что, куда копируется было бы видно.
http://4put.ru/pictures/small/791/2432416.jpg (http://4put.ru/view-max-picture.php?id=2432416)
А если ещё к твоему примеру и проценты прикрутить, будет вообще класс!
только размер в байтах (так кстати и надо), которые уже не проблема математически перевести в нужную тебе единицу измерения памяти! »
Я всё понимаю, так правильно, но для человеческого глаза, согласись смотрится как-то не так. :)
sergey095
01-12-2013, 18:12
Здравствуйте. Помогите мне. Что делать, у меня что-то плохо отображается дополнительные слова, которые я вписал.
http://forum.oszone.net/attachment.php?attachmentid=107450&stc=1&d=1385907108
Johny777
01-12-2013, 18:16
Tco 03,
Я имею в виду реализовать вот такой вид. Чтобы, что, куда копируется было бы видно. »
вот тебе ещё лучше:
http://img593.imageshack.us/img593/2702/nn2h.png (http://imageshack.us/photo/my-images/593/nn2h.png/)
код ( замени участок "demo" в этом примере http://forum.oszone.net/post-2259324-1482.html ):
//////////////////////////////////////////// demo //////////////////////////////////////////////////////////////////
function GetTickCount: DWORD; external 'GetTickCount@kernel32.dll stdcall';
const
SPACE = #32;
KILOBYTE = 1024;
MEGABYTE = 1048576;
GIGABYTE = 1073741824;
//TERABYTE = 1099511627776;
function TicksToTime(const Ticks: Single): String;
var
hCount, mCount, sCount: Integer;
LocalTicks: Single;
begin
Result := '';
if Ticks = 0 then Exit;
LocalTicks := Ticks/1000;
hCount := Round(LocalTicks) div 3600;
LocalTicks := LocalTicks-hCount*3600;
mCount := Round(LocalTicks) div 60;
sCount := Round(LocalTicks-mCount*60);
if hCount <> 0 then Result := Result + IntToStr(hCount) + SPACE + 'Hours' + SPACE;
if mCount <> 0 then Result := Result + IntToStr(mCount) + SPACE + 'Min' + SPACE;
if sCount <> 0 then Result := Result + IntToStr(sCount) + SPACE + 'Sec';
end;
function ConvertSize(const Bytes: Extended): String;
begin
if Bytes < KILOBYTE then
Result := Format('%d b', [Bytes])
else
if Bytes < MEGABYTE then
Result := Format('%.2f Kb', [Bytes/KILOBYTE])
else
//if Bytes < GIGABYTE then
Result := Format('%.2f Mb', [Bytes/MEGABYTE]);
end;
function RemTime(
const StartTime: Integer;
const NowTime: Integer;
const Count: Extended;
const OverallCount: Extended
): Integer;
var
TimePast: Integer;
CountLeft: Extended;
begin
Result := 0;
if Count = 0 then Exit;
TimePast := NowTime - StartTime;
CountLeft := OverallCount - Count;
Result := Round(( TimePast * CountLeft ) / Count);
// Example: OverallCount = 1000;
// Count = 50;
// TimePast = 3000[Ms] (NowTime - StartTime);
//
// 50 [Count] - 3000[Ms]
// 950[Count] - x [Ms]
//
// Result = ( 3000[Ms] * 950[Count] ) div 50[Count]
end;
const
NEW_LINE = #13#10;
var
MainCopyPrgBar,FileCopyPrgBar: TNewProgressBar;
FileStatic: TNewStaticText;
CopyStartTime: Integer;
function ____________________
(
const Msg: Integer;
const srcFilePath: String;
const dstFilePath: String;
const FileBytes: Extended;
const FileBytesCopied: Extended;
const OverallBytes: Extended;
const OverallBytesCopied: Extended
): Boolean;
var
OverallPercent, FilePercent: Integer;
begin
case Msg of
COPY_COLLECTING_INFO: FileStatic.Caption := 'Processing: ' + srcFilePath;
COPY_IN_PROGRESS:
begin
if CopyStartTime = 0 then CopyStartTime := GetTickCount();
OverallPercent := Round( (100*OverallBytesCopied) / OverallBytes );
FilePercent := Round( (100*FileBytesCopied) / FileBytes );
FileCopyPrgBar.Position := FilePercent;
MainCopyPrgBar.Position := OverallPercent;
FileStatic.Caption :=
'Copying:' + NEW_LINE +
'Source: ' + srcFilePath + NEW_LINE +
'Dest: ' + dstFilePath + NEW_LINE +
+ NEW_LINE +
'Overall: ' + ConvertSize( OverallBytesCopied ) + ' of ' +
ConvertSize( OverallBytes ) + ', ' +
IntToStr( OverallPercent ) + '[%]' + NEW_LINE +
'File: ' + ConvertSize( FileBytesCopied ) + ' of ' +
ConvertSize( FileBytes ) + ', ' +
IntToStr( FilePercent ) + '[%]' + NEW_LINE +
+ NEW_LINE +
'Remaining Time: ' + TicksToTime( RemTime(CopyStartTime, GetTickCount, OverallBytesCopied, OverallBytes) ) + NEW_LINE +
'Elapsed Time: ' + TicksToTime( GetTickCount() - CopyStartTime );
end;
COPY_FINISHED: MsgBox('Finish! :)', mbInformation, MB_OK);
end;
Application.ProcessMessages;
Result := not Application.Terminated;
end;
procedure ButtonClick(Sender: TObject);
begin
CopyFiles('D:\Freemans Mind\', 'C:\downloads',['*'], SET_PROCESS_READONLY_FILES or SET_OVERWRITE_EXISTING_FILES, @____________________);
end;
procedure InitializeWizard();
begin
CopyStartTime := 0;
WizardForm.OuterNotebook.Hide;
MainCopyPrgBar := TNewProgressBar.Create(nil);
with MainCopyPrgBar do
begin
Parent:= WizardForm;
SetBounds(ScaleX(5), ScaleY(5), WizardForm.ClientWidth-10, ScaleY(20));
end;
FileCopyPrgBar := TNewProgressBar.Create(nil);
with FileCopyPrgBar do
begin
Parent:= WizardForm;
SetBounds(ScaleX(5), ScaleY(30), WizardForm.ClientWidth-10, ScaleY(20));
end;
FileStatic := TNewStaticText.Create(WizardForm);
with FileStatic do
begin
Parent := WizardForm;
SetBounds(ScaleX(5), ScaleY(65), WizardForm.ClientWidth-10, ScaleY(20));
Caption := '...';
end;
with TButton.Create(WizardForm) do
begin
Parent:= WizardForm;
Left := ScaleX(0);
Top := ScaleY(200);
Width := ScaleY(150);
Caption:='Copy';
OnClick:=@ButtonClick;
end;
end;
PS: повторюсь. Та инфа которую, ты хочешь отобразить + то, что я дополнительно отображаю высчитывается в каллбэке (функции обратного вызова)
короче прочитай внимательно пример!
можно ещё прикрутить время (оставшееся, прошедшее) для текущего файла, но я не стал перегружать код, тк думаю, что это лишнее
=====================================================================================
sergey095,
используй функцию
function CustomMessage(const MsgName: String): String; // Returns the value of the [CustomMessages] entry with the specified name.
например: свойство класса(пр. Caption, Text) := CustomMessage('infopath01');
вот тебе ещё лучше: »
Вот, это совсем другое дело :) Мне по большому счёту это не нужно, просто понравился код, а именно: отображение прогресс бара и прочая информация при копировании.
Хотя считывание размера и процентов каждого копирующегося файла, малых размеров, отображается мельканием строчки и конкретно там ничего не увидеть.
И ещё, если тебе интересно, вот такая ошибка, иногда имеет место быть:
http://4put.ru/pictures/small/792/2434138.jpg (http://4put.ru/view-max-picture.php?id=2434138)
sergey095
01-12-2013, 19:26
Johny777, Спасибо. Все встало как надо.
Dimon585h
01-12-2013, 19:42
Как сделать чтобы при удалении, удалялись только установленные файлы?
Цитата Dimon585h:
Как сделать чтобы при удалении, удалялись только установленные файлы? »
По умолчанию (если не исползуются сторониие распаковщики) то есть, если запаковать проект только Inno, то после установки удаляются только те файлы, которые скопированы. Все установленные файлы прописываются в unins000.dat
Если ипользуются сторонние распаковщики, то нужно прописать что удалить:
Пример:
[UninstallDelete]
Name: "{app}\Dair1"; Type: filesandordirs; Удалить папку с файлами
Name: "{app}\Dair2"; Type: dirifempty; Удалить папку только если она пустая
Name: "{app}\MyProgramm.exe"; Type: files; Удалить определённый файл
Raf-9600
02-12-2013, 00:08
в начале функции
function PlayRandDemoSound(const Sounds: array of String): boolean;
напиши StopSoundBtn.Enabled := True;
в procedure InitializeWizard(); впиши StopSoundBtn.Enabled := False;
ну и в событии StopSoundBtn.OnClick закатай в конце
TButton(Sender).Enabled := False; »
Спасибо, но это не совсем то, в чём затык произошёл. Кроме этого функционала, нужно ещё чтобы после того как воспроизведение само завершиться (без клика пользователя по кнопке Стоп), кнопка Стоп становилась неактивной.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC