Jump to content
Korean Random
EvilAlex

Создание инсталляторов для модпаков на базе Inno Setup

Recommended Posts

Котярко. Не твой код? Не победил воспроизведение по компонентам?

[Setup]
RawDataResource=SndA:bugreporter_succeeded.wav |SndB:WindowsLogoffSound.wav

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

type
    HINST = THandle;
    HMODULE = HINST;
    Pointer = Longint;
    HRSRC = THandle;
    HGLOBAL = THandle;

const
    SND_ASYNC           = $0001;
    SND_NODEFAULT       = $0002;
    SND_MEMORY          = $0004;
    RT_RCDATA           = 10;


function sndPlaySound(lpszSoundName: Pointer; uFlags: UINT): BOOL; external 'sndPlaySound{#A}@Winmm.dll stdcall';
function LoadResource(hModule: HINST; hResInfo: HRSRC): HGLOBAL; external '[email protected] stdcall';
function FindResource(hModule: HMODULE; lpName: String; lpType: Longint): HRSRC; external 'FindResource{#A}@kernel32.dll stdcall';
function LockResource(hResData: HGLOBAL): Pointer; external '[email protected] stdcall';

var
 pSoundMemory_A, pSoundMemory_B: Pointer;
    
function GetResourceSoundAddr(const ResourceName: String): Pointer;
var
    hResourceSound: HRSRC;
begin
    hResourceSound := FindResource(HInstance, ResourceName, RT_RCDATA);
    Result := LockResource(LoadResource(HInstance, hResourceSound));
end;

procedure ComponentsOnClickCheck(Sender: TObject);
begin
    if IsComponentSelected('KMP\AB') then
    begin
    sndPlaySound(pSoundMemory_B, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
    end;
    if IsComponentSelected('KMP\ZK') then
    begin
    sndPlaySound(pSoundMemory_A, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
    end;
end;

procedure InitializeWizard4();
begin
    pSoundMemory_A := GetResourceSoundAddr('_IS_SNDA');
    pSoundMemory_B := GetResourceSoundAddr('_IS_SNDB');
    
    WizardForm.ComponentsList.OnClickCheck := @ComponentsOnClickCheck;
end;


Edited by justdj

Share this post


Link to post

Short link
Share on other sites
[spoiler]

Котярко. Не твой код? Не победил воспроизведение по компонентам?

[Setup]
RawDataResource=SndA:bugreporter_succeeded.wav |SndB:WindowsLogoffSound.wav

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

type
    HINST = THandle;
    HMODULE = HINST;
    Pointer = Longint;
    HRSRC = THandle;
    HGLOBAL = THandle;

const
    SND_ASYNC           = $0001;
    SND_NODEFAULT       = $0002;
    SND_MEMORY          = $0004;
    RT_RCDATA           = 10;


function sndPlaySound(lpszSoundName: Pointer; uFlags: UINT): BOOL; external 'sndPlaySound{#A}@Winmm.dll stdcall';
function LoadResource(hModule: HINST; hResInfo: HRSRC): HGLOBAL; external '[email protected] stdcall';
function FindResource(hModule: HMODULE; lpName: String; lpType: Longint): HRSRC; external 'FindResource{#A}@kernel32.dll stdcall';
function LockResource(hResData: HGLOBAL): Pointer; external '[email protected] stdcall';

var
 pSoundMemory_A, pSoundMemory_B: Pointer;
    
function GetResourceSoundAddr(const ResourceName: String): Pointer;
var
    hResourceSound: HRSRC;
begin
    hResourceSound := FindResource(HInstance, ResourceName, RT_RCDATA);
    Result := LockResource(LoadResource(HInstance, hResourceSound));
end;

procedure ComponentsOnClickCheck(Sender: TObject);
begin
    if IsComponentSelected('KMP\AB') then
    begin
    sndPlaySound(pSoundMemory_B, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
    end;
    if IsComponentSelected('KMP\ZK') then
    begin
    sndPlaySound(pSoundMemory_A, SND_MEMORY or SND_NODEFAULT or SND_ASYNC);
    end;
end;

procedure InitializeWizard4();
begin
    pSoundMemory_A := GetResourceSoundAddr('_IS_SNDA');
    pSoundMemory_B := GetResourceSoundAddr('_IS_SNDB');
    
    WizardForm.ComponentsList.OnClickCheck := @ComponentsOnClickCheck;
end;

более удобный 

[Setup]
AppName=My Program
AppVerName=My Program 1.5
DefaultDirName={pf}\My Program
DefaultGroupName=My Program
ComponentsListTVStyle=true
[Files]
Source: sounds\*; flags: dontcopy;
[Languages]
Name: russian; MessagesFile: compiler:Languages\Russian.isl
[Components]
Name: sound; Description: Звук выстрела; Types: full;
Name: sound\snd1; Description: "Тихий"; Flags: exclusive;
Name: sound\snd2; Description: "Громкий"; Flags: exclusive;
[Code]
const
  LB_ITEMFROMPOINT  = $01A9;
type
  TComponentSound = record
    SoundName: String;
    Index: Integer;
  end;
  TSize = record
    cx: Longint;
    cy: Longint;
  end;
  ABC = record
    abcA: Integer;
    abcB: UINT;
    abcC: Integer;
  end;
  HDC = Longword;
  HGDIOBJ = Longword;
var
  iSound: array of TComponentSound;
  sndCompOldProc: TNotifyEvent;
function GetCursorPos(var lpPoint: TPoint): BOOL; external '[email protected] stdcall';
function MapWindowPoints(hWndFrom, hWndTo: HWND; var lpPoints: TPoint; cPoints: UINT): Integer; external '[email protected] stdcall';
function GetTextExtentPoint32(DC: HDC; lpString: String; Len: Integer; var lpSize: TSize): Boolean; external '[email protected] stdcall';
function GetClientDC(hWnd: HWND): HDC; external '[email protected] stdcall';
function ReleaseClientDC(hWnd: HWND; hDC: HDC): Integer; external '[email protected] stdcall';
function SelectObject(DC: HDC; p2: HGDIOBJ): HGDIOBJ; external '[email protected] stdcall';
function GetCharABCWidths(DC: HDC; uFirstChar, uLastChar: UINT; var lpAbc: ABC): Boolean; external '[email protected] stdcall';
function sndPlaySound(lpszSoundName: String; fuSound: UINT): BOOL; external '[email protected] stdcall';
function GetTextWidth(aFont: TFont; Text: String): Integer;
var
  DC: HDC;
  aSize: TSize;
  OldObj: Longword;
  abc1, abc2: ABC;
begin
  if Text='' then Exit;
  DC:= GetClientDC(0);
  try
    OldObj:= SelectObject(DC, aFont.Handle);
    GetTextExtentPoint32(DC, Text, Length(Text), aSize);
    Result:= aSize.cx;
    if (Length(Text)<>1)and(fsItalic in aFont.Style) then begin
      GetCharABCWidths(DC, Ord(Text[1]), Ord(Text[1]), abc1);
      GetCharABCWidths(DC, Ord(Text[Length(text)]), Ord(Text[Length(text)]), abc2);
      if abc1.abcA<0 then Result:= Result-abc1.abcA;
      if abc2.abcC<0 then Result:= Result-abc2.abcC
    end;
  finally
    SelectObject(DC, OldObj);
    ReleaseClientDC(0, DC);
  end;
end;
procedure PlaySound(Sender: TObject);
var
  x, o, n, lParam, i, f, ids, w1, w2, x1, x2: Integer;
  p: TPoint;
  sp, s: String;
  fnt: TFont;
begin
  GetCursorPos(p);
  MapWindowPoints(0, WizardForm.ComponentsList.Handle, p, 1);
  lParam:= p.x or (p.y shl 16);
  i:= SendMessage(WizardForm.ComponentsList.Handle, LB_ITEMFROMPOINT, 0, lParam);
  if ((i shr 16) = 1) or ((i and $FFFF) < 0) then Exit;
  ids:= i and $FFFF;
  o:= WizardForm.ComponentsList.Offset;
  n:= WizardForm.ComponentsList.ItemLevel[ids];
  if (WizardForm.ComponentsList.TreeViewStyle) then
    x:= ScaleX((1 + o) + ((13 + o * 2)*(n + 1)) + (14 + o * 2))
  else
    x:= ScaleX((13 + o * 2)*(n + 1));
   
  sp:= ' '+#$266B;
  f:= -1;
  for i:= 0 to GetArrayLength(iSound)-1 do begin
    if (ids = iSound[i].Index) then begin
      f:= i;
      Break;
    end;
  end;
  if (f < 0) then Exit;
  s:= WizardForm.ComponentsList.ItemCaption[ids];
  if (Pos(#$266B, s) <= 0) then Exit;
  fnt:= WizardForm.ComponentsList.Font;
  fnt.Style:= WizardForm.ComponentsList.ItemFontStyle[i];
 
  w1:= GetTextWidth(fnt, Trim(s));
  w2:= GetTextWidth(fnt, sp);
 
  x2:= w1 + x;
  x1:= x2 - w2;
  if (p.x >= (x1 - 1)) and (p.x <= (x2 + 1)) then begin
    if FileExists(iSound[f].SoundName) then
      sndPlaySound(iSound[f].SoundName, 0);
  end;
 
  if (sndCompOldProc <> nil) then
    sndCompOldProc(Sender);
end;
procedure AddItemSound(AIndex: Integer; AFilename: String);
var
  i: Integer;
begin
  i:= GetArrayLength(iSound);
  SetArrayLength(iSound, i+1);
  iSound[i].Index:= AIndex-1;
  iSound[i].SoundName:= ExpandConstant(AFilename);
  WizardForm.ComponentsList.ItemCaption[AIndex-1]:= WizardForm.ComponentsList.ItemCaption[AIndex-1] + ' '+#$266B;
end;
procedure InitializeWizard();
begin
  WizardForm.TypesCombo.Visible:=False;
  WizardForm.ComponentsList.Height := ScaleY(181) - WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Top := WizardForm.TypesCombo.Top;
  WizardForm.ComponentsList.Width := ScaleX(417);
  sndCompOldProc:= WizardForm.ComponentsList.OnClick;
  WizardForm.ComponentsList.OnClick:= @PlaySound;
  ExtractTemporaryFile('sound1.wav');
  ExtractTemporaryFile('sound2.wav');
  AddItemSound(2, '{tmp}\sound1.wav');
  AddItemSound(3, '{tmp}\sound2.wav');
end;

Edited by ♫♫♫Dark_Knight_MiX♫♫♫
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

 

 

Котярко. Не твой код? Не победил воспроизведение по компонентам?
Не мой.

Вот подходящий вариант.
 

з.ы. опоздал, он же комментарием выше.

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Благодарю. Буду разбирать. Не подскажете чем будет отличатся реализация "убивалки процессов" через dll и через системный тасккилл? Что "лучше"? Или одинаково? Мб проблем будет меньше где-то.

Share this post


Link to post

Short link
Share on other sites

Не подскажете чем будет отличатся реализация "убивалки процессов" через dll и через системный тасккилл? Что "лучше"? Или одинаково? Мб проблем будет меньше где-то.

Ну, кмк, либа удобнее, по применению.

А по исполнению особой разницы нет.

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Помогите разобраться....

Имеется строка кода

 

Source: "{app}\res\audio\*"; DestDir: "{app}\res_mods\0.9.6\audio\"; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\O;

 

но в данном варианте это у меня не работает. Зато прекрасно работает вариант

 

Source: C:\Games\World_of_Tanks\res\audio\*; DestDir: {app}\res_mods\0.9.6\audio; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\O;

 

Но что если игра расположена по другому адресу?...

Share this post


Link to post

Short link
Share on other sites

Помогите разобраться....

Имеется строка кода

 

Source: "{app}\res\audio\*"; DestDir: "{app}\res_mods\0.9.6\audio\"; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\O;

 

но в данном варианте это у меня не работает. Зато прекрасно работает вариант

 

Source: C:\Games\World_of_Tanks\res\audio\*; DestDir: {app}\res_mods\0.9.6\audio; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\O;

 

Но что если игра расположена по другому адресу?...

#define Patch               "0.9.6"
Source: "{app}\res\audio\*"; DestDir: "{app}\res_mods\{#Patch}\audio\"; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\18; 
Source: "моды\звуки\звонок крита\*"; DestDir: "{app}\res_mods\{#Patch}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: KMP\18\1;

если у тебя ищет через реестр то не важно по какому пути 

Edited by ♫♫♫Dark_Knight_MiX♫♫♫

Share this post


Link to post

Short link
Share on other sites

{app} - константа выбранной папки приложения пользователем (или же угаданная по реестру), в общем конечная папка, указанная на этапе выбора директории. Это может быть как папка с игрой, так и рабочий стол. Вы же не знаете, что такое справка.

Чтобы не было фигни лучше сделать проверку, правильный ли указан путь до папки с игрой.


 

 

Помогите разобраться.
По данному примеру должно работать (если, конечно, за {app} принимается корневая папка игры). Edited by Kotyarko_O

Share this post


Link to post

Short link
Share on other sites
#define Patch               "0.9.6"
Source: "{app}\res\audio\*"; DestDir: "{app}\res_mods\{#Patch}\audio\"; Flags: external recursesubdirs skipifsourcedoesntexist; Components: KMP\18; 
Source: "моды\звуки\звонок крита\*"; DestDir: "{app}\res_mods\{#Patch}"; Flags: ignoreversion recursesubdirs createallsubdirs; Components: KMP\18\1;

если у тебя ищет через реестр то не важно по какому пути 

 

А если не через реестр?

Share this post


Link to post

Short link
Share on other sites

а как у вас?

Да понятия не имею если честно. Я весь код кусками собирал, методом научного тыка.

Share this post


Link to post

Short link
Share on other sites

Да понятия не имею если честно. Я весь код кусками собирал, методом научного тыка.

[Setup]
DefaultDirName={code:WotDirNameRU}

[Code]
function WotDirNameRU(S:String): String; // ключь для основного клиента  {1EAC1D02-C6AC-4FA6-9A44-96258C37C812RU}_is1
var                                 
  InsPath: String;
  er: boolean;
  myFile:String;
begin
  Result:=ExpandConstant('C:\Games\World_of_Tanks\'); //если ключа нет то будем ставить сюда
  er := RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812RU}_is1', 'InstallLocation', InsPath);
  if er and (InsPath<>'') then //если ключ существует и там что-то записано
  begin
    Result := InsPath;
  end;
end;
//""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
function WotDirNameCT(S:String): String; // ключь для тестового клиента {1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1
var                                
  InsPath: String;
  er: boolean;
  myFile:String;
begin
  Result:=ExpandConstant('C:\Games\World_of_Tanks_CT\'); //если ключа нет то будем ставить сюда
  er := RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1', 'InstallLocation', InsPath);
  if er and (InsPath<>'') then //если ключ существует и там что-то записано
  begin
    Result := InsPath;
  end;
end;

Share this post


Link to post

Short link
Share on other sites

В том и вся беда ваша - ничего не знаю, но делаю.

Ну да! В варианте - ЗНАЮ ВСЁ, посетителей на этом форуме было б  море... 

[Setup]
DefaultDirName={code:WotDirNameRU}

[Code]
function WotDirNameRU(S:String): String; // ключь для основного клиента  {1EAC1D02-C6AC-4FA6-9A44-96258C37C812RU}_is1
var                                 
  InsPath: String;
  er: boolean;
  myFile:String;
begin
  Result:=ExpandConstant('C:\Games\World_of_Tanks\'); //если ключа нет то будем ставить сюда
  er := RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812RU}_is1', 'InstallLocation', InsPath);
  if er and (InsPath<>'') then //если ключ существует и там что-то записано
  begin
    Result := InsPath;
  end;
end;
//""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""//
function WotDirNameCT(S:String): String; // ключь для тестового клиента {1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1
var                                
  InsPath: String;
  er: boolean;
  myFile:String;
begin
  Result:=ExpandConstant('C:\Games\World_of_Tanks_CT\'); //если ключа нет то будем ставить сюда
  er := RegQueryStringValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT}_is1', 'InstallLocation', InsPath);
  if er and (InsPath<>'') then //если ключ существует и там что-то записано
  begin
    Result := InsPath;
  end;
end;

{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT} Это ведь не случайный набор символов. Откуда это берётся?

Share this post


Link to post

Short link
Share on other sites

 

 

{1EAC1D02-C6AC-4FA6-9A44-96258C37C812CT} Это ведь не случайный набор символов. Откуда это берётся?

 

Это GUID, вычисляется исходя из кучи всяких параметров на компе и текущей даты и времени. GUID случайны и не повторяются ввиду огромного кол-во возможных комбинаций символов. Их часто используют как идентификационные номера или ключи.

Share this post


Link to post

Short link
Share on other sites

Это GUID, вычисляется исходя из кучи всяких параметров на компе и текущей даты и времени. GUID случайны и не повторяются ввиду огромного кол-во возможных комбинаций символов. Их часто используют как идентификационные номера или ключи.

А можно просто вписать что-то своё)

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Это GUID, вычисляется исходя из кучи всяких параметров на компе и текущей даты и времени. GUID случайны и не повторяются ввиду огромного кол-во возможных комбинаций символов. Их часто используют как идентификационные номера или ключи.

Он как-нибудь связан с этим?

#define GameID            "{5F05CE9B-7768-490E-9A71-C6R92B4EX123}"  ;Ид инстолятора

Share this post


Link to post

Short link
Share on other sites

чем можно распаковать созданный данной штукой инсталятор? 

InnoExtractor ругается что я создал его в модифицированной программе и отказывается рапаковывать

Edited by psix89

Share this post


Link to post

Short link
Share on other sites

чем можно распаковать созданный данной штукой инсталятор? 

InnoExtractor ругается что я создал его в модифицированной программе и отказывается рапаковывать

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

Если инсталл сделан расширенной версией компилятора, китайской, то никак.

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

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

Если инсталл сделан расширенной версией компилятора, китайской, то никак.

я так понимаю у нас китайский вариант в теме выложен?

Share this post


Link to post

Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...