In CMD Fenster auf gewisse Größe öffnen?

2 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Für Programme deren übergebene Parameter nicht in eigenen Fenstern ausgeführt werden, sondern als Tabs dargestellt werden, gibt es keine Möglichkeieit das verhalten der Komponenten zu steuern. Fast alle Browser fungieren quasi als eigenes abgeschlossenes System , gleiches gilt auch für den Explorer! dito Notepad++

Die beim Start zurückgegebene ProcessID ist nach wenigen Millisekunden bereits wieder "verworfen". Das gilt auch für Programme wie Calc (ein Wrapper, welcher das eigentliche Programm Calculator startet) oder Programme mit einen Startlogo wie Gimp und diverse Laucher...

Sicher kann man versuchen sich mit einem riesigen Aufwand durch die Hirarchien von Objekten zu hangeln, bis man das Hwnd für das entsprechende Element ermittelt hat. Das wäre dan jedoch kein lustiger Zeitvertreib mehr sondern ein knallhartes Projekt für mehrere Tage... (kennst Du meinen Tagessatz🤑😁?)

Hier eine kleine Demo wie es mit "normalen" Programmen läuft:

<# : Batch Teil  diese Zeile nicht veränden !!!!!!! (Tricky: Versteckt den Batchteil vor dem Powershellskript)
@echo off
chcp 65001 >nul

  rem hier Arbeitsverzeichnis hinter dem Gleichheitszeichen angeben oder leer lassen... 
  rem zb set "workingDir=F:/test"
set "workingDir="
if defined workingDir  cd /d %workingDir%
 
  rem lade die Bildschirmparameter  in die Variable Screen
call :getScreenSize screen
  rem zur Demo mal die eben erzeugten  Variablen anzeigen
set screen


set "MyWnd.Breite=600"
set "MyWnd.Hoehe=400"
  rem berechne Fensterposition von Unten-Rechts
set /a "MyWnd.X=screen.Width - MyWnd.Breite , MyWnd.Y=screen.Height - MyWnd.Hoehe"

  rem Aufruf: call :StartXY XPosition YPosition  Breite Höhe "Zielprogramm"   optional: Parameter "Parameter" ...
  rem Programm aufrufen Parameter 1 und 2 sind die x und y-Posiotion der  linken oberen Fensterecke
  rem Negative Werte für Breite/Höhe beteuten, dass dieser Parameter den Originalwert  beibehält!
        rem rechts unten...
call :StartXY %MyWnd.X% %MyWnd.Y% %MyWnd.Breite% %MyWnd.Hoehe%  Notepad

  rem gleich ein anderes daneben
set /a "neues.X=MyWnd.X-MyWnd.Breite"
call :StartXY %neues.X% %MyWnd.Y% %MyWnd.Breite% %MyWnd.Hoehe%  cmd /k call "echo ich bin das Fenster daneben "

  rem ...und  eins drüber
set /a "neues.Y=MyWnd.Y-MyWnd.Hoehe"
call :StartXY %myWnd.X% %neues.Y% %MyWnd.Breite% %MyWnd.Hoehe%  cmd /k call "echo ich bin das Fenster darüber "
call :StartXY %MyWnd.X% %MyWnd.Y% 
call :StartXY 0 0 400 -1 cmd /k call "echo blubb"
call :StartXY 500 700 300 300 Notepad "test.txt"

pause

  rem ab hier nichts verändern!!!!!!!!!!!!!!!!! (es sei denn, Du weißt was Du tust)
exit /b

:::  subroutines ::::
:StartXY %*=Kommandozeile
if defined workingDir cd /d "%workingDir%"
(for %%I in (%*) do @echo(%%~I)|powershell -noprofile "[Array]$argv = $input|?{$_}; iex (${%~f0}|out-string)"
exit /b

:getScreenSize    %1=Name der Variable, in welcher Breite und Hoehe des Bildschirms gespeichet werden sollen.
  rem  hier  nur  für den Hauptmonitor, reicht für übliche Systeme :þ 
for /f "tokens=1-4 delims=," %%a in ('powershell -nop "Add-Type -a System.Windows.Forms;[system.windows.forms.screen]::PrimaryScreen.Bounds -replace '\{|\}',''; "') do (
    for %%. in ("%%a" "%%b" "%%c"  "%%d") do set "%~1.%%~."
)
exit /b

: end Batch / begin powershell #>
"$argv"
if (!($argv[3] -as [int])) {
'Parameter sind Falsch';
exit
}

  #definiere Funktion zum verschieben des Fensters
Function Set-WindowPos( $WindowHandle,[int]$X,[int]$Y,[int]$Width,[int]$Height) {
      #erstelle virtuelle Bibliothek für nötige PInvoke-Funktionen in C#
    Add-Type @"
        using System;
        using System.Runtime.InteropServices;
        public class PosWnd {
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

            [DllImport("User32.dll")]
             public extern static bool MoveWindow(IntPtr handle, int x, int y, int width, int height, bool redraw);
        }
        public struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }
"@

    $Rectangle = New-Object RECT;
    $Return = [PosWnd]::GetWindowRect($WindowHandle,[ref]$Rectangle);
    $currentWidth = $Rectangle.Right - $Rectangle.Left;
    $currentHeight = $Rectangle.Bottom - $Rectangle.Top;
      #da negetive Größen physisch onhnehin nicht möglich sind, nutze ich diese als Flag und belasse die Originalgröße
    if ($Width -ge 0) { $currentWidth=$Width};
    if ($Height -ge 0) {$currentHeight=$Height};
    if ($Return) {
        $Return = [PosWnd]::MoveWindow($WindowHandle, $x, $y, $currentWidth, $currentHeight, $True);
    }
};
  #Powershell Hauptprogramm

  # von  der Batch übergebene Argumente für Start-Process anpassen...
$MyProcess=$argv[4];
$ArgumentList=$argv|select -skip 5|%{
      #finde alle Zeichen, welche ohne Quotes in Batch als Sonder-/Trennzeichen wirken
    if ($_.trim() -match '[\&\|\<\>=;,\t]') {
        '"{0}"' -f $_.trim(); #Start-Process erwartet Argumente mit Sonder-/Trennzeichen in "".
    }else{$_.trim()};
};

if (!$ArgumentList) {$ArgumentList+=' ' }; # die Argumentliste daf  nicht $Null sein
$proc=Start-Process -filepath $MyProcess -ArgumentList $ArgumentList -PassThru; #Prozes starten
$TimeOut=5000;  # Warte maximal 5000 Milliekunden (für Programme, welche extrem lange starten, diesen Wert erhöhen)
do{
    sleep -Milliseconds 1;
    $WHandle=(Get-Process -ID $proc.id).mainwindowhandle; #Fensterhandle für den gestarteten Prozess ermittel
    $TOut+=1;
} while($WHandle -eq 0 -and $TOut -lt $TimeOut);  #Maximal $TimeOut Millisekunden die Schleife laufen lassen, wenn bis dahin kein Windowhandle bekannt ist, bleibt das Fenster wo es ist!
  # verschiebe das Fenster...
Set-WindowPos $WHandle $argv[0] $argv[1] $argv[2] $argv[3];

Ich habe das Script versucht so zu gestalte, das ein Nachnutzer einfach die gekennzeichneten Bereiche in Frieden lassen kann, und sich im Batchbereich nach herzenslust austoben kann.

Das sieht zwar nach "viel" aus, aber Vieles ist einfach nur Kommentar und Narrensichermachen. Damit man eben Nicht im Wirksamen Code herumwursteln muss.

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren
AnonymerFrosch 
Fragesteller
 14.12.2020, 17:18

Danke, ist nicht ganz das was ich gesucht habe da in meinen Beispiel konkret 4 mal Chrome mit ner gewissen URL geöffnet werden. Aber ich weiß jetzt das ich es nicht mit cmd bzw Power Shell machen kann. Vielleicht Java oder Python muss ich mir mal anschauen.

0