Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Автоматическая установка Windows » Автоматическая установка приложений » Скрипты Inno Setup. Помощь и советы [часть 8]

Закрытая тема
Настройки темы
Скрипты Inno Setup. Помощь и советы [часть 8]

Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1264
Благодарности: 1024


Конфигурация

Профиль | Отправить PM | Цитировать


Изменения
Автор: El Sanchez
Дата: 22-10-2015
Внимание! Данная тема предназначена только для обсуждения написания скриптов !
Остальные вопросы, а также последние версии компилятора в теме
Inno Setup. Прочие вопросы.


Показать/скрыть: Справка, руководство, примеры:

Показать/скрыть: Ссылки на примеры скриптов:

Показать/скрыть: Дополнительные программы для Inno Setup:
  • ISTool - неплохой редактор скриптов Inno Setup.
    Последняя версия: 5.3.0.1 [29.09.2009] - Скачать | зеркало;

  • Inno Script Generator - генератор скриптов Inno Setup. Обладает некоторыми полезными функциями, которых нет ни у самого Inno Setup, ни у ISTool.
    Последняя версия: 1.0.3.1 [23.03.2008] - Скачать | зеркало на русифицированную программу;
    Примечание: Родной сайт www.hisoft2000.de более недоступен, поэтому здесь расположены сторонние ссылки.

  • Inno Setup Form Designer - редактор страниц Inno Setup, можно создавать свои страницы.
    Последняя версия: 2.0.8 [12.11.2006] - Скачать;
    Примечание: Родной сайт http://isfd.kaju74.de/index.php?isfd более недоступен, поэтому здесь расположены сторонние ссылки.

  • Inno Setup GameScript Generator - программа генерирует скрипты для Inno Setup . С помощью GameScript Generator и Inno Setup вы сможете быстро создать простенький инсталляционный пакет для любой игры. В инсталлятор можно встроить музыку, слайдшоу и фоновый рисунок. Для специалистов созданный скрипт, возможно, будет неплохой заготовкой для дальнейшей модернизации;

  • ISSkin - Программа для создания и добавления в инсталлятор скинов. Инструкция.
    Последняя версия: 3.0.0.0 [19.01.2010] - Скачать;

  • ISSJoiner - Программа для объединения нескольких скриптов InnoSetup в один.
    Последняя версия: 3.0 [23.07.2009]

  • Converter - Программа конвертирует reg-файлы в формат *.iss (формат скриптов Inno Setup).
    Последняя версия: 0.1.4 [13.03.2010] - Скачать;

  • RegExporter - Фриварная утилита для экспорта реестра и конвертации файлов *.reg и *.ini в инсталляционные скрипты Inno Setup и NSIS.
    Последняя версия: 1.2.0 [23.09.2014] - Скачать;



Предыдущие ветки обсуждения по ссылкам ниже и в прикреплённых архивах:

Скрипты Inno Setup. Помощь и советы [часть 6]
Скрипты Inno Setup. Помощь и советы [часть 7]

Отправлено: 08:52, 02-02-2015

 

Новый участник


Сообщения: 10
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: jpg downbar.jpg
(17.4 Kb, 16 просмотров)

Добавил IDPForm.FileProgressBar.Visible := False; IDPForm.TotalProgressBar.Visible := False; в результате получилось такое окно (на скрепке)

Отправлено: 14:31, 09-08-2017 | #2021



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Пользователь


Сообщения: 76
Благодарности: 2

Профиль | Отправить PM | Цитировать


Как сделать чтобы при изменении пути в DirEdit кнопка NewButton становилась активной, а при нажатии на кнопку NewButton
она становилась неактивной?

Отправлено: 00:09, 10-08-2017 | #2022


Аватара для OldGamer

Новый участник


Сообщения: 33
Благодарности: 0

Профиль | Отправить PM | Цитировать


Изображения
Тип файла: png Error.png
(146.4 Kb, 13 просмотров)
Тип файла: png Error-Made some changes.png
(129.5 Kb, 12 просмотров)

Господа, есть тут кто-нибудь, кто разбирается в Unicode-версии Inno Setup?
Или возможно ли отключить жёсткую проверку синтаксиса?

Установил Inno Setup с поддержкой Unicode, чтобы корректно отображалось название языков.
При компиляции появляются ошибки, а в обычной версии компиляция скрипта проходит без каких-либо проблем.

Что делать с этой строкой "record..."?

Сам скрипт
Код: Выделить весь код
#include "botva2.iss"
#include "BASS_Module.iss"
#define GDFExe "{app}\Prog.exe"
#define GDFBinary "{app}\GDF.dll"

[Setup]
SourceDir=.
OutputDir=Setup
AppName=MyProg
AppVersion=1.0
AppPublisher=EmuGames
AppCopyright=EmuGames
AppPublisherURL=
AppSupportURL=
AppUpdatesURL=
DefaultDirName={pf64}\MyProg™
DefaultGroupName=\MyProg™
AllowNoIcons=yes
InfoBeforeFile=\System requirements.txt
InfoAfterFile=\Recommendation.txt
OutputBaseFilename=setup
WizardImageFile=\picture.bmp
WizardSmallImageFile=\small picture.bmp
SetupIconFile=\icon.ico
WindowVisible=no
WindowShowCaption=no
WindowResizable=no
Compression=none
CompressionThreads=4
DiskSpanning=yes
DiskSliceSize=2100000000
SlicesPerDisk=1
RestartIfNeededByRun=no
ShowUndisplayableLanguages=yes

[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl
Name: english; MessagesFile: compiler:Languages\English.isl
Name: french; MessagesFile: compiler:Languages\French.isl
Name: german; MessagesFile: compiler:Languages\German.isl
Name: spanish; MessagesFile: compiler:Languages\Spanish.isl
Name: italian; MessagesFile: compiler:Languages\Italian.isl

[Messages]

SelectLanguageTitle=MyProg
SelectLanguageLabel=Please select a language.                                     Выберите язык установки.

[LangOptions]
russian.LanguageName=Русский / Russian
english.LanguageName=Английский / English
french.LanguageName=Французский / French
german.LanguageName=Немецкий / German
spanish.LanguageName=Испанский / Spanish
italian.LanguageName=Итальянский / Italian

[Tasks]
Name: desktopicon; Description: Создать ярлык на рабочем столе; GroupDescription: Ярлыки:
Name: pin; Description: Закрепить ярлык на панели задач; GroupDescription: Ярлыки:; Flags: unchecked

Name: DirectX; Description: Обновить DirectX; GroupDescription: Дополнительное программное обеспечение:; Flags: checkablealone
Name: Redist; Description: Установить Microsoft Visual C++ 2010 Redist; GroupDescription: Дополнительное программное обеспечение:; Flags: checkablealone

Name: desktopicon; Description: Русский | Английский | Multi6; GroupDescription: Язык интерфейса:; Flags: exclusive

[Files]
Source: include/GDF.dll; DestDir: {app};
Source: include/GameuxInstallHelper.dll; DestDir: {localappdata}; Flags: overwritereadonly
Source: CallbackCtrl.dll; DestDir: {tmp}; Flags: dontcopy
Source: BASS.dll; DestDir: {tmp}; Flags: dontcopy
Source: innocallback.dll; Flags: dontcopy
Source: botva2.dll; DestDir: {tmp}; Flags: dontcopy
Source: Bass_Files\*; DestDir: {tmp}; Flags: dontcopy
Source: OST.mp3; DestDir: {tmp}; Flags: dontcopy
Source: "\MyProg™.png"; DestDir: {tmp}; Flags: ignoreversion dontcopy nocompression
Source: "\miniature.png"; DestDir: {tmp}; Flags: ignoreversion dontcopy nocompression
Source: "\miniature-2.png"; DestDir: {tmp}; Flags: ignoreversion dontcopy nocompression
Source: "isgsg.dll"; DestDir: {tmp}; Flags: ignoreversion dontcopy nocompression

Source: "\Pakovano\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs sortfilesbyextension;

[Icons]
Name: "{userdesktop}\MyProg"; Filename: "{app}\MyProg.exe"; WorkingDir: "{app}"; Tasks: desktopicon;
Name: "{group}\MyProg"; Filename: "{app}\MyProg.exe";
Name: "{group}\{cm:UninstallProgram,MyProg}"; Filename: "{uninstallexe}"

[Run]
Description: {cm:LaunchProgram, MyProg}; Filename: {app}\MyProg.exe; WorkingDir: {app}; Flags: nowait postinstall skipifsilent
Filename: {src}\Soft\DirectX®\DXSETUP.exe; Parameters: /silent; Tasks: DirectX; StatusMsg: Обновление DirectX...
Filename: {src}\Soft\Vcredist\Vcredist_2010 (x64+x86).exe; Parameters: /q; Tasks: Redist; StatusMsg: Установка Microsoft Visual С++ 2010 Redistributable...

[UninstallDelete]
Type: filesandordirs; Name: "{app}";
Type: filesandordirs; Name: "{localappdata}\Spoon";
Type: filesandordirs; Name: "{localappdata}\VirtualStore";

[Сode]
type TGUID          = record Data1: Cardinal; Data2, Data3: Word; Data4: array [0..8] of Char; end;

const PlayTask    = 0;
        SupportTask = 1;
var GameuxGUID: TGUID;

function GenerateGUID(var GUID: TGUID): Cardinal; external 'GenerateGUID@files:GameuxInstallHelper.dll stdcall setuponly';
function AddToGameExplorer(Binary: String; Path: String; InstallType: Integer; var GUID: TGUID): Cardinal; external 'AddToGameExplorerA@files:GameuxInstallHelper.dll stdcall setuponly';
function CreateTask(InstallType: Integer; var GUID: TGUID; TaskType: Integer; TaskNumber: Integer; TaskName: String; Binary: String; Parameters: String): Cardinal; external 'CreateTaskA@files:GameuxInstallHelper.dll stdcall setuponly';
function RetrieveGUIDForApplication(Binary: String; var GUID: TGUID): Cardinal; external 'RetrieveGUIDForApplicationA@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';
function RemoveFromGameExplorer(var GUID: TGUID): Cardinal; external 'RemoveFromGameExplorer@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';
function RemoveTasks(var GUID: TGUID): Cardinal; external 'RemoveTasks@{localappdata}\GameuxInstallHelper.dll stdcall uninstallonly';

function IntToHex(Int: Cardinal; Digits: Integer): String; var i, Digit: Integer; ch: Byte;
begin
  result:='';
  for i:=0 to Digits-1 do
    begin
    digit:=Int mod 16;
    Int:=Int div 16;
    if digit<0 then
      digit:=digit+16;
      ch:=Ord('0')+digit;
        if digit>9 then
        ch:=ch+7;
        result:=chr(ch)+result;
    end;
end;

function GetGUID(GGUID: TGUID): String; var i: Integer;
begin
  result:='{'+IntToHex(GGUID.Data1, 8)+'-'+IntToHex(GGUID.Data2, 4)+'-'+IntToHex(GGUID.Data3, 4)+'-'+IntToHex(Ord(GGUID.Data4[0]), 2)+IntToHex(Ord(GGUID.Data4[1]), 2)+'-';
  for i:=2 to 7 do result:=result+IntToHex(Ord(GGUID.Data4[i]), 2); result:=result+'}';
end;

procedure GDFInstall(Binary, MainExe: String);
begin
  GenerateGUID(GameuxGUID);
  AddToGameExplorer(ExpandConstant(Binary), ExpandConstant('{app}'), 3, GameuxGUID);

  CreateTask(3, GameuxGUID, PlayTask, 0, 'Play', ExpandConstant(MainExe), '');
end;

procedure win7fix;
  var regGDF: Cardinal;
  var GUXPath: string;
begin
GUXPath := 'Software\Microsoft\Windows\CurrentVersion\GameUX\Games\' + GetGUID(GameuxGUID);
  if isWin64 then
  begin
    if RegQueryDWordValue(HKLM64, GUXPath, 'IsSigned', regGDF) then
      if regGDF=0 then
        if RegDeleteValue(HKLM64, GUXPath, 'IsSigned') then
          RegWriteDWordValue(HKLM64, GUXPath, 'IsSigned', 1);
  end
  else
  begin
    if RegQueryDWordValue(HKLM, GUXPath, 'IsSigned', regGDF) then
      if regGDF=0 then
        if RegDeleteValue(HKLM, GUXPath, 'IsSigned') then
          RegWriteDWordValue(HKLM, GUXPath, 'IsSigned', 1);
  end;
end;

type
  TPBProc = function (h:hWnd;Msg,wParam,lParam:Longint):Longint;
  
var
  TimeLeftLabel : TLabel;

  PBOldProc     : Longint;
  eTime, sTime  : DWORD;

var
  BASS_Initialized: Boolean;

const
   AW_BLEND = $00080000;
   AW_HIDE = $00010000;
const
    LOAD_LIBRARY_AS_DATAFILE = $2;

#define A = (Defined UNICODE) ? "W" : "A"

function AnimateWindow(hWnd: HWND; dwTime: DWORD; dwFlags: DWORD): Boolean;
external 'AnimateWindow@user32 stdcall';
function LoadLibraryEx(lpFileName: String; hFile: THandle; dwFlags: DWORD): THandle; external 'LoadLibraryEx{#A}@kernel32.dll stdcall';
function LoadString(hInstance: THandle; uID: SmallInt; var lpBuffer: Char; nBufferMax: Integer): Integer; external 'LoadString{#A}@user32.dll stdcall';
function SHGetNewLinkInfo(pszLinkTo, pszDir: String; var pszName: Char; var pfMustCopy: Longint; uFlags: UINT): BOOL; external 'SHGetNewLinkInfo{#A}@shell32.dll stdcall';
function PinToTaskbar(const szFilename: String; IsPin: Boolean): Boolean;

var
    hInst: THandle;
    buf: array [0..255] of Char;
    i, res: Integer;
    strLnk, strVerb: String;
    objShell, colVerbs: Variant;
begin
    Result := False;
    if (GetWindowsVersion < $06010000) or not FileExists(szFilename) then Exit; { below Windows 7 }

    { String resources }
    if IsPin then
    begin
        if SHGetNewLinkInfo(szFilename, ExpandConstant('{tmp}'), buf[0], res, 0) then
        begin
            while buf[Length(strLnk)] <> #0 do Insert(buf[Length(strLnk)], strLnk, Length(strLnk)+1);
            if FileExists(ExpandConstant('{userappdata}\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\') + ExtractFileName(strLnk)) then Exit;
        end;
        res := 5386;        { Pin to Tas&kbar }
    end else res := 5387;   { Unpin from Tas&kbar }

    { Load string resource }
    hInst := LoadLibraryEx(ExpandConstant('{sys}\shell32.dll'), 0, LOAD_LIBRARY_AS_DATAFILE);
    if hInst <> 0 then
    try
        for i := 0 to LoadString(hInst, res, buf[0], 255)-1 do Insert(buf[i], strVerb, i+1);
        try
            objShell := CreateOleObject('Shell.Application');
            colVerbs := objShell.Namespace(ExtractFileDir(szFilename)).ParseName(ExtractFileName(szFilename)).Verbs;
            for i := 1 to colVerbs.Count do if CompareText(colVerbs.Item[i].Name, strVerb) = 0 then
            begin
                colVerbs.Item[i].DoIt;
                Result := True;
                Break;
            end;
        except
            Exit;
        end;
    finally
        FreeDLL(hInst);
    end;
end;

type
    TTimerProc = procedure(HandleW, Msg, idEvent, TimeSys: LongWord);
var
  PercentsTimer: LongWord;
  PercentsLabel: TLabel;

function SetWindowLong(hWnd: HWND; nIndex: Integer; dwNewLong: Longint): Longint; external 'SetWindowLongA@user32.dll stdcall';
function CallBackProc(P:TPBProc;ParamCount:integer):LongWord; external 'wrapcallbackaddr@files:CallbackCtrl.dll stdcall';
function CallWindowProc(lpPrevWndFunc: Longint; hWnd: HWND; Msg: UINT; wParam, lParam: Longint): Longint; external 'CallWindowProcA@user32.dll stdcall';
function GetTickCount: DWORD; external 'GetTickCount@kernel32.dll stdcall';
function WrapTimerProc(callback: TTimerProc; Paramcount: Integer): longword; external 'wrapcallback@files:innocallback.dll stdcall';
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): longword; external 'SetTimer@user32';
function KillTimer(hWnd, nIDEvent: LongWord): LongWord; external 'KillTimer@user32 stdcall delayload';

function LongintToStringTime(t:Longint):string;
var
  h,m,s:integer;
begin
  h:=t div 3600;
  t:=t-h*3600;
  m:=t div 60;
  s:=t-m*60;
  Result:='';
  if h>0 then Result:=Result+IntToStr(h)+' ч. ';
  if (m>0) or (h>0) then Result:=Result+IntToStr(m)+' мин. ';
  if (m>0) or (h>0) or (s>0) then Result:=Result+IntToStr(s)+' сек.';
end;

function PBProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
var
  lt:Longint;
  dt,at,pr,i1,i2:Extended;
  p:string;
  tc:DWORD;
begin
  Result:=CallWindowProc(PBOldProc,h,Msg,wParam,lParam);
  if (Msg=$402) and (WizardForm.ProgressGauge.Position>WizardForm.ProgressGauge.Min) then begin
    i1:=WizardForm.ProgressGauge.Position-WizardForm.ProgressGauge.Min;
    i2:=WizardForm.ProgressGauge.Max-WizardForm.ProgressGauge.Min;

    tc:=GetTickCount;
    if (tc-eTime)>=1000 then begin //???????????? ????? ?????????? ?? ????? ????????? ?? ????, ??? ??? ? 1 ???????
      dt:=(tc-sTime)/1000;
      at:=i2*dt/i1;
      lt:=Round(at-dt)
      TimeLeftLabel.Caption:='Осталось - '+LongintToStringTime(lt);
      eTime:=tc;
    end;

    pr:=i1*100/i2;
    p:=' - ['+Format('%f',[pr])+'%]';
    StringChange(p,',','.');
  end;
end;

procedure AllCancel;
begin
  SetWindowLong(WizardForm.ProgressGauge.Handle,-4,PBOldProc);
  TimeLeftLabel.Free;
end;

function InitializeSetup:boolean;
begin
  if not FileExists(ExpandConstant('{tmp}\CallbackCtrl.dll')) then ExtractTemporaryFile('CallbackCtrl.dll');
  Result:=True;
end;

Function NumToStr(Float: Extended): String;
Begin
    Result:= Format('%.1n', [Float]); StringChange(Result, ',', '.');
    while ((Result[Length(Result)] = '0') or (Result[Length(Result)] = '.')) and (Pos('.', Result) > 0) do
        SetLength(Result, Length(Result)-1);
End;

Procedure PercentsProc(h, msg, idevent, dwTime: Longword);
Begin
  with WizardForm.ProgressGauge do
  begin
    PercentsLabel.Caption:= 'Выполнено ' + NumToStr((Position*100)/Max) + ' %';
  end;
End;

const
  Indent=25;

function GetWindowLong(hWnd: HWND; nIndex: Integer): Longint; external 'GetWindowLongA@user32.dll stdcall delayload';
function ssInitialize(hParent:HWND;ssTimeShow:integer;FadeOut:boolean;StretchMode:integer;BkgColor:DWORD):boolean; external 'ssInitialize@files:isgsg.dll stdcall delayload';
procedure ssDeInitialize; external 'ssDeInitialize@files:isgsg.dll stdcall delayload';
procedure ssSetBkgImage(FileName:PChar); external 'ssSetBkgImage@files:isgsg.dll stdcall delayload';
procedure ssAddImage(FileName:PChar); external 'ssAddImage@files:isgsg.dll stdcall delayload';
procedure ssStartShow; external 'ssStartShow@files:isgsg.dll stdcall delayload';
procedure ssStopShow; external 'ssStopShow@files:isgsg.dll stdcall delayload';
procedure ShowSplashScreen(p1:HWND;p2:string;p3,p4,p5,p6,p7:integer;p8:boolean;p9:Cardinal;p10:integer); external 'ShowSplashScreen@files:isgsg.dll stdcall delayload';
function GetSystemMetrics(nIndex:Integer):integer; external 'GetSystemMetrics@user32.dll stdcall delayload';

procedure RunListClickCheck(Sender: TObject);
var
  i:integer;
begin
  if WizardForm.RunList.Checked[WizardForm.RunList.ItemIndex] then begin
    for i:=0 to WizardForm.RunList.Items.Count-1 do
      WizardForm.RunList.Checked[i]:=False;
    WizardForm.RunList.Checked[WizardForm.RunList.ItemIndex]:=True;
  end;
end;

procedure InitializeWizard();
begin
  ExtractTemporaryFile('Bass.dll');
  ExtractTemporaryFile('botva2.dll');
  ExtractTemporaryFile('volmax.png');
  ExtractTemporaryFile('volmin.png');
  ExtractTemporaryFile('volpb.png');
  ExtractTemporaryFile('voldote.png');
  ExtractTemporaryFile('OST.mp3');
  ExtractTemporaryFile('MusicButton.png');
  ExtractTemporaryFile('miniature.png');
  ExtractTemporaryFile('miniature-2.png');
  
  ShowSplashScreen(WizardForm.Handle,ExpandConstant('{tmp}')+'\miniature.png',4000,4000,2000,0,255,False,$FFFFFF,10);
  ShowSplashScreen(WizardForm.Handle,ExpandConstant('{tmp}')+'\miniature-2.png',4000,4000,2000,0,255,False,$FFFFFF,10);
  ssInitialize(GetWindowLong(MainForm.Handle,-8),5,True,1,$FF000000);

  WizardForm.RunList.OnClickCheck:=@RunListClickCheck;
  BASS_Init('{tmp}\OST.mp3')
  BASS_CreateMediaPlayer(WizardForm, '{tmp}\volmax.png', '{tmp}\volmin.png', '{tmp}\volpb.png', '{tmp}\voldote.png', 20, 325)
  BASS_Initialized := True;
  ExtractTemporaryFile('MyProg™.png');
  ssSetBkgImage(ExpandConstant('{tmp}')+'\MyProg™.png');
  WizardForm.TypesCombo.ItemIndex:=0;
  
  PercentsLabel:= TLabel.Create(WizardForm);
  with PercentsLabel do
  begin
    Left:= WizardForm.ProgressGauge.Left;
    Top:= WizardForm.ProgressGauge.Top + WizardForm.ProgressGauge.Height + ScaleY(10);
    Width:= WizardForm.StatusLabel.Width;
    Height:= WizardForm.StatusLabel.Height;
    AutoSize:= False;
    Transparent := True;
    Parent:= WizardForm.InstallingPage;
   end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var Version: TWindowsVersion;
begin
  GetWindowsVersionEx(Version);
  if (CurStep = ssPostInstall) and Version.NTPlatform and (Version.Major > 5) then begin
    GDFInstall('{#GDFBinary}', '{#GDFExe}');
      win7fix;
  end;
begin
  case CurStep of
    ssInstall: begin
      TimeLeftLabel:=TLabel.Create(nil);
      with TimeLeftLabel do begin
        Parent:=WizardForm.InstallingPage;
        AutoSize:=True;
        SetBounds(WizardForm.ProgressGauge.Left + ScaleX(250),WizardForm.ProgressGauge.Top + ScaleY(30),ScaleY(80),ScaleY(21));
      end;
sTime:=GetTickCount;
      eTime:=sTime;

      PBOldProc:=SetWindowLong(WizardForm.ProgressGauge.Handle,-4,CallBackProc(@PBProc,4));
    end;
    ssPostInstall: AllCancel;
  end;
begin
  if CurStep=ssInstall then begin
PercentsTimer:= SetTimer(0, 0, 100, WrapTimerProc(@PercentsProc, 4));
    ExtractTemporaryFile('MyProg™.png');
    ssAddImage(ExpandConstant('{tmp}')+'\MyProg™.png');
  end;
  if CurStep=ssPostInstall then ssStopShow;
end;
end;
end;

procedure CurPageChanged(CurPageID: Integer);
begin
case CurPageID of
    wpFinished: end
  if IsTaskSelected('Pin') then
        PinToTaskbar(ExpandConstant('{app}\MyProg.exe'), True);
  if CurPageID=wpInstalling then begin;
    WizardForm.MainPanel.Visible:=False;
    WizardForm.Bevel1.Visible:=False;
    WizardForm.Width:=ScaleX(395);
    WizardForm.Height:=ScaleY(142);
    WizardForm.Left:=ScaleX(GetSystemMetrics(0)-WizardForm.Width-Indent);
    WizardForm.Top:=ScaleY(GetSystemMetrics(1)-WizardForm.Height-Indent);
    WizardForm.InnerNotebook.Left:=ScaleX(10);
    WizardForm.InnerNotebook.Top:=ScaleY(10);
    WizardForm.InnerNotebook.Width:=ScaleX(370);
    WizardForm.StatusLabel.Left:=ScaleX(0);
    WizardForm.StatusLabel.Top:=ScaleY(0);
    WizardForm.StatusLabel.Width:=WizardForm.InnerNotebook.Width;
    WizardForm.FileNameLabel.Left:=ScaleX(0);
    WizardForm.FileNameLabel.Top:=ScaleY(20);
    WizardForm.FileNameLabel.Width:=WizardForm.InnerNotebook.Width;
    WizardForm.ProgressGauge.Top:=ScaleY(40);
    WizardForm.ProgressGauge.Width:=WizardForm.InnerNotebook.Width;
    WizardForm.CancelButton.Left:=ScaleX(154);
    WizardForm.CancelButton.Top:=ScaleY(80);
  end;
  if (CurPageID=wpFinished) or (CurPageID=wpInfoAfter) then begin
    WizardForm.RunList.Checked[0]:=True;
    if WizardForm.Width<>502 then begin
      WizardForm.Visible:=False;
      WizardForm.Width:=ScaleX(502);
      WizardForm.Height:=ScaleY(392);
      WizardForm.Left:=(GetSystemMetrics(0)-WizardForm.Width) div 2;
      WizardForm.Top:=(GetSystemMetrics(1)-WizardForm.Height) div 2;
      WizardForm.MainPanel.Visible:=True;
      WizardForm.Bevel1.Visible:=True;
      WizardForm.InnerNotebook.Left:=ScaleX(40);
      WizardForm.InnerNotebook.Top:=ScaleY(72);
      WizardForm.InnerNotebook.Width:=ScaleX(417);
      WizardForm.Visible:=True;
    end;
  end;
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  Result := True;
  if CurPageID=wpFinished then
  begin
    if WizardForm.RunList.Checked[0] then
    Result := True;
  end;
end;

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
  if MsgBox(SetupMessage(msgExitSetupMessage), mbConfirmation, MB_OKCANCEL) = IDOK then
  begin
    Confirm := False;
    AnimateWindow(WizardForm.Handle, 2500, AW_BLEND or AW_HIDE);
    Cancel := True;
  end else
  Cancel := False;
end;

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
var
Binary: String;
GUID: TGUID;
begin
if CurUninstallStep=usUninstall then
begin
Binary:=ExpandConstant('{#GDFBinary}');
RetrieveGUIDForApplication(Binary, GUID);
RemoveFromGameExplorer(GUID);
RemoveTasks(GUID);
UnloadDll(ExpandConstant('{localappdata}\GameuxInstallHelper.dll'));
end;
  begin
    if (CurUninstallStep=usUninstall) then
      begin
    case CurUninstallStep of
      usUninstall: begin
        PinToTaskbar(ExpandConstant('{app}\MyProg.exe'), False);
      end;
   end;
end;
end;
end;

procedure DeinitializeSetup();
begin
if BASS_Initialized then
begin
KillTimer(0, PercentsTimer);
  ssDeInitialize;
  BASS_DeInit;
    gdipShutdown
end;
end;

Буду очень благодарен за помощь.

Последний раз редактировалось OldGamer, 10-08-2017 в 23:01.


Отправлено: 20:14, 10-08-2017 | #2023


Новый участник


Сообщения: 28
Благодарности: 9

Профиль | Отправить PM | Цитировать


Пытаюсь прикрутить к Inno чтение с консоли, причем нужна реализация через пайпы и чтобы текст построчно отображался в Memo.
Пытаюсь адаптировать следующий пример, 3-ий на странице (RunDosInMemo):
http://decoding.dax.ru/faq/vcl/console/console001.html


Вроде почти перевел, но осталась заморочка именно с чтением через ReadFile и вывод, соответственно в Memo, да, там должны передаваться символы и строки, у меня счас там цифры, содрал с одного примера, но подружить с текстом не удается.
Просьба продвинутых поправить пример, если это возможно.

Скрипт (для версии Unicode)

Код: Выделить весь код
[Setup] 
AppName=MyApp 
Appvername=MyApp                                        
DefaultDirname={pf}\MyApp 

[_Code] 
const 
  ReadBuffer = 2400;
  STARTF_USESTDHANDLES = $100;
  STARTF_USESHOWWINDOW = 1;
  NORMAL_PRIORITY_CLASS = $00000020;
  HEAP_ZERO_MEMORY = $0008;
  WAIT_TIMEOUT = $00000102;

type 
  TMyMsg = record hWnd: HWND; msg, wParam: Word; lParam: LongWord; Time: TFileTime; pt: TPoint; end;

type
  TSecurityAttributes = record
    nLength: DWord;
    lpSecurityDescriptor: longint;
    bInheritHandle: Boolean;
  end; 

TProcessInformation = record
  hProcess:DWORD;
  hThread:DWORD;
  dwProcessId:DWORD;
  dwThreadId:DWORD;
end;

TStartupInfo = record
  cb:DWORD;
  lpReserved:DWORD; // not PChar; - need NULL pointer
  lpDesktop:DWORD;  // not PChar; - need NULL pointer
  lpTitle:DWORD;  // not PChar; - need NULL pointer
  dwX:DWORD;
  dwY:DWORD;
  dwXSize:DWORD;
  dwYSize:DWORD;
  dwXCountChars:DWORD;
  dwYCountChars:DWORD;
  dwFillAttribute:DWORD;
  dwFlags:DWORD;
  wShowWindow:WORD;
  cbReserved2:WORD;
  lpReserved2:DWORD;
  hStdInput:DWORD;
  hStdOutput:DWORD;
  hStdError:DWORD;
end;

// ----------------------------------------------------------- //
function PeekMessage(var lpMsg: TMyMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; 
external 'PeekMessageW@user32.dll stdcall';

function TranslateMessage(const lpMsg: TMyMsg): BOOL; 
external 'TranslateMessage@user32.dll stdcall';

function DispatchMessage(const lpMsg: TMyMsg): Longint; 
external 'DispatchMessageW@user32.dll stdcall';
// ----------------------------------------------------------- //

function CloseHandle(hObject: THandle): BOOLEAN;
external 'CloseHandle@kernel32.dll stdcall';

function CreateProcess(lpApplicationName: String; lpCommandLine: string; lpProcAttrib,lpThreadAttrib: TSecurityAttributes; bInheritHandles: Boolean; dwCreationFlags: DWORD; lpEnvironment:DWORD; lpCurrentDirectory: String; var lpStartupInfo:TStartupInfo; var lpProcessInfo:TProcessInformation): Boolean;
external 'CreateProcessW@kernel32.dll stdcall';

function CreatePipe(out hReadPipe,hWritePipe: THandle; lpPipeAttributes: TSecurityAttributes; nSize: dword): BOOLEAN;
external 'CreatePipe@kernel32.dll stdcall';

function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; 
external 'WaitForSingleObject@kernel32.dll stdcall';
 
function ReadFile(hFile: THandle; lpBuffer: Longint; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: Longint): BOOL; 
external 'ReadFile@kernel32.dll stdcall';

function GetProcessHeap: THandle; 
external 'GetProcessHeap@kernel32.dll stdcall';

function HeapAlloc(hHeap: THandle; dwFlags, dwBytes: DWORD): Longint; 
external 'HeapAlloc@kernel32.dll stdcall';

function HeapSize(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): DWORD; 
external 'HeapSize@kernel32.dll stdcall';

function HeapFree(hHeap: THandle; dwFlags: DWORD; lpMem: Longint): BOOL; 
external 'HeapFree@kernel32.dll stdcall';

Function OemToChar(lpszSrc, lpszDst: AnsiString): longint; 
external 'OemToCharA@user32.dll stdcall';

procedure AppProcessMessage;
var
  Msg: TMyMsg;
begin
  while PeekMessage(Msg, 0, 0, 0, 1) do
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;

function OemToAnsiStr(strSource: AnsiString): AnsiString;
var
  nRet: longint;
begin
  SetLength(Result, Length(strSource));
  nRet:= OemToChar(strSource, Result);
end;

procedure InitializeWizard; 
var 
  MyMemo: TMemo; 

  Security: TSecurityAttributes;
  ReadPipe, WritePipe: THandle;
  Start: TStartUpInfo;
  ProcessInfo: TProcessInformation;
  Buffer: PAnsiChar;
  BytesRead: DWord;
  Apprunning: DWord;
  appName, commandLine,workingDirectory: string;

  hFile, hHeap: THandle;
  lpBuffer: Longint;
  dwBufferSize, dwRead: DWORD;
begin 
  WizardForm.InnerNoteBook.Hide; 
  WizardForm.OuterNotebook.Hide; 
  
  MyMemo:=TMemo.Create(WizardForm); 
  MyMemo.SetBounds(30, 30, 440, 260); 
  MyMemo.Parent:=WizardForm; 

  MyMemo.Text:='Hello!';
   
  {
  with Security do
  begin
    nlength := SizeOf(Security);
    binherithandle := true;
    lpsecuritydescriptor := 0;
  end;
  }

  Security.nlength := SizeOf( Security );
  Security.binherithandle := true;
  Security.lpSecurityDescriptor := 0;

  if Createpipe( ReadPipe, WritePipe, Security, 0 ) then
  begin
    hHeap := GetProcessHeap;
    lpBuffer := HeapAlloc(hHeap, HEAP_ZERO_MEMORY, ReadBuffer);
    dwBufferSize := HeapSize(hHeap, 0, lpBuffer);
    //Buffer := AllocMem( ReadBuffer+1 );
    //FillChar( Start, Sizeof( Start ), #0 );
    Start.cb := SizeOf( Start );
    Start.hStdOutput := WritePipe;
    Start.hStdInput := ReadPipe;
    Start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
    Start.wShowWindow := SW_HIDE;


    if CreateProcess('c:\windows\System32\PING.EXE', ' ' + 'ya.ru', Security, Security, True, NORMAL_PRIORITY_CLASS, 0, 'c:\windows\System32', Start, ProcessInfo) then
    begin
         
         repeat
            Apprunning := WaitForSingleObject( ProcessInfo.hProcess, 100 );

            ReadFile(ReadPipe, lpBuffer, dwBufferSize, dwRead, 0);
            //ReadFile( ReadPipe, lpBuffer[0], ReadBuffer, BytesRead, nil );
            //lpBuffer[BytesRead] := #0; 
            
            MyMemo.Text := MyMemo.text + OemToAnsiStr(lpBuffer);
            AppProcessMessage;
         until ( Apprunning <> WAIT_TIMEOUT );
         // until ( BytesRead < ReadBuffer );

    end;
    HeapFree(hHeap, 0, lpBuffer);
    CloseHandle( ProcessInfo.hProcess );
    CloseHandle( ProcessInfo.hThread );
    CloseHandle( ReadPipe );
    CloseHandle( WritePipe );
  end;

end;

Последний раз редактировалось usermode, 15-08-2017 в 14:29.


Отправлено: 14:23, 15-08-2017 | #2024


Аватара для TheLeon

Пользователь


Сообщения: 50
Благодарности: 0

Профиль | Отправить PM | Цитировать


Здравствуйте, у меня вопрос, а можно ли на финишной странице установщика сделать пункт, который удаляет файлы в определённых папках?(Решено)

Последний раз редактировалось TheLeon, 17-08-2017 в 20:04.


Отправлено: 15:14, 16-08-2017 | #2025


Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1264
Благодарности: 1024

Профиль | Отправить PM | Цитировать


Цитата usermode:
чтение с консоли, причем нужна реализация через пайпы и чтобы текст построчно отображался в Memo. »
usermode,
Скрытый текст

Код: Выделить весь код
[Setup]
AppName=test
AppVerName=test
CreateAppDir=false
DefaultDirName={tmp}
Uninstallable=false
DisableWelcomePage=no

[Languages]
Name: ru; MessagesFile: compiler:Languages\russian.isl

[Code]
#define A = (Defined UNICODE) ? "W" : "A"
const
  WM_QUIT = $0012;
  PM_REMOVE = $1;
  MSGF_SLEEPMSG = $5300;
  STARTF_USESTDHANDLES = $0100;
  STARTF_USESHOWWINDOW = $0001;
  QS_ALLINPUT = $04FF;
  WAIT_TIMEOUT  = $00000102;
  EM_LINESCROLL = $B6;

type
#ifndef IS_ENHANCED
  TMsg = record
    hwnd: HWND;
    message: LongWord;
    wParam: Longint;
    lParam: Longint;
    time: LongWord;
    pt: TPoint;
  end;
#endif

  TSecurityAttributes = record
    nLength: DWORD;
    lpSecurityDescriptor: Longint;
    bInheritHandle: BOOL;
  end;
    
  TStartupInfo = record
    cb: DWORD;
    lpReserved: Longint;
    lpDesktop: Longint;
    lpTitle: Longint;
    dwX: DWORD;
    dwY: DWORD;
    dwXSize: DWORD;
    dwYSize: DWORD;
    dwXCountChars: DWORD;
    dwYCountChars: DWORD;
    dwFillAttribute: DWORD;
    dwFlags: DWORD;
    wShowWindow: Word;
    cbReserved2: Word;
    lpReserved2: Longint;
    hStdInput: THandle;
    hStdOutput: THandle;
    hStdError: THandle;
  end;
    
  TProcessInformation = record
    hProcess: THandle;
    hThread: THandle;
    dwProcessId: DWORD;
    dwThreadId: DWORD;
  end;

// Message Functions
function PeekMessage(var lpMsg: TMsg; hWnd: HWND; wMsgFilterMin, wMsgFilterMax, wRemoveMsg: UINT): BOOL; external 'PeekMessage{#A}@user32.dll stdcall';
function TranslateMessage(const lpMsg: TMsg): BOOL; external 'TranslateMessage@user32.dll stdcall';
function DispatchMessage(const lpmsg: TMsg): Longint; external 'DispatchMessage{#A}@user32.dll stdcall';
procedure PostQuitMessage(nExitCode: Integer); external 'PostQuitMessage@user32.dll stdcall';

// Hook Functions
function CallMsgFilter(lpMsg: TMsg; nCode: Integer): BOOL; external 'CallMsgFilter{#A}@user32.dll stdcall';

// Synchronization Functions
function WaitForSingleObject(hHandle: THandle; dwMilliseconds: DWORD): DWORD; external 'WaitForSingleObject@kernel32.dll stdcall';

// Handle and Object Functions
function CloseHandle(hObject: THandle): BOOL; external 'CloseHandle@kernel32.dll stdcall';

// Process and Thread Functions
function CreateProcess(lpApplicationName, lpCommandLine: string; lpProcessAttributes, lpThreadAttributes: TSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Longint; lpCurrentDirectory: string; lpStartupInfo: TStartupInfo; out lpProcessInformation: TProcessInformation): BOOL; external 'CreateProcess{#A}@kernel32.dll stdcall';

// Pipe Functions
function CreatePipe(out hReadPipe, hWritePipe: THandle; lpPipeAttributes: TSecurityAttributes; nSize: DWORD): BOOL; external 'CreatePipe@kernel32.dll stdcall';
function PeekNamedPipe(hNamedPipe: THandle; lpBuffer: AnsiString; nBufferSize: DWORD; out lpBytesRead: DWORD; lpTotalBytesAvail, lpBytesLeftThisMessage: DWORD): BOOL; external 'PeekNamedPipe@kernel32.dll stdcall';

// File Management Functions
function ReadFile(hFile: THandle; lpBuffer: AnsiString; nNumberOfBytesToRead: DWORD; var lpNumberOfBytesRead: DWORD; lpOverlapped: Longint): BOOL; external 'ReadFile@kernel32.dll stdcall';

var
  OutputMemo: TMemo;
  RunButton: TButton;

//////////////////////////////////
function ProcessMessages: Boolean;
var
  Msg: TMsg;
begin
  Result := True;
  while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
  begin
    if (Msg.Message = WM_QUIT) then
    begin
      PostQuitMessage(Msg.wParam);
      Result := False;
      Exit;
    end;
    if not CallMsgFilter(Msg, MSGF_SLEEPMSG) then
    begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;
  end;
end;

/////////////////////////////// ///////////////////////////////////
procedure CaptureConsoleOutput(const ACommand, AParameters: string;
  const AOEMConvert: Boolean; AMemo: TMemo);
var
  SecurityAttributes: TSecurityAttributes;
  StartupInfo: TStartupInfo;
  ProcessInformation: TProcessInformation;
  ReadHandle, WriteHandle: THandle;
  BufSize, ResultCode, BytesRead: DWORD;
  Buffer: AnsiString;
begin
  SecurityAttributes.nLength := SizeOf(SecurityAttributes);
  SecurityAttributes.bInheritHandle := True;
  if CreatePipe(ReadHandle, WriteHandle, SecurityAttributes, 0) then
  try
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.hStdInput := ReadHandle;
    StartupInfo.hStdOutput := WriteHandle;
    StartupInfo.hStdError := WriteHandle;
    StartupInfo.dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
    StartupInfo.wShowWindow := SW_HIDE;
    if CreateProcess('', Format('%s %s', [ACommand, AParameters]), SecurityAttributes, SecurityAttributes, True, 0, 0, '', StartupInfo, ProcessInformation) then
    try
      CloseHandle(WriteHandle);
      BufSize := 1024;  // 1KB
      Buffer := StringOfChar(#0, BufSize);
      repeat
        ResultCode := WaitForSingleObject(ProcessInformation.hProcess, 0);
        PeekNamedPipe(ReadHandle, Buffer, BufSize, BytesRead, 0, 0);
        while ProcessMessages and (BytesRead > 0) do
        begin
        #ifdef IS_ENHANCED
          AMemo.Lines.BeginUpdate;
        #endif
          ReadFile(ReadHandle, Buffer, BytesRead, BytesRead, 0);
          if AOEMConvert then
            OemToCharBuff(Buffer);
          AMemo.Text := AMemo.Text + Copy(Buffer, 1, BytesRead);
          SendMessage(AMemo.Handle, EM_LINESCROLL, 0, AMemo.Lines.Count);
        #ifdef IS_ENHANCED  
          AMemo.Lines.EndUpdate;
        #endif
        end;
      until not ProcessMessages or (ResultCode <> WAIT_TIMEOUT);
    finally
      CloseHandle(ProcessInformation.hProcess);
      CloseHandle(ProcessInformation.hThread);
    end;
  finally
    CloseHandle(ReadHandle);
  end;
end;

////////////////////////////////////////////
procedure RunButtonOnClick(Sender: TObject);
begin
  CaptureConsoleOutput('cmd.exe', '/c ping ya.ru', True, OutputMemo);
end;

///////////////////////////
procedure InitializeWizard;
begin
  WizardForm.OuterNotebook.Hide;

  OutputMemo := TMemo.Create(WizardForm);
  with OutputMemo do
  begin
    Parent := WizardForm;
    SetBounds(WizardForm.OuterNotebook.Left, WizardForm.OuterNotebook.Top, WizardForm.OuterNotebook.Width, WizardForm.OuterNotebook.Height);
    ScrollBars := ssVertical;
    ReadOnly := True;
  #ifdef IS_ENHANCED
    DoubleBuffered := True;
  #endif
  end;

  RunButton := TButton.Create(WizardForm);
  with RunButton do
  begin
    Parent := WizardForm;
    SetBounds(WizardForm.OuterNotebook.Left, WizardForm.NextButton.Top, WizardForm.NextButton.Width, WizardForm.NextButton.Height);
    Caption := 'Run';
    OnClick := @RunButtonOnClick;
  end;
end;

//////////////////////////////////////////////////////
function NextButtonClick(CurPageID: Integer): Boolean;
begin
  Result := False;
end;

Последний раз редактировалось El Sanchez, 16-08-2017 в 21:39. Причина: legacy code

Это сообщение посчитали полезным следующие участники:

Отправлено: 15:23, 16-08-2017 | #2026


Новый участник


Сообщения: 28
Благодарности: 9

Профиль | Отправить PM | Цитировать


El Sanchez, а что за компилятор используется? Пробовал расширенную версию от ResTools - не понимает многих параметров. (В Inno Ultra, все хорошо.)
Привык к стандартной официальной версии, буду пробовать адаптировать, за пример огромное спасибо!

добавлено
подскажите, какой изврат можно использовать в стандартной версии Unicode вместо:

Buffer := CastIntegerToString(BufPtr);

чтобы перевести содержимое в ANSI.

Адаптировал пример под официальную ANSI версию компилятора - все нормально, отображает символы корректно, но UNICODE не содержит CastIntegerToAnsiString.
Что нужно учесть, чтобы написать свою функцию CastIntegerToAnsiString, либо как решить задачу другим способом?
======================================================================================
Цитата El Sanchez:
usermode, адаптировал под официальную версию. »
респект! рука профессионала!

Последний раз редактировалось usermode, 16-08-2017 в 22:05.


Отправлено: 16:21, 16-08-2017 | #2027


Аватара для nik1967

Старожил


Сообщения: 440
Благодарности: 251

Профиль | Сайт | Отправить PM | Цитировать


El Sanchez, а вывод с консоли заголовка окна возможен? Скажем, проценты выполнения процесса? Было бы здорово.

-------
Если сообщение оказалось полезным для Вас, то помимо спасибо, можно нажать на "Полезное сообщение".


Последний раз редактировалось nik1967, 16-08-2017 в 20:48.


Отправлено: 16:57, 16-08-2017 | #2028


Аватара для El Sanchez

Ветеран


Contributor


Сообщения: 1264
Благодарности: 1024

Профиль | Отправить PM | Цитировать


Цитата usermode:
Что нужно учесть, чтобы написать свою функцию CastIntegerToAnsiString, либо как решить задачу другим способом? »
usermode, адаптировал под официальную версию.
Цитата nik1967:
а вывод с консоли заголовка окна возможен? Скажем, проценты выполнения процесса? »
nik1967, а фиг его знает. После CreateProcess известны PID и дескриптор процесса, по одному из них искать дескриптор окна, далее текст заголовка.
Это сообщение посчитали полезным следующие участники:

Отправлено: 21:44, 16-08-2017 | #2029


Аватара для nik1967

Старожил


Сообщения: 440
Благодарности: 251

Профиль | Сайт | Отправить PM | Цитировать


El Sanchez, спасибо за направление, но это не мой уровень, увы.

-------
Если сообщение оказалось полезным для Вас, то помимо спасибо, можно нажать на "Полезное сообщение".


Последний раз редактировалось nik1967, 17-08-2017 в 09:11.


Отправлено: 22:42, 16-08-2017 | #2030



Компьютерный форум OSzone.net » Автоматическая установка Windows » Автоматическая установка приложений » Скрипты Inno Setup. Помощь и советы [часть 8]

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Скрипты Inno Setup. Помощь и советы [часть 7] El Sanchez Автоматическая установка приложений 2499 02-02-2015 08:59
Скрипты Inno Setup. Помощь и советы [часть 6] El Sanchez Автоматическая установка приложений 2494 10-03-2014 11:51
Скрипты Inno Setup. Помощь и советы [часть 5] El Sanchez Автоматическая установка приложений 1999 28-03-2013 19:09
Скрипты Inno Setup. Помощь и советы [часть 4] El Sanchez Автоматическая установка приложений 2099 22-05-2012 23:16
Скрипты Inno Setup. Помощь и советы [часть 3] Serega Автоматическая установка приложений 3755 26-10-2011 17:58




 
Переход