Per Batch ein Fenster öffnen und Fokussieren?

1 Antwort

Hast Du dem Fenster auch Zeit gelassen sich zu öffnen bevor Du die Tasten sendest? (ansonsten sind die Tasten bereits durch bevor das Fenster aufgebaut ist. ) Zudem sollte vor jedem Block von zu sendenden Zeichen das entsprechende Fenster über seinen Titel aktiv gesetzt werden. Das klapp nicht mehr uneingeschränkt... dazu später....

demo. cmd

@echo off
  rem zur Demo:
  rem erzeuge  eine leere Textdatei 
(call)>"meine Datei.txt"
  rem öffne Diese im Notepad
start "" notepad "meine Datei.txt"
  rem Title des Zielfensters
set "WindowNameToActivate=meine Datei.txt - Editor"


  rem kleines JScript, welches in der Kommandozeile übergebene Zeichenfolgen  an ein  Fenster mit der zuvor festgelegten Überschrift sendet...
  rem .AppActivate  funktioniert (seit Vista) nur noch, wenn das Fenster bereits im fordergrund  ist!  
echo WScript.Sleep(10);var t='';for (var i = 0; i ^< WScript.Arguments.Length;i++){t=t+WScript.Arguments(i)} ;WshShell=new ActiveXObject("WScript.shell");WshShell.AppActivate('%WindowNameToActivate%');WshShell.Sendkeys(t) >"%temp%\sendkey.js"
  rem makro erzeugen (eleichtert den Aufruf)
set "sendKeys=cscript /nologo "%temp%\sendkey.js" "


  rem Wichtig!!! etwas Zeit zum öffnen geben
timeout 1 >nul


%sendKeys% "1|0|c|d|efghijklmnopqrstuvwxyz" {Enter} "blu mup" {Enter} mmahhhh murks
  rem weiterschreiben
%sendKeys% {Enter} "Weiter geht's"{Enter}
  rem mal ein paar Zeiln füllen damit wir  etwas "Fleisch"  zum Scrollen  bekommen
for /l %%a in (1,1,100) do  %sendKeys%  "%%a Mississippi" {Enter}
  rem 2 sekunden Luft holen...
timeout 2 >nul
%sendKeys% " " "...das war ein Space Weiter geht's"{Enter} 


  rem lass uns 5 mal Deine  PGUP-Taste senden
for /l %%a in (1,1,5) do %sendKeys% {PGUP}
  rem und  etwas  schreiben 
%sendKeys% "  Hallo ich habe  automatisch gescrolt"{Enter}
%sendKeys% " " "...das war ein Space Weiter geht's"{Enter} 


  rem Speichern? ( achtung in Batch  müssen %-Zeichen ,die als Textzeichen verwendet werden sollen, verdoppelt werden)
%sendKeys% %%{F4}
echo alles gesendet....
pause

Die Demo ist natürlich Spielerei. Kein vernünftiger Programmierer würde dergleichen tun. (kommt gleich nach rektaler Augenoperation)

vbs/js wird schon lange nicht mehr von Microsoft supported.

Seit dem hat sich das System weiterentwickelt. ...aber VBS ist geblieben, wie es der letzte Stand unter WinXP war. Das vieles nachwievor funktioniert grenzt fast an ein Wunder.

.AppActivate funktioniert nicht mehr uneingeschränkt...

Aber auch in Sprachen ist das fokussieren eines Fensters nicht unbedingt vom Erfolg gekrönt:

Wenn man nach showwindow not working sucht, kommt jede Menge Gejammer zum Vorschein. Tatsächlich sind das aber alles Anfänger mit irgendwelchen falschen Programmkonzepten.

Es gibt keinen wirklichen Grund ein fremdes Fenster in den Vordergrund zu holen. (Außer man kennt keine anderen Möglichkeiten , als mit sendkey ein fremdes GUI zu bedienen.) Mal davon abgesehen könnte zwischendurch ein anderer Prozess sich zwischendurch den Focus "schnappen" und dann gehen all die Tastendrücke ganz wo anders hin, was u.U. auch böse ins Auge gehen kann.

Also lass solche Pfrimelei.

Die meisten Installer verfügen über ein Kommandozeileninterface, damit Administratoren auch per Script eine Silentinstallation ausführen können.

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
Tilomaster  05.12.2022, 21:27

Kann Mann auch Mauseingaben in ein Script einbauen? So wie z.b. klicke dort...?

0
xSyntachs 
Fragesteller
 06.12.2022, 11:30
@Tilomaster

Ich hatte es so gemacht

set posX=960 

set posy=540

powershell -ExecutionPolicy ByPass -Command ^"^

Add-Type -A System.Windows.Forms;^

Add-Type -Memberdefinition '[DllImport(\"user32.dll\")]public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);' -Namespace Tools -Name Mouse ;^

$pos = new-object System.Drawing.Point %posX%,%posY%;^

[System.Windows.Forms.Cursor]::Position = $pos;^

[Tools.Mouse]::mouse_event(2,$pos.X,$posY,0,0);^

[Tools.Mouse]::mouse_event(4,$pos.X,$posY,0,0);^

sleep 2;^

    [System.Windows.Forms.Cursor]::Position = $pos;^

[Tools.Mouse]::mouse_event(2,$pos.X,$posY,0,0);^

[Tools.Mouse]::mouse_event(4,$pos.X,$posY,0,0);^"

1
Erzesel  06.12.2022, 13:33
@xSyntachs

ja.. kann man machen. 😏

Aber willst Du solch ein Monstrum in Deiner Batch haben? Das geht wesentlich kompakter :

demo.cmd

set posX=960 
set posY=540
powershell "Add-Type -a System.Windows.Forms;Add-Type -m '[DllImport(\"user32.dll\")]public static extern void mouse_event(int dF,int dX,int dY,int dD,int dE);' -ns T -name M;[System.Windows.Forms.Cursor]::Position='%posX%,%posY%';[T.M]::mouse_event(6,0,0,0,0);sleep -m 10;[T.M]::mouse_event(6,0,0,0,0)"

...macht einen Doppelklick auf 960 540.

Das ist aber ziemlich unflexibel man könnte vielleicht auch mal mit den anderen Maustasten klicken wollen oder/und auf verschiedene Stellen? Jedesmal das Monster neu zuschreiben wäre eklig...🤢

Aber man kann ja den Powershell-Einzeiler flexibler gestalten und in eine Batch-Subroutine verlegen (und dort nie wieder anfassen):

@echo off

 rem    L : Linksklick
 rem    R : Rechtsklick
 rem    M : Mittelclick
 rem    LD: Linker Doppelklick
 rem Position 50,30 von der linken oberen Ecke , linker Doppelklick
call :mouseClick 50 30 LD
 rem warte 3 sekunden
timeout 3 >nul
 rem Position 700,500 von der linken oberen Ecke , rechtsKlick
call :mouseClick 700 500 R
pause
exit /b

:mouseClick
powershell "Add-Type -a System.Windows.Forms;Add-Type -m '[DllImport(\"user32.dll\")]public static extern void mouse_event(int dF,int dX,int dY,int dD,int dE);' -ns T -name M;$me={param($e)[T.M]::mouse_event($e,0,0,0,0)};[System.Windows.Forms.Cursor]::Position='%~1,%~2';switch ( '%~3'){'LD'{&$me 6;sleep -m 10;&$me 6; break};'L'{&$me 6;break};'R'{&$me 24 ;break};'M'{&$me 96;break}}"
exit /b

 Das PowershellScript ist maximal "eingedampft" Hier noch mal fein säuberlich:

Demo. ps1

Add-Type -AssemblyName System.Windows.Forms 
Add-Type -Memberdefinition '[DllImport("user32.dll")]public static extern void mouse_event(int dwFlags,int dx,int dy,int dwData,int dwExtraInfo);' -Namespace Tools -Name Mouse

[System.Windows.Forms.Cursor]::Position = '30,30'
$ClickTyp = 'RClick'

  # ach wie gut, das man Zeug das immer wiederkehrt einfach in ein Macro (Scriptblock) legen kann
$mouse_event = { param($dwFlag) [Tools.Mouse]::mouse_event($dwFlag,0,0,0,0)}

switch ($ClickTyp) {
    'LClick'    {   &$mouse_event 6 ; break}
    'RClick'    {   &$mouse_event 24; break}
    'MClick'    {   &$mouse_event 96; break}
    'LDClick'   {     #generiere linken Doppelklick 2 mal in Folge LEFTDOWN+LEFTUP mit einem Abstand von 10 Millisekunden
                    &$mouse_event 6
                    Sleep -m 10
                    &$mouse_event 6 ; break
                }
}
pause

Hier noch ein paar Infos dazu , Du sollst ja auch wissen was da getan wird.

    LEFTDOWN  = 2
    LEFTUP    = 4
    RIGHTDOWN = 8
    RIGHTUP   = 16
    MIDDLEDOWN= 32
    MIDDLEUP  = 64
1
xSyntachs 
Fragesteller
 06.12.2022, 19:47
@Erzesel

Respekt das du so viel weist und dein wissen so freundlich mit jedem teilst :)

0
xSyntachs 
Fragesteller
 08.12.2022, 17:00

Hast du zufälliger weise eine Seite mit Docs über die Keys?

0