1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Dankeschön

Beiträge von Dankeschön

  • [INetGet] Vorzeitiger Abbruch

    • Dankeschön
    • 5. Juni 2011 um 20:27

    Hallo zusammen.

    Ich habe ein kleines Problem:
    Mein selbstgemachter Downloadmanager initiiert den Download erfolgreich,
    aber sobald InetGetInfo die Größe des herunterzuladendem Objekt herausfindet,
    wird der Download abgebrochen.
    Zu diesem Zeitpunkt wurde noch kein einziger Byte geladen.

    Nun frage ich mich,
    woran es liegen kann,
    dass der Download abgebrochen wird,
    obwohl die Dateigröße ja sogar richtig erkannt wird.


    Dankeschön im Vorraus,
    Dankeschön

    P.S.: Ich weiß, das Skript mitzuposten würde helfen,
    aber da das Problem offensichtlich allgemeinerer Natur ist,
    und das Skript aus mehr als tausend unübersichtlichen Zeilen Code besteht,
    versuch ichs erstmal ohne...

  • Seltsame Fehler

    • Dankeschön
    • 22. März 2011 um 21:43

    Das Problem besteht immernoch.

    Problematisch ist, dass sobald eine Vollbildanwendung (getestet: Skype) in den Vordergrund tritt,
    das gesamte Skript pausiert !!!
    Der PC fährt sich nicht runter, die AdLib-Kontrollfunktion klappt nicht etc etc

    In der Hoffnung um Hilfe,
    Dankeschön

  • Seltsame Fehler

    • Dankeschön
    • 20. Februar 2011 um 14:35
    Zitat von Sprenger120

    Hi,
    also beim ersten drüberschauen ist mir folgendes aufgefallen:
    1. Um einen Prozess zu beenden kannst du ProcessClose benutzen
    //tue ich das nicht schon ? Zeile 157
    2. Wenn du in der Registry etwas schreiben willst (Win Vista und höher) musst du immer #RequireAdmin an den Anfang setzen
    //das Programm läuft nur lokal, und da hat es Adminrechte


    Was passiert denn nicht ? Wird kein LV Eintrag hinzugefügt? Dann würde ich mal die @error Rückgabe von FileOpenDialog mir ausgeben lassen und/oder die Rückgabe von GuiCtrlCreateListViewItem anschauen.
    //Exakt das passiert. Ich werde mir das noch einmal ansehen

    Alles anzeigen

    Meine Kommentare stehen per // drunter :)

    Das Problem mit dem "pausieren" des skriptes während der ausführung eines programmes besteht offensichtlich immer.
    Das wundert mich, da ich shellexecute, und nicht shellexecutewait benutze...

  • Seltsame Fehler

    • Dankeschön
    • 19. Februar 2011 um 11:17

    Wieso kommt der Fehler dann nur gekegentlich ?

  • Seltsame Fehler

    • Dankeschön
    • 18. Februar 2011 um 17:26

    Entschuldigung für den nichtssagenden Titel,
    aber genau das ist das Problem -
    ich habe keine Error, es sieht alles sauber aus,
    aber manchmal geht garnichts mehr.

    Folgendes Skript (selbstgemacht) soll mir helfen,
    dass ich meinen PC unbeaufsichtigt Familienmitgliedern zur Verfügung stellen kann:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <GuiListView.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $forbidstring

    [/autoit] [autoit][/autoit] [autoit]

    Do
    $inpu = InputBox("","Passwort:","","*")
    If @error Then Exit
    $best = InputBox("","Nochmal das PW:","","*")
    If @error Then Exit
    If $inpu <> $best Then
    MsgBox(16,"","Keine Übereinstimmung")
    Else
    ExitLoop
    EndIf
    Until 1=2

    [/autoit] [autoit][/autoit] [autoit]

    $var = WinList()
    For $i = 1 to $var[0][0]
    ; Only display visble windows that have a title
    If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then
    WinClose($var[$i][0])
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $sProzess = "explorer.exe"
    Run('"' & @ComSpec & '" /c taskkill /F /IM '&$sProzess, '', @SW_HIDE)

    [/autoit] [autoit][/autoit] [autoit]

    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System","DisableTaskMgr","REG_DWORD",1)
    RegWrite("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System","DisableTaskMgr","REG_DWORD",1)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate("",300,450)
    $list = GUICtrlCreateListView("Programm",5,5,290,340)
    _GUICtrlListView_SetColumnWidth($list, 0, 290)
    $startb = GUICtrlCreateButton("Starten",5,355,140,40)
    $addb = GUICtrlCreateButton("Hinzufügen",155,355,140,40)

    [/autoit] [autoit][/autoit] [autoit]

    $endh = GUICtrlCreateInput(@HOUR+1,125,415,50,25)
    GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1,23,0)
    $endm = GUICtrlCreateInput(@min,180,415,50,25)
    GUICtrlCreateUpdown(-1)
    GUICtrlSetLimit(-1,60,0)
    $settime = GUICtrlCreateButton("Set",180+55,415,50,25)
    Local $limit = 0,$limith,$limitm
    $showt = GUICtrlCreateLabel(@HOUR & ":" & @MIN,50,417,50,25)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    AdlibRegister("closef",1000)
    OnAutoItExitRegister("endfu")
    $timer = TimerInit()
    while 1

    [/autoit] [autoit][/autoit] [autoit]

    If TimerDiff($timer) >= 1000*30 Then
    GUICtrlSetData($showt,@HOUR & ":" & @MIN & "N")
    $timer = TimerInit()
    If $limit Then
    GUICtrlSetData($showt,@HOUR & ":" & @MIN & " Y")
    ;HotKeySet("{f4}","notausgang")
    If @HOUR >= $limith And @MIN >= $limitm Then

    [/autoit] [autoit][/autoit] [autoit]

    Do
    ;SoundPlay(@ScriptDir & "\sound.wav",0)
    If InputBox("","Passwort?","","*",-1,-1,@DesktopWidth/2,@DesktopHeight/2,5) <> $inpu Then
    MsgBox(16,"","Falsches PW",2)
    Else
    ExitLoop
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $var = WinList()
    For $i = 1 to $var[0][0]
    If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then
    WinClose($var[$i][0])
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $check = StringSplit($forbidstring,"|")

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $check[0]
    If ProcessExists($check[$i]) Then ProcessClose($check[$i])
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Beep(5000,2000)
    Until 1=2
    Exit
    EndIf
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Switch(GUIGetMsg())
    Case $settime
    If InputBox("","Passwort?","","*") <> $inpu Then
    MsgBox(16,"","Falsches PW")
    ContinueLoop
    EndIf
    $limit = Not $limit
    If $limit Then
    GUICtrlSetState($endh,$GUI_DISABLE)
    GUICtrlSetState($endm,$GUI_DISABLE)
    GUICtrlSetData($settime,"Stop")
    GUISetState()
    $limith = GUICtrlRead($endh)
    $limitm = GUICtrlRead($endm)
    Else
    GUICtrlSetState($endh,$GUI_ENABLE)
    GUICtrlSetState($endm,$GUI_ENABLE)
    GUICtrlSetData($settime,"Set")
    GUISetState()
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case $GUI_EVENT_CLOSE
    If InputBox("","Passwort?","","*") <> $inpu Then
    MsgBox(16,"","Falsches PW")
    ContinueLoop
    EndIf
    Exit

    [/autoit] [autoit][/autoit] [autoit]

    Case $addb
    If InputBox("","Passwort?","","*") <> $inpu Then
    MsgBox(16,"","Falsches PW")
    ContinueLoop
    EndIf
    $fop = FileOpenDialog("","","Exe (*.exe)")
    If @error Then ContinueLoop
    GUICtrlCreateListViewItem($fop,$list)
    $spl = StringSplit($fop,"\")
    $forbidstring = $forbidstring & "|" & $spl[$spl[0]] & "|"

    [/autoit] [autoit][/autoit] [autoit]

    Case $startb
    $read = StringReplace(GUICtrlRead(GUICtrlRead($list)),"|","")
    If StringLen($read) < 2 Then
    MsgBox(16,"","Wähle ein Programm aus")
    ContinueLoop
    EndIf
    ShellExecute($read)

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func closef()
    $var = WinList()
    For $i = 1 to $var[0][0]
    If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then
    $acb = WinGetProcess($var[$i][0])
    $name = ""
    $list = ProcessList()
    for $i = 1 to $list[0][0]
    If $list[$i][1] = $acb Then
    $name = $list[$i][0]
    ExitLoop
    EndIf
    next

    [/autoit] [autoit][/autoit] [autoit]

    If Not StringInStr($forbidstring,$name) Then
    ;WinClose($var[$i][0])
    ProcessClose($name)
    EndIf
    EndIf
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func endfu()
    RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System","DisableTaskMgr","REG_DWORD",0)
    RegWrite("HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System","DisableTaskMgr","REG_DWORD",0)
    ShellExecute("explorer.exe")
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func notausgang()
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func IsVisible($handle)
    If BitAnd( WinGetState($handle), 2 ) Then
    Return 1
    Else
    Return 0
    EndIf
    EndFunc

    [/autoit]

    Folgende Obskuritäten treten allerdings MANCHMAL (habe keinen Trigger gefunden) auf:

    Zitat


    * Wenn ich ein Programm hinzufüge, und den FileOpenDialog bestätige, passiert garnichts
    ==> Neustart behebt oft das Problem
    * Die Zeitmessung, um die Benutzung des Computers zu beenden, funktioniert oft/immer nicht,
    wenn noch ein anderes, intern gestartetes Programm im Vordergrund läuft

    Ich hoffe hier einfach mal auf Verbesserungsvorschläge
    und auf den entscheidenden Hinweis auf diese Gelegenheitsfehler...

  • Code in Konsole ausführen (Special)

    • Dankeschön
    • 6. Februar 2011 um 11:45

    *kusshand*

    Danke, nach einer so optimalen Lösung hab ich gesucht :)

  • Code in Konsole ausführen (Special)

    • Dankeschön
    • 6. Februar 2011 um 00:42

    Guten Morgen.

    Ihr habt sicher nun gedacht, ihr könntet mich mit einem _RunDos abspeisen - sorry, aber so einfach ist mein Problem nicht ;)

    Ich habe aktuell die rar.exe, also die Kommandozeilendatei von WinRar.exe .
    Ich möchte per Skript nun Archive entpacken lassen, was per _RunDos auch gut funktioniert.

    Nun habe ich mir aber überlegt, dass eine Fortschrittsanzeige angebracht wäre ;)

    Wenn ich meinen bisherigen Befehl zum Entpacken (abgespeckt) -

    [autoit]

    $query = "rar.exe e -hp" & $split[8] & " -y """ & $toprep & """ """ & $toprep2 & """ >""" & @TempDir & "\unrar.log"""
    _RunDOS($query)

    [/autoit]

    - verwende, und dann versuche, auf die unrar.log zuzugreifen, passiert dies erst, nachdem die Datei fertig entpackt wurde.

    Das bringt mir natürlich nichts, da zu dem Zeitpunkt das Entpacken bereits abgeschlossen ist.

    Was ich also benötige ist ein Weg, per Kommandozeile die rar.exe aufzurufen, und dort live aus der Konsole meine Informationen zu bekommen.

    Dankeschön,
    Dankeschön

    P.S.: cmd.exe fernsteuern ist sehr ... eklig, es wäre also gut, wenn ihr einen Trick ohne diese Technik kennt ;)

  • Sichere SQL-Abfrage

    • Dankeschön
    • 26. Januar 2011 um 16:15

    Ich weiß echt nicht, wie das Tutorial helfen kann,
    auch dort wird das DB-Passwort im Klartext im Quelltext verankert.

    @tuttifrutti:
    Wie willste denn auf die DB zugreifen, wenn du dich garnicht verbunden hast, um dann mit dem PW zu connecten ?

  • AutoIt Windows Screenshooter v1.84 Build 2019-08-18

    • Dankeschön
    • 26. Januar 2011 um 15:25

    Grund dafür wird wohl der Nutzen sein.
    Das Skript ist super gemacht, viele Features, sauber gecodet etc.

    Aber ich persönlich brauche das Tool nicht (brauche so etwas zu selten, und dann benutz ich paint+druck),
    also lade oder kommentiere ich nicht (eigentlich).

    Ein Lob an UEZ lass ich aber trotzdem kurz noch da ;)

  • Manuell gehts, per Autoit nicht

    • Dankeschön
    • 26. Januar 2011 um 15:21

    Und der IE kann auf den nicht zugreifen ?
    Oder kann ich den freigeben ?

    Da muss ja nach einigen Überlegungen eher ein Problem des IE sein, nich ?

    //edit:
    Sehe grade, dass ich mit einem php workaround auch nicht zum Ziel komme,
    da dort dasselbe Problem ist, Error 404 :\

  • Substring zählen

    • Dankeschön
    • 22. Dezember 2010 um 21:08

    Danke, so hatte ichs auch versucht,
    nur den 1er Parameter kannte ich nicht ;)

    Funzt, danke :)

  • Substring zählen

    • Dankeschön
    • 22. Dezember 2010 um 20:41

    Tag zusammen.

    Suche eine Funktion, um zu zählen,
    wie oft ein Substring in einem String vorhanden ist.

    Dankeschön,
    Dankeschön

  • GDI+ String ändern

    • Dankeschön
    • 18. Dezember 2010 um 10:55

    Und das tut es :)

    Wenn ichs richtig sehe,
    zeichnest du einfach vor dem String das Hintergrund immer neu,
    berechnest es aber nicht neu und überschreibst damit die vorherige Schrift.
    Richtig ?

    Danke auf jeden Fall,
    sehr großen Dank auch euch allen :)

  • GDI+ String ändern

    • Dankeschön
    • 17. Dezember 2010 um 16:04

    Gefunden :)

    Ja, sowas wollte ich (auch wenn ich das langsame Verwischen und die Laufschrift nicht brauche, und ich den ganzen Bildschirm verpixel).
    Ich schau´s mir mal an...

    //edit: Blicke nicht ganz durch...
    Kannst du mir ein Beispiel machen, wo ein String an einer fixen Position von 5 auf 1 runtergezählt wird, oder wo einfach nur der String überschrieben wird.
    Bei soviel Code ist es schwer, das wichtige rauszufiltern, wenn man wie ich keine AHnung von GDI+ hat...

  • GDI+ String ändern

    • Dankeschön
    • 16. Dezember 2010 um 22:30

    name22:
    Leider soll sich die Schrift sekündlich aktualisieren (Zeit-Countdown),
    da wird alles sehr aufwendig...

    Also einfachn neuen Screenshot vom verschwommenem Bild machen und immer neusetzen ?

  • GDI+ String ändern

    • Dankeschön
    • 14. Dezember 2010 um 22:58

    Hui, GDI+ sieht immer so verdammt komplex aus...

    Wenn ich richtig geguckt habe besteht das Kernstück aus dieser Funktion:

    [autoit]

    Func Print_Bitmap_Font($hWnd, $Msg, $wParam, $lParam)
    Local $fw = 16, $fh = 16, $size = 1, $dx = 9.5 * $size
    Local $chk

    [/autoit][autoit][/autoit][autoit]

    $chk = BitAND($wParam, 0x0000FFFF)
    Switch $chk
    Case $Input
    $inp = GUICtrlRead($Input)
    $inp_len = StringLen($inp)
    If $inp_len < Ceiling($width / $dx - 2) Then
    $aInp = StringSplit($inp, "", 2)
    _GDIPlus_GraphicsClear($hBackbuffer, "0xFF" & $bgc)
    For $i = 0 To $inp_len - 1
    $x = Mod(Asc($aInp[$i])-32, 32)
    $y = Floor((Asc($aInp[$i])-32) / 32)
    _GDIPlus_GraphicsDrawImageRectRect($hBackbuffer, $hImage, $x * $fw, $y * $fh, $fw -1, $fh -1, $fw + $i * $dx, $gfx_h / 2 - ($fh * $size / 2), $fw * $size, $fh * $size)
    Next
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, $heigth * $factor2, $gfx_w, $gfx_h)
    EndIf
    EndSwitch

    [/autoit][autoit][/autoit][autoit]

    Return "GUI_RUNDEFMSG"
    EndFunc

    [/autoit]

    Leider sagen mir diese Berechnungen nichts.
    Es wäre also schön,wenn mir jemand den Stups in die richtige Richtung geben könnte, und mir die wichtige Zeile markieren könnte, oder/und mir sagen könnte, wie UEz´s System theoretisch funktioniert... :)

    Beim zweiten Blick auf den Code sehe ich auch hier eine Färbung des Hintergrunds, also auch nur eine Art "Übermalen",
    was wiederum den Blur-Screenshot zerstört...

    dankeschön im vorraus :)

  • GDI+ String ändern

    • Dankeschön
    • 14. Dezember 2010 um 21:48

    Ja, die Frage ist ja grade, wie ich diesen String wieder löschen kann,
    da es wohl zu ressourcenfressend wäre, den Blur-Effekt jede sekunde neu zu berechnen...

  • GDI+ String ändern

    • Dankeschön
    • 14. Dezember 2010 um 21:24

    Aktuell benutze ich diesen Code

    Spoiler anzeigen
    [autoit]

    #include <GDIplus.au3>
    #include <ScreenCapture.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $GDIP_BLUREFFECT = "{633C80A4-1843-482b-9EF2-BE2834C5FDD4}"
    Global Const $GDIP_SHARPENEFFECT = "{63CBF3EE-C526-402c-8F71-62C540BF5142}"
    Global Const $GDIP_COLORMATRIXEFFECT = "{718F2615-7933-40e3-A511-5F68FE14DD74}"
    Global Const $GDIP_COLORLUTEFFECT = "{A7CE72A9-0F7F-40d7-B3CC-D0C02D5C3212}"
    Global Const $GDIP_BRIGHTNESSCONTRASTEFFECT = "{D3A1DBE1-8EC4-4c17-9F4C-EA97AD1C343D}"
    Global Const $GDIP_HUESATURATIONLIGHTNESSEFFECT = "{8B2DD6C3-EB07-4d87-A5F0-7108E26A9C5F}"
    Global Const $GDIP_LEVELSEFFECT = "{99C354EC-2A31-4f3a-8C34-17A803B33A25}"
    Global Const $GDIP_TINTEFFECT = "{1077AF00-2848-4441-9489-44AD4C2D7A2C}"
    Global Const $GDIP_COLORBALANCEEFFECT = "{537E597D-251E-48da-9664-29CA496B70F8}"
    Global Const $GDIP_REDEYECORRECTIONEFFECT = "{74D29D05-69A4-4266-9549-3CC52836B632}"
    Global Const $GDIP_COLORCURVEEFFECT = "{DD6A0022-58E4-4a67-9D9B-D48EB881A53D}"

    [/autoit] [autoit][/autoit] [autoit]

    _GDIPlus11_Startup()
    If @error Then Exit MsgBox(0x10, "Error", "GDIPlus v1.1 is not installed")

    [/autoit] [autoit][/autoit] [autoit]

    Local $hGUI, $hGraphics, $hImage, $hBlurredImage, $hEffect, $file
    FileDelete(@TempDir & "\screen.jpg")
    _ScreenCapture_Capture(@TempDir & "\screen.jpg", 0,0, -1,-1, False)
    $file = @TempDir & "\screen.jpg"
    If @error Then Exit
    $hImage = _GDIPlus_ImageLoadFromFile($file)

    [/autoit] [autoit][/autoit] [autoit]

    $hGUI = GUICreate("GDI+ v1.1 Demo Blur", _GDIPlus_ImageGetWidth($hImage), _GDIPlus_ImageGetHeight($hImage))
    GUISetState()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hEffect = _GDIPlus_EffectCreate($GDIP_BLUREFFECT)
    $hBlurredImage = _GDIPlus_BitmapCreateWithEffect($hImage, $hEffect)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBlurredImage, 0, 0)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics(_GDIPlus_ImageGetWidth($hImage), _GDIPlus_ImageGetHeight($hImage), $hGraphics)
    $hBuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)

    [/autoit] [autoit][/autoit] [autoit]

    Local $count = 0
    $donebut = GUICtrlCreatePic(@ScriptDir & "\erledigt2.gif",(@DesktopWidth/2)-200,@DesktopHeight/2+300,355,197)
    GUISetState()
    Do
    $count += 1
    _GDIPlus_GraphicsDrawString($hGraphics,"testring #" & $count,(@DesktopWidth/2)-300,@DesktopHeight/2)
    GUISetState()
    Sleep(1000)
    Until GUIGetMsg() = -3

    [/autoit]


    was aber logischerweise nicht funktioniert, weil die Strings sich immer überschreiben (überlappen) und dadurch unleserlich werden.

    Nun ist meine Frage, wie ich denn einen mit _GDIPlus_GraphicsDrawString erstellten String entferne oder ändere,
    ohne die ganze GDI+ Umgebung mitzulöschen (was die bisherigen Befehle getan haben), wie z.bsp. der verschwommene Screenshot in meinem Skript.

    mfg,
    Dankeschön

  • Zertifikate für autoit.de-User

    • Dankeschön
    • 24. November 2010 um 23:01

    Ich befürwörte die Idee, auch wenn ich hier nur halb aktiv bin...
    Da ich gerne Tools für versch. Communties veröffentliche, wäre so ein gemeinsamer Anker zur Authentifizierung meiner Programme natürlich spitze...

    Ich stimme allerdings auch den Vorpostern zu, dass vor allem hier nur der Quellcode was zu suchen hat...

  • Check your Love

    • Dankeschön
    • 24. November 2010 um 22:59

    Mach eine Datenbank mit den Namen und ihrem Namensklischee-IQ...

    Kevin ist dumm, Jaqueline auch, sie passen gut zueinander.
    Herodes ist klug, Aristhetela ( :D ) auch, sie passen gut zueiander.

    Klug und dumm aber nicht :P

    (btw sehr unnötige Arbeit ;) )

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™