How can a batch file run a program and set the position and size of the window?

前端 未结 6 762
半阙折子戏
半阙折子戏 2020-11-28 06:18

I have batch file that sets up the desktop environment for me when I am writing code. The file is named: SetEnv.cmd and it opens 3 other windows:

6条回答
  •  生来不讨喜
    2020-11-28 06:50

    Following method can be useful for new users who doesn't want to download third-party tools and have modern PowerShell (PS).

    Script was based on post by Garry Galler. All folders from question, but you can replace with yours.

    Create file SetPositionAndSizeForExplorerWindow.ps1 with PS script:

    # PowerShell script for opening Explorer windows and changing its position and size
    
    # add .NET type
    Add-Type @"
      using System;
      using System.Runtime.InteropServices;
      public class Win32 {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string ClassName, IntPtr  TitleApp);
      }
      public struct RECT
      {
        public int Left;        // x position of upper-left corner
        public int Top;         // y position of upper-left corner
        public int Right;       // x position of lower-right corner
        public int Bottom;      // y position of lower-right corner
      }
    "@
    
    # set variable for RECT object
    $rcWindow = New-Object RECT
    
    #----- REPLACE WITH YOUR PATHs from HERE---------
    
    # open first folder in separate Explorer process
    explorer.exe "c:\develop\jboss-4.2.3.GA\server\default\deploy"
    
    # magic sleep =) to wait starting explorer on slow machines
    sleep -Milliseconds 1500
    
    $h1 = (Get-Process | where {$_.mainWindowTitle -match "deploy"}).MainWindowHandle
    
    # check if there is a window with this Title, if NO - return
    if ($h1 -eq [IntPtr]::Zero) {return "Cannot find window with this Title"}
    
    # bind RECT object with our window
    [void][Win32]::GetWindowRect($h1,[ref]$rcWindow)
    # set new position and size for window 
    [void][Win32]::MoveWindow($h1, 10, 10, 700, 345, $true)
    
    # remember PID to exclude it for next window with the same name
    $duplicate = (Get-Process | where {$_.mainWindowTitle -match "deploy"}).Id
    
    # open second folder in separate Explorer process
    explorer.exe "c:\develop\Project\Mapping\deploy"
    sleep -Milliseconds 1500
    $h1 = (Get-Process | where {$_.mainWindowTitle -match "deploy" -and $_.Id -ne $duplicate}).MainWindowHandle
    if ($h1 -eq [IntPtr]::Zero) {return "Cannot find window with this Title"}
    [void][Win32]::GetWindowRect($h1,[ref]$rcWindow)
    [void][Win32]::MoveWindow($h1, 400, 20, 700, 335, $true)
    
    # open cmd window with title SetupEnvCmd.cmd
    cmd /c "start C:\develop\jboss-4.2.3.GA\bin\SetupEnvCmd.cmd"
    sleep -Milliseconds 1500
    # cmd.exe process has no own title, that's why we get PID searching by CommandLine process property
    $process = "cmd.exe"
    $cmdPID = Get-CimInstance Win32_Process -Filter "name = '$process'" | where {$_.CommandLine -match "SetupEnvCmd"} | select ProcessId
    $h1 = (Get-Process | where {$_.Id -eq $cmdPID.ProcessId}).MainWindowHandle
    if ($h1 -eq [IntPtr]::Zero) {return "Cannot find window with this Title"}
    [void][Win32]::GetWindowRect($h1,[ref]$rcWindow)
    [void][Win32]::MoveWindow($h1, 200, 400, 800, 400, $true)
    

    Move it to C:\develop folder. Create OpenDevelopEnv.bat file to run this .ps1 script (in order not to delve into security policy of PS):

    Powershell -executionpolicy RemoteSigned -File "C:\develop\SetPositionAndSizeForExplorerWindow.ps1"
    

    Run OpenDevelopEnv.bat

    For multi-display configuration you can use negative coordinates, for instance: for opening window on left display (relative to the main) you can write:

    [void][Win32]::MoveWindow($h1, -600, 400, 800, 400, $true)
    

    Disadvantages:

    • PowerShell must be installed;
    • required windows must be closed;
    • folders starts in separate processes;
    • using of sleep time for correct work on slow machines.

    Tested on: Windows 10 Pro 1803 x64/x86 with PSVersion 5.1 (administrator and regular users)

提交回复
热议问题