2

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

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

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

Спасибо!

1 ответ1

2

Вы можете сделать это с 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. Если они находятся в другом расположении (например, уже в вертикальном расположении), то, скорее всего, возникнет странность!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .