Anwendungen automatisch an bestimmte Monitorposition mit definierter Größe öffnen

  • Hallo zusammen,

    ich plane für demnächst einen kleinen "Anwendungs Starter" der folgendes können soll.

    Da ich bald mit 5 Monitoren arbeiten werde und aktuell jeden Tag mindestes 16 Anwendungen parallel starten muss und diese aktuell von Hand auf die jeweiligen Monitore verschiebe, möchte ich mir das in Zukunft einfacher machen.

    Der "Anwendungs Starter" soll ..

    • automatisch alle 16 Anwendungen starten (das bekomme ich hin)
    • die jeweilige Anwendung auf einen bestimmten Monitor ziehen
    • dort dann die Anwendung links oben und rechts unten auf eine definierte Größe aufziehen

    Ich denke mit einem MouseClickDrag kann man hier vermutlich was bewegen, jedoch wollte ich fragen, ob es vielleicht einen schickeren Lösungsansatz gibt. Vielleicht irgendwas, dass die Anwendung optisch da gleich richtig erscheint und nicht erst lange wie von Geisterhand durch die Monitore gezogen werden muss.

    Danke für eure Vorschläge.

  • Meiner Meinung nach, wäre WinMove() die bessere Wahl.

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Jupp seh ich auch so. Mit WinGetPos() kannst du die Position und Größe der Fenster ermitteln wenn du sie von Hand positionierst. Die ermittelten Infos kannst du dann nutzen um die Fenster zukünftig immer gleich mit winmove() zu positionieren.

    Die einzige Schwierigkeit hierbei ist, dass die Fenster nicht sofort existieren wenn der Prozess von dir gestartet wurde. Je nach Anwendung kann der Startvorgang mehrere Sekunden benötigen. Du solltest dir also auch noch die Funktionen winexists() oder winwait() ansehen. Aber selbst dann kann es bei bestimmten Anwendungen vorkommen, dass das Fenster zwar früh erzeugt wird und existiert, aber zunächst unsichtbar ist und später im Startvorgang durch die Anwendung nochmals neu positioniert und sichtbar gemacht wird, dies kann auch mit dem Titel des Fensters passieren, welcher evtl. erst später gesetzt oder geändert wird.

    Um solche Timing Probleme zu vermeiden bzw. zu korrigieren solltest du die neue Zielposition nochmals am Ende des Scriptes nach kurzer Wartezeit für alle Fenster mit WinGetPos() überprüfen und ggf. eine erneute Positionierung durchführen wenn dies zuvor nicht erfolgreich war.

  • Hallo zusammen,

    bin mit den ersten 3 Anwendungen schon gut am laufen, aber meine 4. Anwendung macht mir Probleme. Es handel sich um die Desktop Version von Telegram.

    Meine ganzen Koordinaten bestimme ich mit "AutoIt v3 Windows Info".

    Leider arbeitet mein WinMove hier nicht

    Code: Code für Telegram
    $iPID_W_04 = Run("C:\Users\Name\AppData\Roaming\Telegram Desktop\Telegram.exe") ; starte Telegram
    Local $hWnd04 = WinWaitActive("[TITLE:Telegram]", "", 20) ; Wartet maximal 20 Sekunden bis Telegram erscheint.
    If WinActive("[TITLE:Telegram]") Then; wenn das Telegram Fenster aktiv ist
        Send("1234{ENTER}"); schreibe den Login und drücke ENTER
        WinMove($hWnd04, "", -840, 34, 840, 626) ; Verschiebt Telegram auf die X-Position von -840 und Y-Position von 34 und setzt die Höhe auf 840 und Breite auf 626
    EndIf

    Habt Ihr da eine Idee?

  • Teste das mal so...

    3 Mal editiert, zuletzt von Bitnugger (27. März 2019 um 16:28) aus folgendem Grund: Zeile 7 korrigiert: IsHWnd($iWait) --> IsHWnd($hWnd04)

  • Also das Telegram Fenster startet, aber zur Eingabe des Kennwort kommt es mit dem Script aktuell nicht.

    Code: Ausgabe vom Output Fenster
    ! Error: 4 Fehler bei WinWaitActive! 
    @@ ScriptLineNumber(232) : <-- Mache einen Doppelklick auf diese Zeile, wenn SciTE zu dieser Zeile springen soll! !
    >16:08:07 AutoIt3.exe ended.rc:4
  • Ich Depp... ändere mal die Zeile...

    If Not IsHWnd($iWait) Then _ErrExit(4, 'Fehler bei WinWaitActive!')

    in...

    If Not IsHWnd($hWnd04) Then _ErrExit(4, 'Fehler bei WinWaitActive!')

  • Also die Lösung von Bitnugger scheint oft zu gehen, aber leider nicht immer. Auch habe ich den WinTitleMatchMode auf 4 gestellt.

    Hier ein Problem mit Lotus Notes

    Code von Lotus Notes

    Das Script geht in Zeile 26 definitiv in den IF Bereich rein (sehe ich ja anhand der Consolen Ausgabe), aber der WinMove geht nicht. Lotus Notes bleibt immer in der Größe, wie es zuvor geschlossen wurde.

    Hier mal die Ausgabe vom aktuellen Windows Info

    Aktuelle Werte von Windows Info

    Ich habe auch mal gehört, das manche Anwendungen sich die letzte Position merken. Wie ist das denn abgelegt, bzw. wie kann man das manipulieren?

    Danke für eure Hilfe

    Nachtrag um 15:54 Uhr: mit Outlook ist es genau das gleiche. Da moved rein gar nichts.

    Einmal editiert, zuletzt von Code4Fun (28. März 2019 um 15:54)

  • Noch eine kleine Frage nebenbei. Wie bilde ich Autoit den die Tastenkombination "gedrückte linke Windows Taste + z.B. Pfeiltaste 1x nach oben drücken" ab.

    Das hier

    Code
    Send("{LWIN down}{UP}") ;

    geht irgendwie nicht. Es öffnet sich hier das Windows Menü. Ich dachte ich hole mir vorher nochmals von Lotus Notes den Focus, aber irgendwie will das nicht

    Code
    If $sLocation = "GP" Then ; wenn Du im Homeoffice bist, sind dies die Koordinaten der Anwendung
                Sleep(20000)
                ConsoleWrite("Warten fertig" & @CRLF)
                WinActivate($hApp) ; nochmals sicher stellen, dass das Fenster von Lotus Notes den Focus hat
                Send("{LWIN down}{UP}") ; halt die linke Windows Taste gedrückt und klicke 1 mal die Pfeiltaste nach oben
    ;~             Send("{LWIN down}{RIGHT}") ; halt die linke Windows Taste gedrückt und klicke 1 mal die Pfeiltaste nach oben
                Send("{LWIN up}") ; lass die linke Windows Taste wieder los.
    ;~             WinMove($hApp, "", $iX, $iY, $iW, $iH) ; Verschiebt die Anwendung an obige Koordinaten
            Else ; ansonsten sind dies die Koordinaten der Anwendung

    Einmal editiert, zuletzt von Code4Fun (28. März 2019 um 15:24)

  • Teste es mal so...

    Das hier

    Send("{LWIN down}{UP}") ;

    geht irgendwie nicht. Es öffnet sich hier das Windows Menü. Ich dachte ich hole mir vorher nochmals von Lotus Notes den Focus, aber irgendwie will das nicht

    Durch das "down" bleibt LWIN gedrückt, solange kein {"LWIN up"} gesendet wird... das willst du aber gar nicht, deshalb einfach das "down" weglassen.

    Für dein Vorhaben ist die Verwendung von Send eh absolut an keiner Stelle sinnvoll...

    Einmal editiert, zuletzt von Bitnugger (29. März 2019 um 14:45)

  • Hallo Bitnugger,

    dein Script fliegt hier raus If Not IsHWnd($hWnd) Then _ErrExit(4, 'Fehler bei WinWaitActive!') ; Fehlermeldung wird erzeugt, somit kann ich die beiden Handles noch nicht vergleichen. Oder macht es Sinn die Consolenausgabe zwischen Until und If Zeile zu setzen.

    Wegen den gleichen Koordinaten. Da habe ich ja geschrieben Else ; ansonsten sind dies die Koordinaten der Anwendung (Achtung: müssen vor Ort noch geprüft werden). Ich scripte gerade an meinem Arbeitsplatz zu Hause und muss dann am anderen Arbeitsplatz erst mal die anderen Koordinaten ermitteln.

    Zu Deiner Aussage

    Zitat

    Für dein Vorhaben ist die Verwendung von Send eh absolut an keiner Stelle sinnvoll...

    muss ich folgends sagen. Ich gebe Dir da im prinzip recht, aber Du kennst ja sicherlich die Windows Tastenkombinationen "WinTaste" + Pfeiltasten, womit man die Fenster wunderbar auf den Monitoren positionieren kann, wenn man Sie im Verhältnis 1:4 1:2 oder 1:1 haben möchte. Dafür war der Gedankengang mit dem Send Befehl.

    Nachtrag um 15:11 Uhr.

    Ich habe jetzt eine weitere Anwendung, die sich nicht verschieben lässt. Habe jetzt den Handle via Console ausgeben lassen, als das Script noch gelaufen ist. Der Wert war 0x00000000001F0E96. Nachdem das Script beendet war habe ich die Anwendung mit dem Windows Info Tool gegen gecheckt. Hier ist der Handle 0x00000000001C1196. Ist das normal, dass sich der Handle ändert?

    Einmal editiert, zuletzt von Code4Fun (29. März 2019 um 15:14)

  • dein Script fliegt hier raus If Not IsHWnd($hWnd) Then _ErrExit(4, 'Fehler bei WinWaitActive!') ; Fehlermeldung wird erzeugt, somit kann ich die beiden Handles noch nicht vergleichen.

    In dem Fall gibt es keine zwei Handles weil keines gefunden wurde... und somit auch nichts zu vergleichen. Eine Ausgabe von $hWnd mit ConsoleWrite bringt dann auch nicht mehr Erleuchtung.

    Ich sehe aber, das ich wieder mal einen blöden Fehler eingebaut habe... ändere folgende Zeile um...

    $hWnd = WinWaitActive("[TITLE:IBM Notes Arbeitsbereich: CLASS:SWT_Window0]", "", 1) ; Wartet maximal 1 Sekunde

    zu...

    $hWnd = WinWaitActive("[TITLE:IBM Notes Arbeitsbereich; CLASS:SWT_Window0]", "", 1) ; Wartet maximal 1 Sekunde

    oder so, wenn das auch nicht geht...

    $hWnd = WinWaitActive("[REGEXPTITLE:^(IBM Notes.+); CLASS:SWT_Window0]", "", 1) ; Wartet maximal 1 Sekunde

    Du kennst ja sicherlich die Windows Tastenkombinationen "WinTaste" + Pfeiltasten

    Ja ok, das macht allerdings Sinn.

  • Cool, die 2. Variante mit dem ";" hat funktioniert. Kannst Du mir, bzw. den Mitlesern mal erklären, was hier genau passiert

    $hWnd = WinWaitActive("[TITLE:IBM Notes Arbeitsbereich; CLASS:SWT_Window0]", "", 1) ; Wartet maximal 1 Sekunde

    Wird hier entweder auf das erscheinen des Titles UND / ODER auf die Klasse gewartet?

  • Wird hier entweder auf das erscheinen des Titles UND / ODER auf die Klasse gewartet?

    Das lässt sich leicht testen... indem du einmal einen falschen Titel und einmal eine falsche Klasse angibst...

    ConsoleWrite(WinGetHandle('[TITLE:M:\Test.au3; CLASS:SciTEWindow]') & @CRLF)

    ConsoleWrite(WinGetHandle('[TITLE:Z:\Test.au3; CLASS:SciTEWindow]') & @CRLF)

    ConsoleWrite(WinGetHandle('[TITLE:M:\Test.au3; CLASS:XWindow]') & @CRLF)

    Ausgabe:

    0x00041070

    0x00000000

    0x00000000

    Fazit: Alle angegebenen Kriterien müssen zutreffen.

    In der AutoIt-Hilfe findest du dazu Infos unter Using AutoIt --> Window Titles and Text (Advanced)

    Auszug:

    One or more properties are used in the title parameter of a window command in the format:

    [PROPERTY1:Value1; PROPERTY2:Value2]

  • Danke Bitnugger für die Erklärung.

    Jetzt habe ich aber noch ein anderes kleines Problem. Ich muss aber zugeben, das ich bisher mit While ... Wend noch nicht bewußt gearbeitet habe.
    In meinem Script habe ich eine Funktion, welche kurz vor Feierabend (natürlich manuell ausgelöst) viele meiner manuell gestarteten Anwendungen beendet.
    Ich habe jetzt 2 Anwendungen, die beide CSBridge.exe heißen, jedoch aus 2 unterschiedlichen Verzeichnissen gestartet wurden.

    Zuerst hatte ich nur die Zeile ProcessClose("CSBridge.exe"), welche aber nur eine Instanz beendet hat.

    Danach habe ich den Aufruf 2x gestartet, was aber auch nicht immer geholfen hat.

    Jetzt möchte ich das gerne mit einer Schleife lösen, aber irgendwas mache ich noch falsch, da die Schleife gar nicht abgearbeitet wird.

    Ich denke mein Aufruf While $iPID NOT 0 stimmt noch nicht ganz.

    Was mache ich hier falsch?

    Code
    Func _KILL()
            Local $iPID
            ConsoleWrite("die $iPID ist aktuell: " & $iPID & @CRLF)
            While $iPID NOT 0
                $iPID = ProcessExists("CSBridge.exe")
                ConsoleWrite("die $iPID ist aktuell: " & $iPID & @CRLF)
                ProcessClose("CSBridge.exe")
                ConsoleWrite("die $iPID ist aktuell: " & $iPID & @CRLF)
            WEnd
    EndFunc

    Vielen Dank

  • Hi

    deine Kill() hat doch anfänglich noch gar keine $iPID! Mußt du doch erst mit ProcessExist abfragen.

    Kannst doch im Task Manager prüfen.

    Mach doch so...

    While ProcessExists("CSBridge.exe")

    $iPID = ProcessExists("CSBridge.exe")

    ProcessClose($iPID)

    ProcessWaitClose($iPID)

    WEnd

  • Oder so...

    Code
    Func _KILL()
        Local $aProcessList = ProcessList("CSBridge.exe")
        If @error Then Return False
        For $i = 1 To $aProcessList[0][0] Step 1
            ProcessClose($aProcessList[$i][1])
        Next
        Return True
    EndFunc