Per Batch ein Fenster öffnen und Fokussieren?
Hallo, Ich bin momentan ein Skript am machen indem ich durch ein einfaches Auswahl Menu Softwaren installiere und Einstellung an Windows ändere. Mein Problem ist nur das ich mit den so genannten fsShell.SendKeys von VBS Dateien arbeite. Wenn ich jetzt ein Fenster von meiner Batch öffnen lasse, dann wird dieses Fenster meist nicht als angeklicktes Fenster anerkannt. Das bedeutet das wenn ich das Fenster vor mir habe weder mit den Pfeiltasten noch mit der Enter taste navigieren kann. Gibt es da eine Möglichkeit das ich das Fenster öffne und direkt als ausgewählte Fenster habe?
LG
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:
- http://www.pinvoke.net/default.aspx/user32.SetForegroundwindow
- https://shlomio.wordpress.com/2012/09/04/solved-setforegroundwindow-win32-api-not-always-works/
- https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow#remarks
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.
Wenn Du die von Senders meinst:
Nicht vergessen: In Batch haben % besondere Bedeutung und müssen als Text verdoppelt werden.
Beim ^ hängt es davon ab, ob es innerhalb von Gänsefüßchen eingesetzt wird oder nicht... außerhalb muss es verdoppelt werden ^^ um als Textzeichen angesehen zu werden.
Kann Mann auch Mauseingaben in ein Script einbauen? So wie z.b. klicke dort...?
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);^"
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.
- https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mouse_event
- Die Positionsparameter dx,dy,dwData,dwExtraInfo sind unerheblich für Klickevents (bleiben einfach alle 0)
- Klickevents können addiert werden 2+4=6=Linksklick etc.
LEFTDOWN = 2
LEFTUP = 4
RIGHTDOWN = 8
RIGHTUP = 16
MIDDLEDOWN= 32
MIDDLEUP = 64
Hast du zufälliger weise eine Seite mit Docs über die Keys?