在 Windows 10 中自动排列多个显示器

在 Windows 10 中自动排列多个显示器

我在开放式办公室工作,每个工作空间都有外接显示器。我没有固定的工作空间,所以每次连接到新的外接显示器屏幕时,我都会默认打开两个并排的屏幕。我只在排列窗口中以两个屏幕相互叠放的模式工作。

有什么方法可以让我自动完成 Windows 10 中的排列,例如,如果我连接一个新显示器来运行快速批处理命令来设置排列?

我知道如果定期进行的话只需点击 3 次,但如果每天都发生这种情况就会很烦人。

谢谢!

答案1

您可以使用 PowerShell 执行此操作。首先创建一个名为“MoveScreens.ps1”的 Powershell 脚本,然后复制并粘贴以下代码:

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
  { 
    public static string ChangePosition(int x, int y) 
    { 
        DEVMODE dm = NativeMethods.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."; 
        } 
    } 

  } 
} 
"@ 
Add-Type $pinvokeCode -ErrorAction SilentlyContinue
[Mover.PrimaryScreenPosition]::ChangePosition($x,$y) 
}

然后创建另一个脚本来运行上述代码(数字分别是第二个屏幕的宽度和高度,显然您需要更新放置第一个脚本的路径!):

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

然后您只需运行第二个脚本,它就会为您堆叠屏幕,主屏幕位于底部。

警告:根据机器上的脚本执行设置,这可能不起作用,如果遇到这种情况,则需要在启用适当设置的情况下运行脚本:

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

另一个警告:此脚本假设显示器水平排列,左侧显示器为 #1。如果它们采用不同的排列方式(例如已经垂直排列)则可能会出现奇怪的情况!

相关内容