[GELÖST] Globale Textkonstanten über Product Properties

Neuling_Opsi
Beiträge: 3
Registriert: 15 Jan 2018, 12:17

[GELÖST] Globale Textkonstanten über Product Properties

Beitragvon Neuling_Opsi » 04 Dez 2018, 13:18

Hallo,

Wir versuchen zur Zeit ein Paket für OpenJDK zu erstellen. Dabei soll der Speicherort im opsi-configed durch ProductProperties gesetzt werden können.
Dies funktioniert auch soweit, ich kann einen festen Pfad (C:\Programme\OpenJDK) eintragen und die Installation geht.

Wir möchten nun aber die globalen Textkonstanten verwenden können um die Speicherorte einstellen zu können.
Wird jetzt im configed in den Properties z.B %ProgramFiles64Dir% (in jeglicher Variation mit/ohne Anführungszeichen) gesetzt, wird diese Konstante leider nicht ersetzt.

Ich gehe jetzt mal davon aus, dass GetProductProperty() da "%ProgramFiles64Dir%" als String behandelt/zurückgibt, und daher keine Ersetzung stattfindet. Gibt es eine Möglichkeit, das ganze irgendwie zu umgehen?

Danke im Voraus für jede Hilfe :)

setup.opsiscript

Code: Alles auswählen

[Actions]
requiredWinstVersion >= "4.11.4.3"
ScriptErrorMessages = false

DefVar $SetupType$
DefVar $ProductId$
DefVar $Setupfile$
DefVar $InstallDir$
DefVar $MinimumSpace$
DefVar $ExitCode$
DefVar $ErrorMsg$
DefVar $LicenseRequired$
DefVar $LicenseKey$
DefVar $LicensePool$
DefVar $MsiId$
DefVar $NsisInstallBatch$
DefVar $LogDir$
DefVar $SilentOption$
DefVar $Umgehung$

Set $LogDir$ = "%opsiLogDir%"

include_append "%ScriptPath%\check_msi_exitcode.opsiscript"

; ----------------------------------------------------------------
Set $SetupType$       = "msi"
; ----------------------------------------------------------------

; $ProductId$ is the name of the product in opsi, only lower letters, no umlauts, no white spaces, use '-' as a seperator
Set $ProductId$       = "openjdk8"
Set $Setupfile$       = "java-1.8.0-openjdk-1.8.0.191-1.b12.ojdkbuild.windows.x86_64.msi"
; the path where we find the product after the installation
Set $InstallDir$      = GetProductProperty("install-dir", "%ProgramFiles64Dir%\OpenJDK")
Set $LicenseRequired$ = "false"
Set $LicensePool$     = "p_" + $ProductId$
Set $MsiId$           = "{579C83AF-A86C-4498-8903-25317C546FEC}"
Set $MinimumSpace$    = "821 MB"
Set $SilentOption$ = GetProductProperty("silent-option","/qb!")

; ----------------------------------------------------------------
; ----------------------------------------------------------------

if not(HasMinimumSpace ("%SystemDrive%", $MinimumSpace$))
   LogError "Not enough space on %SystemDrive%, " + $MinimumSpace$ + " on drive %SystemDrive% needed for " + $ProductId$
   isFatalError "No Space"
   ; Stop process and set installation status to failed
else
   comment "Show product picture"
       ShowBitmap "%ScriptPath%\o4i.png" $ProductId$


   if FileExists("%ScriptPath%\delsub.opsiscript")
      comment "Start uninstall sub section"
      Sub "%ScriptPath%\delsub.opsiscript"
   endif
   
   Message "Installing " + $ProductId$ + " ..."
   
   if $LicenseRequired$ = "true"
      comment "Licensing required, reserve license and get license key"
      Sub_get_licensekey
   endif


   
   comment "Start setup program"
   ChangeDirectory "%SCRIPTPATH%"
   ;----------------------------------------------
   Winbatch_install_msi
   ;----------------------------------------------
   Sub_check_exitcode   
endif


; ----------------------------------------------------------------
; install section
; ----------------------------------------------------------------

[Winbatch_install_msi]
msiexec /i "%ScriptPath%\java-1.8.0-openjdk-1.8.0.191-1.b12.ojdkbuild.windows.x86_64.msi"  /l* "$LogDir$\$ProductId$.install_log.txt" $SilentOption$ ALLUSERS=1 REBOOT=ReallySuppress ADDLOCAL=ALL TARGETDIR=$InstallDir$

; ----------------------------------------------------------------


control

Code: Alles auswählen

[ProductProperty]
type: unicode
name: install-dir
multivalue: False
editable: True
description: Sets the Install-Dir
Zuletzt geändert von Neuling_Opsi am 06 Dez 2018, 13:30, insgesamt 1-mal geändert.

hobbyist
Beiträge: 24
Registriert: 29 Mai 2018, 13:38

Re: Globale Textkonstanten über Product Properties

Beitragvon hobbyist » 04 Dez 2018, 15:15

Hallo,

richtig vermutet. Woher OPSI auch wissen, dass er in der ProductProperty %Konstanten% ersetzen soll. Dann müsstest Du ja umgekehrt die Inhalte escapen. Du musst die Ersetzung selbst im Skript vornehmen, z.B. mit stringReplace oder anderen StringHandling-Funktionen.

Viele Grüße

larsg
Beiträge: 203
Registriert: 16 Dez 2014, 18:06

Re: Globale Textkonstanten über Product Properties

Beitragvon larsg » 05 Dez 2018, 08:57

1) Du könntest auf Umgebungsvariablen in Windows zurückgreifen %ProgramFiles% und %ProgramFiles(x86)% (ja, mit klammer)
Wenn du in DOS den Befehl set eingibts erhälst du eine Übersicht über alle verfügbaren Umgebungsvariablen.

2) Du schreibst in den Properties die Variablen mit anderem Sonderzeichen und ersetzt die im Skript durch "%", und zwar für jede Variable die du berücksichtigen möchtest.

Set $Path$ = GetProductProperty("path","")
Set $Path$ = StringReplace($Path$,"#ProgramFiles32Dir#","%ProgramFiles32Dir%")
Set $Path$ = StringReplace($Path$,"#ProgramFiles64Dir#","%ProgramFiles64Dir%")
...

Hab ich selbst noch nicht so ausprobiert, sollte aber funktionieren. Etwas aufwendig, aber du könntest dir damit eine Sub-Sektion oder besser noch eine Funktion bauen, dann musst du den Krempel nicht in jedes Skript einbauen.

3) Du stellst eine Anfrage bei UIB, das die entsprechenden Änderungen in OPSI eingebaut werden.
Ich sehe keinen Grund warum die Variablen nicht auch in Properties ersetzt werden sollen. Warum muss man die Inhalte dann escapen? Die werden einfach verarbeitet wie bei allen anderen Befehlen auch. Nur eine Frage wie man es ablauftechnisch realisiert. Es ist nämlich sogar eher umgekehrt, das z.b. bei Pfaden die enthaltenen Backslashs escaped werden müssen, mit einer Variable spart man sich den Part, da die Ersetzung durch den Echtwert später erfolgen sollte. Daher sehe ich das eher schon als Bug oder zumindest fehlende Funktionalität.

Neuling_Opsi
Beiträge: 3
Registriert: 15 Jan 2018, 12:17

Re: Globale Textkonstanten über Product Properties

Beitragvon Neuling_Opsi » 05 Dez 2018, 15:33

Erstmal, vielen Dank für eure Antworten.

Es ist wirklich ein Graus, dass es nicht so einfach mit getProductProperty funktioniert.
Ich glaube aber ich habe einen Weg aus meiner Krise gefunden.

Ich habe mir folgende Hilfsvariable definiert:

Code: Alles auswählen

Set $Hilfsvar$   = takestring(0, splitString($InstallDir$,"\"))


Diese sorgt dafür das ich den String einer dieser Konstanten so zerlege das ich nur die entsprechende Konstante als String bekomme.

mit einem elif-Konstrukt

Code: Alles auswählen

if contains($InstallDir$,"Konstante")
Set $Umgehung$   =  stringReplace($Installdir$,$Hilfsvariable$,"%Konstante%")


Komischerweise nutzt stringReplace diese globalen Textkonstanten

Ersetze ich dann je nach Fall die entsprechenden Stellen in den richtigen Pfad. Sollte keine andere Konstante vorkommen wird das ganze dann als Pfad behandelt.

Ist vermutlich keine schöne Lösung, vielleicht auch nicht effektiv, aber erstmal läuft es so. Ich lerne schließlich noch.

hobbyist
Beiträge: 24
Registriert: 29 Mai 2018, 13:38

Re: Globale Textkonstanten über Product Properties

Beitragvon hobbyist » 05 Dez 2018, 18:44

Hallo,
Neuling_Opsi hat geschrieben:Komischerweise nutzt stringReplace diese globalen Textkonstanten


wieso? Dazu ist die Konstante ja da!
Deine Ersetzung wäre mit

Code: Alles auswählen

set $Installdir$ = stringReplace($Installdir$, "%"+"ProgramFilesDir"+"%","%ProgramFilesDir%")

z.B. für die Konstante %ProgramFilesDir% einfacher gewesen.

Du musst Variablen und Konstanten unterscheiden (sie unterscheiden sich ja auch optisch durch $ bzw. %). Denk einfach mal so: Konstanten können bereits zur Präprozessorzeit im Code ersetzt werden, also vor der Laufzeit. Daher ersetzt OPSI (wann und wie es das wirklich tut, mal außen vor gelassen) "%ProgramFilesDir%" durch den Programmpfad, wenn es im Programmcode steht. Schreibst Du es in einem String, den Du über die Property einliest, ist das zur Laufzeit, da ist die Ersetzung der Konstante schon rum. Freilich kann UIB so etwas einprogrammieren, Du kannst aber auch!

Durch das Zusammensetzen des Konstantennamen in einem String "%"+"ProgramFilesDir"+"%" wird die Konstante im Code nicht mehr erkannt und nicht ersetzt.

Noch ein bisschen mehr dazu: da die Konstante typenlos ist, musst Du Sie in einem Set mit Anführungzeichen in einen String packen, was Du ja auch gemacht hast:

Code: Alles auswählen

   DefVar $test$
   DefVar $neu$
   Set $test$ = "%ProgramFilesDir%" ;;;geht
   Set $test$ = %ProgramFilesDir% ;;;geht nicht
   Set $neu$ = "ABC"
   Set $test$ = %ProgramFilesDir%+$neu$ ;;;geht nicht
   Set $test$ = $neu$+$neu$ ;;;geht
   Set $test$ = "$neu$$neu$" ;;;geht auch, aber evtl. nicht so, wie Du denkst.


Und da haben wir die OPSI-Pseudo-Integer-Vergleiche noch nicht mal thematisiert :lol:

Neuling_Opsi
Beiträge: 3
Registriert: 15 Jan 2018, 12:17

Re: Globale Textkonstanten über Product Properties

Beitragvon Neuling_Opsi » 06 Dez 2018, 13:30

Vielen Dank für diese ausführliche und lehrreiche Erklärung.
Es hätte so schön simpel sein können, ich mussts mir kompliziert machen. Da war wohl der Kaffee alle ;).

Ich mache hier dann erstmal auf gelöst. Es läuft jetzt so. Als SHK lernt man halt doppelt ;)

larsg
Beiträge: 203
Registriert: 16 Dez 2014, 18:06

Re: Globale Textkonstanten über Product Properties

Beitragvon larsg » 07 Dez 2018, 11:48

Neuling_Opsi hat geschrieben:Es hätte so schön simpel sein können, ich mussts mir kompliziert machen.

Das geht wohl allen so die mit OPSI anfangen, wenn man etwas tiefer in die Materie geht wird es schnell komplex und man findet sich hier im Forum wieder :D