Автоматизировать расположение нескольких дисплеев в Windows 10

377
kftb

Я работаю в офисе открытого типа с внешними мониторами на каждом рабочем месте. У меня нет установленного рабочего пространства, поэтому каждый раз, когда я подключаюсь к новому экрану внешнего монитора, по умолчанию открываются два экрана рядом друг с другом. Я работаю исключительно в режиме, когда два экрана располагаются друг над другом в окне расположения.

Можно ли каким-либо образом автоматизировать устройство в Windows 10, например, если я подключу новый монитор для запуска быстрой пакетной команды для установки устройства?

Я знаю, что это всего лишь около 3 кликов, если делать регулярно, но это раздражает, если это происходит каждый день.

Спасибо!

2

1 ответ на вопрос

1
motosubatsu

Вы можете сделать это с PowerShell. Сначала создайте скрипт Powershell под названием «MoveScreens.ps1» и скопируйте и вставьте следующий код в:

Function Set-ScreenPosition {  param (  [Parameter(Mandatory=$true,  Position = 0)]  [int]  $x,  [Parameter(Mandatory=$true,  Position = 1)]  [int]  $y  )  $pinvokeCode = @"  using System;  using System.Runtime.InteropServices;  namespace Mover {  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct DEVMODE { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName;  public short dmSpecVersion; public short dmDriverVersion; public short dmSize; public short dmDriverExtra; public int dmFields; public int dmPositionX; public int dmPositionY; public int dmDisplayOrientation; public int dmDisplayFixedOutput; public short dmColor; public short dmDuplex; public short dmYResolution; public short dmTTOption; public short dmCollate;  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmFormName;  public short dmLogPixels; public short dmBitsPerPel; public int dmPelsWidth; public int dmPelsHeight; public int dmDisplayFlags; public int dmDisplayFrequency; public int dmICMMethod; public int dmICMIntent; public int dmMediaType; public int dmDitherType; public int dmReserved1; public int dmReserved2; public int dmPanningWidth; public int dmPanningHeight; }; public class NativeMethods { // PInvoke declaration for EnumDisplaySettings Win32 API [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);  // PInvoke declaration for ChangeDisplaySettings Win32 API [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern int ChangeDisplaySettings(ref DEVMODE lpDevMode, int dwFlags);   // constants public const int ENUM_CURRENT_SETTINGS = -1; public const int CDS_UPDATEREGISTRY = 0x01; public const int CDS_TEST = 0x02; public const int DISP_CHANGE_SUCCESSFUL = 0; public const int DISP_CHANGE_RESTART = 1; public const int DISP_CHANGE_FAILED = -1;    public static DEVMODE CreateDevmode() { DEVMODE dm = new DEVMODE(); dm.dmDeviceName = new String(new char[32]); dm.dmFormName = new String(new char[32]); dm.dmSize = (short)Marshal.SizeOf(dm); return dm; } }    public class PrimaryScreenPosition {  static public string ChangePosition(int x, int y)  {  DEVMODE dm = CreateDevmode();  if (0 != NativeMethods.EnumDisplaySettings(@"\\.\DISPLAY1", NativeMethods.ENUM_CURRENT_SETTINGS, ref dm))  {  dm.dmPositionX = x; dm.dmPositionY = y;  int iRet = NativeMethods.ChangeDisplaySettings(ref dm, NativeMethods.CDS_TEST);  if (iRet == NativeMethods.DISP_CHANGE_FAILED)  {  return "Unable To Process Your Request. Sorry For This Inconvenience.";  }  else  {  iRet = NativeMethods.ChangeDisplaySettings(ref dm, 0);  switch (iRet)  {  case NativeMethods.DISP_CHANGE_SUCCESSFUL:  {  return "Success";  }  case NativeMethods.DISP_CHANGE_RESTART:  {  return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode.";  }  default:  {  return "Failed To Change The Position";  }  }  }  }  else  {  return "Failed To Change The Position.";  }  }  private static DEVMODE1 GetDevMode1()  {  DEVMODE1 dm = new DEVMODE1();  dm.dmDeviceName = new String(new char[32]);  dm.dmFormName = new String(new char[32]);  dm.dmSize = (short)Marshal.SizeOf(dm);  return dm;  }  }  }  "@  Add-Type $pinvokeCode -ErrorAction SilentlyContinue  [Resolution.PrmaryScreenPosition]::ChangePosition($x,$y)  } 

Затем создайте другой сценарий для запуска описанного выше кода следующим образом (числа - это ширина и высота вашего второго экрана, и, очевидно, вам нужно обновить путь к тому месту, куда вы поместили первый сценарий!):

.\C:\Temp\MoveScreeens.ps1 Set-ScreenPosition 1920 1080 

Тогда вам просто нужно запустить второй скрипт, и он должен сложить экраны для вас с основным существом внизу.

Предупреждение: это может не работать в зависимости от настроек выполнения скрипта на машине, если вы столкнетесь с этим, вам нужно запустить скрипт с включенным соответствующим параметром:

PowerShell.exe -ExecutionPolicy Bypass -File .\MoveScreens_Stack.ps1 

Еще одна оговорка: в этом сценарии предполагается, что мониторы расположены горизонтально, а левый дисплей - № 1. Если они находятся в другом расположении (например, уже в вертикальном расположении), то, скорее всего, возникнет странность!

Похожие вопросы