Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to position a window when starting a process with PowerShell (Start-Process)?

Tags:

powershell

I'm running the command as follows.

Start-Process dotnet -ArgumentList "run"

The window can be managed using -WindowStyle flag to be maximized, minimized, hidden and normal. However, what I usually do is to push the frame to the left (and the second to the right).

Is it possible to tell PowerShell to float the window to the edge? Something like this wishful pseudo-code?

Start-Process dotnet -ArgumentList "run" -WindowStyle FloatLeft
like image 942
Konrad Viltersten Avatar asked Dec 19 '16 19:12

Konrad Viltersten


1 Answers

Try this, which uses the -Passthru option for Start-Process to get the process info. Then, we use a bit of pInvoke magic to move the window we've just created to somewhere else.

This example will enable you to snap the spawned window to the edges of the windows current screen. You can specify X or Y edges, or both. Top, Left wins if all 4 switches are specified.

Add-Type -AssemblyName System.Windows.Forms

Add-Type @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

public struct RECT
{
    public int left;
    public int top;
    public int right;
    public int bottom;
}

public class pInvoke
{
    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, ExactSpelling = true, SetLastError = true)]
    public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);
}
"@

function Move-Window([System.IntPtr]$WindowHandle, [switch]$Top, [switch]$Bottom, [switch]$Left, [switch]$Right) {
  # get the window bounds
  $rect = New-Object RECT
  [pInvoke]::GetWindowRect($WindowHandle, [ref]$rect)

  # get which screen the app has been spawned into
  $activeScreen = [System.Windows.Forms.Screen]::FromHandle($WindowHandle).Bounds

  if ($Top) { # if top used, snap to top of screen
    $posY = $activeScreen.Top
  } elseif ($Bottom) { # if bottom used, snap to bottom of screen
    $posY = $activeScreen.Bottom - ($rect.bottom - $rect.top)
  } else { # if neither, snap to current position of the window
    $posY = $rect.top
  }

  if ($Left) { # if left used, snap to left of screen
    $posX = $activeScreen.Left
  } elseif ($Right) { # if right used, snap to right of screen
    $posX = $activeScreen.Right - ($rect.right - $rect.left)
  } else { # if neither, snap to current position of the window
    $posX = $rect.left
  }

  [pInvoke]::MoveWindow($app.MainWindowHandle, $posX, $posY, $rect.right - $rect.left, $rect.bottom - $rect.top, $true)
}

# spawn the window and return the window object
$app = Start-Process dotnet -ArgumentList "run" -PassThru

Move-Window -WindowHandle $app.MainWindowHandle -Bottom -Left
like image 94
TechSpud Avatar answered Oct 21 '22 11:10

TechSpud