Wątek przeniesiony 2023-07-01 19:38 z Delphi i Pascal przez Ktos.

Inno Setup - pytanie do wyjadaczy

0

Witam, piszę instalator w Inno Steup i mam pytanie.

Daje dyrektywe defined (5 nazw pliku exe + ikonki)

// EXE 1
#if ReadIni(SourcePath	+ "\Setup.ini", "Information", "AppEXE1", "") != ""
#define AppEXE1 ReadIni(SourcePath	+ "\Setup.ini", "Information", "AppEXE1", "")
// EXE 1 IKONKA
#define AppIconFile1 ReadIni(SourcePath + "\Setup.ini", "Information", "AppIconFile1", "")
#endif

// EXE 2
#if ReadIni(SourcePath	+ "\Setup.ini", "Information", "AppEXE2", "") != ""
#define AppEXE1 ReadIni(SourcePath	+ "\Setup.ini", "Information", "AppEXE2", "")
// EXE 2 IKONKA
#define AppIconFile2 ReadIni(SourcePath + "\Setup.ini", "Information", "AppIconFile2", "")
#endif

i tak 5 razy

Chce po instalacji stworzyc na pulpicie ikonki dla tych plikow (exe, najlepiej w pętli)

procedure CreateIcons();
var
i: Integer;
begin
{

  function CreateShellLink (
     const Filename,
     Description,
     ShortcutTo,
     Parameters,
     WorkingDir,
     IconFilename: String;
     const IconIndex,
     ShowCmd: Integer
 ): String;

}


for i := 1 to 5 do begin
  #ifdef AppEXE + str(i)
  // Wyskakuje blad...
  #endif
end;

jak zmodyfikowac kod zeby było poprawnie?, jezeli to w ogole mozliwe.

Wiem ze moge zrobic tak...

#ifdef AppEXE1
if IsTaskSelected('DesktopIcon1') then
   CreateShellLink(
   ExpandConstant('{commondesktop}\{#AppIconName1}.lnk'),
   '',
   ExpandConstant('{app}\{#AppExe1}'),
   '',
   ExpandConstant(ExtractFilePath('{app}\{#AppExe1}')),
   ExpandConstant('{app}\{#AppFile1}'),
   0,
   SW_SHOWNORMAL
   );
#endif

I tak 5 razy, a ja chce to dac w pętle.

reasumujac #ifdef AppEXE + str(i) nie kompiluje

Jak to ugryś poprawnie, macie jakies pomysly?

Pozdrawiam.

1

InnoSetup używałem lata świetlne temu, ale tak na chłopski rozum, biorąc zachowania z innych języków programowania (a i chat gpt podpowiada podobnie) to #define definiuje wartości na etapie "pre-processingu" Twojego kodu. Tj. najpierw wszędzie, gdzie używasz zdefiniowanych wartości na surowo są one podmieniane w kodzie, a dopiero potem wykonywane, tj.

#define AppIconName1 cośtam
CreateShellLink(
   ExpandConstant('{commondesktop}\{#AppIconName1}.lnk'),
   ...
)

w efekcie powoduje pierwsze preprocessing i finalnie uruchomienie takiego kodu:

CreateShellLink(
   ExpandConstant('{commondesktop}\{cośtam}.lnk'),
   ...
)

Nie ma już żadnego define, ifdef też jest usunięte na etapie pre-processingu.

Czyli AppEXE + str(i) nie ma racji bytu, ponieważ #ifdef powinno zostać wyeliminowane przed właściwym uruchomieniem, a ty tu mieszasz statyczne definicje ze zmienną, która ma wartość dopiero podczas uruchomienia kodu.

Używaj zmiennych var, nie definicji, jakiś array by się przydał i wszystko powinno być ok.

(A ChatGPT podpowiada mi tak paskudny workaround, że nawet nie polecam zaglądać tak szczerze :D)

Wybacz, jeżeli powiedziałem coś nie do końca prawdziwego - nie znam InnoSetup.

0

@dzek69 Mam duzo lini kodu, tylo utkwilem :)
image

    // testuje pętle
    for i := 1 to 5 do begin
      #if AppEXE1 != NULL
        MsgBox('{#AppEXE1} ', mbInformation, MB_OK);
        // jest ok, ale nie o to chodzi.
      #endif
      // Jak przypisac do dyrektywy AppEXE ini chyba sie nie da ;p
      // #if AppEXE[str(i)] != NULL
      // da byka
      // #ifdef AppEXE (i to przydalby sie int)
    end;
    // testuje pętle

Nie wiem jak to ogarnąć i czy to w ogole możliwe aby do #define directive dodawac zmienna itd..
Jak sadzisz/sądzicie?

Pozostaje mi zrobic tak

#ifdef AppEXE1
if IsTaskSelected('DesktopIcon1') then
   CreateShellLink()
   //...
#endif
  #ifdef AppEXE2
if IsTaskSelected('DesktopIcon2') then
   CreateShellLink()
#endif

// I tak 5 razy, 
#ifdef AppEXE1 do #ifdef AppEXE5

// nie lubie isc na latwizne, myslalem ze ktos zna jakis patent :)
1

Chodzi mi o to, żeby zamiast #define użyć:

var AppExes: array of string;
SetArrayLength(3);

AppExes[0] := 'jakaswartosc';
AppExes[1] := 'inna wartosc';
AppExes[2] := 'trzecia appka';

i po tym powinieneś spokojnie móc iterować pętlą for, np:

for i := 1 to 5 do begin
      #if AppExes[i] != NULL
           // cośtam
           // ...

Pisane oczywiście z kosmosu, liczę, że pomoże

0

@dzek69 Witam ponownie. Ja wiem ze tak można, tylko ciekawi mnie czy da sie jakos ingerowac w dyrktywy preprocesora. Być może nie wiem jak, a ktoś ogarniety wie. Tak czy inaczej dzieki za podpowiedz.

0

No ale po co pchać się w błędne rozwiązanie na siłę? To służy do czego innego i w najgłupszy sposób świata może to nagniesz, ale po co?

0

@dzek69 mam tak zdefiniowane w instalatorze duzo plikow z pliku ini

Na szybko przyklad.

// NAZWY TWORZONYCH IKONEK
#define DesktopIconSelect1 ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconSelect1", "{cm:CreateDesktopIcon}")
#define DesktopIconSelect2 ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconSelect2", "{cm:CreateDesktopIcon}")
#define DesktopIconSelect3 ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconSelect3", "{cm:CreateDesktopIcon}")
#define DesktopIconSelect4 ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconSelect4", "{cm:CreateDesktopIcon}")
#define DesktopIconSelect5 ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconSelect5", "{cm:CreateDesktopIcon}")

// DEFINUJ NAZWE SKROTOW NA PULPICIE
#define DesktopIconName1  ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconName1", "{#AppEXE1}")
#define DesktopIconName2  ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconName2", "{#AppEXE2}")
#define DesktopIconName3  ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconName3", "{#AppEXE3}")
#define DesktopIconName4  ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconName4", "{#AppEXE4}")
#define DesktopIconName4  ReadIni(SourcePath	+ "\Setup.ini", "Information", "DesktopIconName4", "{#AppEXE5}")

// NFO DO APKI
#define GameVersion ReadIni(SourcePath	+ "\Setup.ini", "Information", "AppVersion", "1.2")
#define CompanyName ReadIni(SourcePath	+ "\Setup.ini", "Information", "CompanyName", "Adrian W.")

itd itd...

Ciekawi mnie też, jak w sekcje [Files] dodać pliki ktore bede uzywal w trakcie instalacji.
Nie każdy osobno, a jakas petla

Katalog z plikami "FileRes"

Struktura INI

[Resources]
Resource1=mydllAPBT.dll
Resource2=7z.dll
Resource3=InnoCallback.dll
Resource4=zstdrec.exe
Resource5=oo2reck.exe
Resource6=
Resource7=
Resource8=
Resource9=
Resource10=

1
[Files]
//  (INI) DODAJEMY PLIKI z sekcji Resources ------------------------------------------------------------------------------------
#define j 0
#sub AddResource
#define DataInf ReadIni(AddBackSlash(SourcePath) + "Setup.ini", "Resources", "Resource" + Str(j), "")
Source: "FileRes\{#DataInf}"; DestDir: {tmp}; Flags: dontcopy;
#endsub
#if ReadIni(AddBackSlash(SourcePath) + "Setup.ini", "Resources", "Resource1", "") != ""
#for {j = 1; ReadIni(AddBackSlash(SourcePath) + "Setup.ini", "Resources", StringChange("ResourceInt","Int", Str(j)), "") !=""; j++} AddResource
#endif
//  ---------------------------------------------------------------------------------------------------------------------------

Cheers ^_^

0

@first_person sprytnie :)

1

Nie bardzo rozumiem, czemu kodujesz to w pascalu zamiast użyć finkcjonalności ISS, coś w ten deseń:

[Files]
Source: "app1.exe"; DestDir: "{app}"; Flags: ignoreversion; Check: AddFile('appexe1')

[Icons]
Name: "{app}\appexe1"; Filename: "{app}\app1.exe"; WorkingDir: "{app}"; Check: AddFile('appexe1')

[Code]
function AddFile(EXEName: String): Boolean;
begin
  Result := (GetIniString('Information', EXEName,'', ExpandConstant('{src}')	+ '\Setup.ini') <>'');
end;

Bo na razie masz dodawanie, a trzeba by jeszcze dopisać usuwanie prze odinstalowaniu, tu masz to out of the box

0

Cześć @Panczo INI mam w katalogu z Inno Setup, wiec var string itd wykluczone.
Stad te #define. instalator nie bedzie korzystal z INI, a jedynie ma za zadananie przypisac stringi.

Po czym je kasuje z pulpitu itd,

procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
begin
  // kasujemy wczesniej utworzeone ikonki
  #ifdef AppEXE1 
  DeleteFile(ExpandConstant('{commondesktop}\{#DesktopIconName1}.lnk'));
  #endif
  #ifdef AppEXE2 
  DeleteFile(ExpandConstant('{commondesktop}\{#DesktopIconName2}.lnk'));
  #endif

// itd... itd...
end;

1 użytkowników online, w tym zalogowanych: 0, gości: 1