https://www.autoitscript.com/forum/topic/84…-master-volume/
_AudioEndpointVolume.au3 damit habe ich bisher gute Erfahrungen machen können.
https://www.autoitscript.com/forum/topic/84…-master-volume/
_AudioEndpointVolume.au3 damit habe ich bisher gute Erfahrungen machen können.
Das WinHttp-Objekt direkt anzusprechen ist in AutoIt nicht unbedingt das Mittel der Wahl, denn es gibt einen hervorragenden Wrapper dafür.
Lad dir das mal runter und bau dein Skript mal darauf um, dann kriegst du auch Fehlermeldungen mit denen du was anfangen kannst: https://github.com/dragana-r/autoit-winhttp/releases
Ich bin mir nicht sicher, ob Buttons standardmäßig eine Funktion/ein Event dafür anbieten aber mit $GUI_EVENT_PRIMARYDOWN und $GUI_EVENT_PRIMARYUP kannst du herausfinden ob die Maustaste gedrückt wird.
Du könntest es einfach so kombinieren, dass du GUIGetMsg mit dem advanced Parameter = 1 nutzt, dann kriegst du auch gleichzeitig die Koordinaten, von wo der Klick ausgelöst wurde.
Jetzt musst du nur noch im Event die Koordinaten mit denen des Buttons vergleichen, liegen sie dadrin, soll gesendet werden.
Wird die Maustaste wieder angehoben, dann soll abgebrochen werden.
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
Global Const $BUTTON_X = 32
Global Const $BUTTON_Y = 32
Global Const $BUTTON_WIDTH = 235
Global Const $BUTTON_HEIGHT = 129
GUICreate("Form1", 310, 219, 192, 124)
$hButton = GUICtrlCreateButton("Klick && halte mich", $BUTTON_X, $BUTTON_Y, $BUTTON_WIDTH, $BUTTON_HEIGHT)
GUISetState(@SW_SHOW)
While Sleep(10)
$nMsg = GUIGetMsg(1)
Switch $nMsg[0]
Case $GUI_EVENT_CLOSE
Exit
Case $GUI_EVENT_PRIMARYDOWN
; $nMsg[3] = X
; $nMsg[4] = Y
Local $iMouseX = $nMsg[3]
Local $iMouseY = $nMsg[4]
If $iMouseX >= $BUTTON_X And $iMouseX <= $BUTTON_X + $BUTTON_WIDTH _
And $iMouseY >= $BUTTON_Y And $iMouseY <= $BUTTON_Y + $BUTTON_HEIGHT Then
GUICtrlSetData($hButton, "Sende Daten")
EndIf
;Alternativ ginge auch $hButton, weil das Event nur ausgelöst wird,
;wenn der Button wieder losgelassen wurde
Case $GUI_EVENT_PRIMARYUP
GUICtrlSetData($hButton, "Klick && halte mich")
EndSwitch
WEnd
Alles anzeigen
Den 1. Beitrag editieren und auf erledigt setzen.
Wenn du " ersetzen möchtest und deine Strings ebenfalls mit " beginnen und enden kannst du die einfach innerhalb des Strings verdoppeln, dann erkennt das AutoIt automatisch als " innerhalb des Strings an.
Also bei deinem Code steige ich auch nicht durch, ich bin mir aber zu 100% sicher, dass wenn du alles sorgfältig in Arrays verstaust auch am Ende deutlich weniger Zeilen unterm Strich hast.
Du fragst z.B. ab welchen Wert das $Input_dropdown_berater Control hast und wiederholst die Anweisung dann dementsprechend für alle Variablen.
Speichere alles in einem Array, und iteriere einfach von 0 bis zum ausgelesenen Wert, da kommst du auf das selbe hinaus.
Genauso wie ich es dir anfänglich vorgeschlagen habe.
Was ist der Unterschied? Unter Windows ist die Shell doch das zuständige Programm zum ausführen von anderen Programmen. (Knoten-im-Kopf)
Wenn du Programme aus dem Explorer heraus startest ja, aber selbst die ShellExecute API führt am Ende des Tages auch nur ein Run aus.
Startest du Programme über andere Programme bist du nicht an eine Shell gebunden, du kannst auch dem Betriebssystem direkt sagen, dass ein Programm gestartet werden soll.
Die Shell startet keine Programme und lädt sie in den RAM, das tut das Betriebssystem wenn du den entsprechenden Betriebssystemaufruf verwendest.
Damit du dich mit Privilegien usw. nicht ärgern musst gibt es die ShellExecute API, die bietet dir auch noch andere Hilfestellungen damit du dich mit Run nicht rumschlagen musst.
Dafür muss die Shell auf dem System vorhanden sein, ist sie es nicht, funktioniert die API nicht. Run ist direkt im System verwurzelt, da es ein direkter Betriebssystemaufruf ist.
Dein Programm wird nicht "aufgerufen" sondern wird von Run ausgeführt, und zur Ausführung fehlen dir die Rechte.
ShellExecute führt dein Programm nicht direkt als Nachfolger mit geerbten Privilegien aus, sondern es stellt fest, dass dir die Rechte fehlen und bietet dir an, dass Programm zu starten indem du dich mit höheren Rechten authentifizierst. DU startest das Programm nicht, die Shell tuts.
Anders ausgedrückt. Hätte ich in meinem Script Admin-Rechte angefordert und bekommen, würde das Starten des Setups mit Run vermutlich ohne weitere UAC-Anfrage funktionieren, oder? (ungetestet)
Korrekt.
Da frage ich mich, warum Run nicht so nett ist!? Und ich frage mich, ob Run denn was anderes macht, als die Shell (den Windows Explorer) zum Starten der Setup.exe zu benutzen!?
Das ist nicht der Sinn von Run.
Alle von Run gestarteten Anwendungen werden nicht über die Shell gestartet sondern über einen Betriebssystemaufruf, und der gestartete Prozess erbt (wenn man es nicht anders angibt) die Rechte, die das aufrufende Skript besitzt.
ShellExecute hingegen macht noch vieles im Hintergrund und zeigt dir eben diese UAC-Prompt.
Wieso sollte denn Run das selbe machen? Dann kann man sich doch direkt eine Funktion sparen.
Was ich nicht verstehe ist, dass Run die Setup.exe nicht startet.
Wo ist mein Denkfehler?
Es sind zwei verschiedene Paar Schuhe.
Run versucht die Datei auszuführen, es ist aber nicht möglich, da die Rechte fehlen. Der User ist nicht berechtigt die Datei auszuführen.
Ändere die Dateiattribute, dass du Vollzugriff auch ohne Adminrechte hast, und die Datei startet.
ShellExecute führt keine Datei direkt aus wie Run es tut. Du sagst mit ShellExecute nur, "hey, führe mir diese datei bitte aus".
ShellExecute versuchts und schafft es nicht, weil dir ebenfalls die Rechte fehlen, jedoch bietet dir die Shell an, die Datei auszuführen, wenn du dich als Administrator verifiziert.
Wenn du dich als Admin verifizierst, indem du auf "Ja" klickst beim UAC-Prompt, erbst du diese Rechte nicht.
Das wird auch klar wenn du versuchst mal eine GUI zu schließen die mit Adminrechten läuft, es klappt nicht, wenn du nicht auf dem selben Level oder höher bist.
Versuch mal mit Run eine txt-Datei zu starten, es klappt nicht. ShellExecute hingegen startet das zugewiesene Programm und übergibt die Datei als CLI-Parameter.
Genau das was eine Shell tun soll.
Du kannst auch dein Skript so modifizieren, dass es ohne Adminrechte startet, und wenn du welche brauchst um Programme zu starten, kannst du das "nachträglich" anfordern.
Wenn du gänzlich auf Adminrechte verzichten willst führt bei dir kein Weg drum rum ShellExecute zu verwenden oder den User das ganze selbst starten zu lassen.
Es wäre bestimmt auch möglich mit Run die @ComSpec zu starten und so das ganze zu starten, aber das läuft letzen Endes dann auch über die ShellExecute API wenn ich mich nicht täusche.
Run ist das abgespeckte Pendant zu RunAs, und dort kannst du direkt Zugangsdaten für Domäne, Konten und Passwörtern abgeben.
Ich schätze, auch aus diesem Grund wird kein UAC-Prompt getriggert, da es sonst in AutoIt keine Möglichkeit gäbe, ein Setup zu starten ohne den User damit zu belästigen, für den Fall, dass solch ein Zugriff nicht möglich ist.
ShellExecute funktioniert ja auch komplett anders, es verwendet die ShellExecute API von Windows und diese zeigt dir automatisch das UAC-Prompt an, eben weil es über die Shell läuft und die Anwendung nicht direkt geladen wird. Das bringt auch einige andere Implikationen mit sich als nur die UAC-Prompt.
Meinem Verständnis nach bringt mir das aber auch keine Ersparnis bei der Menge der Codezeilen.
Ich muss so erst abfragen welche Inputs Daten haben, die dann auslesen und an die Ausgabe schicken.
Vielleicht scheint es dir ja nicht auf die schnelle ersichtlich zu sein, aber ich kann dir gerne weiter helfen.
Am besten wird so etwas klar wenn du uns ein Beispielskript schreibst, das quasi die selbe Struktur wie dein jetziges Skript hat, mit den dutzenden von Code-Zeilen die du einsparen willst.
Das rüsten wir dann mal auf die Arrayvariante um und es sollte dann hoffentlich etwas deutlicher werden.
Bitte nicht dein jetziges Skript posten, das scheint sehr überladen zu sein, wenn ich mir die Zeilen so ansehe.
Erstell doch einfach eine GUI auf der das ganze zu sehen ist und zeige diese GUI je nach belieben an?
Gab letztens einen Thread dazu: GIF-Animation mit GDI+
Vielleicht möchtest du uns erstmal erzählen was dein Skript am Ende des Tages bewerkstelligen soll.
Manchmal sieht man den Wald vor lauter Bäumen nicht, und grundlos wild in einem Browser rumklicken kann ich auch nicht nachvollziehen.
Ich würde gerne die Zahl in $Input_berater_1 gegen $i tauschen, da ich so schon mal ein paar hundert Zeilen Code sparen kann.
Wenn du deine Variablen am Ende immer nummerierst solltest du vielleicht sie direkt in ein Array speichern.
Also Local $berater[] = [ $berater1, $berater2, ... ]. Dann kannst du auch gemütlich über das Array laufen und dir den Code sparen.
Der Zugriff erfolgt dann über $berater[0] ($berater1 in diesem Fall).
Ne, eben dann stimmt sie ja.
Beim Vorwärtslaufen hast du das Problem, dass du die Größe des Arrays als Ziel setzt, aber da du währenddessen Indizes löscht, kommt die Größe nicht mehr hin.
Du bist im Index 3, löscht 3 und gehst in der nächsten Schleifeniteration in Index 4, aber dieser Index ist bereits auf 3 nachgerutscht.
Beim Rückwärtslaufen passiert das eben nicht, du fängst nämlich am Ende an und willst bei Index 0 ankommen.
Du bist im Index 5, löscht 5 und gehst in Index 4, Index 4 ist und bleibt auch bei 4, lediglich der Index der nach 5 kommt (also 6) rutscht auf 5 nach, aber das ist ja egal.
Hier ein kleines Beispiel, bei der Vorwärtsiteration werden nicht alle gewünschten Indizes gelöscht.
AutoIt spuckt dir sogar einen Fehler aus, dass einige Indizes nicht mehr erreichbar sind, wenn du auf das Array selbst zugreifst (ich habe hier einfach die Zählervariable genommen, nicht den Arrayinhalt).
#include <Array.au3>
Local $aArray[] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Local $aArray2 = $aArray
; Vorwärtsiteration
For $i = 0 To UBound($aArray) - 1 Step 1
If $i = 1 Or $i = 3 Or $i = 5 Or $i = 7 Or $i = 9 Then _ArrayDelete($aArray, $i)
Next
; Rückwärtsiteration
For $i = UBound($aArray2) - 1 To 0 Step -1
If $i = 1 Or $i = 3 Or $i = 5 Or $i = 7 Or $i = 9 Then _ArrayDelete($aArray2, $i)
Next
_ArrayDisplay($aArray, "Vorwärts")
_ArrayDisplay($aArray2, "Rückwärts");
Alles anzeigen
Vorwärtsiterationen klappen gut wenn du die Anzahl an Löschungen merkst und sie bei den nächsten Indizes abziehst, um das `Nachrutschen´ zu verhindern.
Ganz einfach, lauf das Array rückwärts durch.