"以编程方式将我的Windows桌面扩展到此监视器上"

Zi *_*kki 17 windows powershell wmi multiple-monitors

我希望能够通过代码设置"将我的Windows桌面扩展到此监视器上".PowerShell脚本是理想的.WMI似乎是前进的方向,但我对WMI知之甚少.

Com*_*bra 21

Windows 7,8和10应该带有一个小程序,它可以完成这个:displayswitch.exe. 此页面列出了以下参数:

displayswitch.exe/internal  Disconnect projector
displayswitch.exe/clone     Duplicate screen
displayswitch.exe/extend    Extend screen
displayswitch.exe/external  Projector only (disconnect local)
Run Code Online (Sandbox Code Playgroud)

对于提出的问题的一键式解决方案,只需创建一个包含单行的*.bat文件

call displayswitch.exe/extend
Run Code Online (Sandbox Code Playgroud)

并将其保存到您的桌面.

[我在Windows 8.1上对此进行了测试,并且已经确认可以在Windows 10上运行.]


lor*_*ron 5

我制作了一个不使用sendkey的更干净的版本。

public class DisplayHelper
{
    [DllImport("user32.dll")]
    static extern DISP_CHANGE ChangeDisplaySettings(uint lpDevMode, uint dwflags);
    [DllImport("user32.dll")]
    static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

    enum DISP_CHANGE : int
    {
        Successful = 0,
        Restart = 1,
        Failed = -1,
        BadMode = -2,
        NotUpdated = -3,
        BadFlags = -4,
        BadParam = -5,
        BadDualView = -1
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    struct DISPLAY_DEVICE
    {
        [MarshalAs(UnmanagedType.U4)]
        public int cb;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string DeviceName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceString;
        [MarshalAs(UnmanagedType.U4)]
        public DisplayDeviceStateFlags StateFlags;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceID;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceKey;
    }

    [Flags()]
    enum DisplayDeviceStateFlags : int
    {
        /// <summary>The device is part of the desktop.</summary>
        AttachedToDesktop = 0x1,
        MultiDriver = 0x2,
        /// <summary>The device is part of the desktop.</summary>
        PrimaryDevice = 0x4,
        /// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
        MirroringDriver = 0x8,
        /// <summary>The device is VGA compatible.</summary>
        VGACompatible = 0x16,
        /// <summary>The device is removable; it cannot be the primary display.</summary>
        Removable = 0x20,
        /// <summary>The device has more display modes than its output devices support.</summary>
        ModesPruned = 0x8000000,
        Remote = 0x4000000,
        Disconnect = 0x2000000
    }

    public static void EnableSecondaryDisplay()
    {
        var secondaryIndex = 1;
        var secondary = GetDisplayDevice(secondaryIndex);
        var id = secondary.DeviceKey.Split('\\')[7];

        using (var key = Registry.CurrentConfig.OpenSubKey(string.Format(@"System\CurrentControlSet\Control\VIDEO\{0}", id), true))
        {
            using (var subkey = key.CreateSubKey("000" + secondaryIndex))
            {
                subkey.SetValue("Attach.ToDesktop", 1, RegistryValueKind.DWord);
                subkey.SetValue("Attach.RelativeX", 1024, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.XResolution", 1024, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.YResolution", 768, RegistryValueKind.DWord);
                subkey.SetValue("DefaultSettings.BitsPerPel", 32, RegistryValueKind.DWord);
            }
        }

        ChangeDisplaySettings(0, 0);
    }

    private static DISPLAY_DEVICE GetDisplayDevice(int id)
    {
        var d = new DISPLAY_DEVICE();
        d.cb = Marshal.SizeOf(d);
        if (!EnumDisplayDevices(null, (uint)id, ref d, 0))
            throw new NotSupportedException("Could not find a monitor with id " + id);
        return d;
    }
}
Run Code Online (Sandbox Code Playgroud)

我仅在新安装的计算机上对此进行了测试。


Von*_*onC 2

第一个可能的解决方案是......通过 GUI(但没有用户交互)

\n\n

VB 脚本(也在此描述,但采用Autoit语言):

\n\n
Option Explicit\nDim WshShell, Dummy, Splash\n\nOn Error Resume Next\n\nSet WshShell = WScript.CreateObject("WScript.Shell")\n\n\'Main\nCall DoIt\nWScript.Quit\n\nSub DoIt\nwshshell.Run("%systemroot%\\system32\\control.exe desk.cpl,@0,3")\n\n\' Give Display Properties time to load\nWScript.Sleep 1000\nWshShell.SendKeys "2"\nWScript.Sleep 10\nWshShell.SendKeys "%E"\nWScript.Sleep 500\nWshShell.SendKeys "%A"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{TAB}"\nWshShell.SendKeys "{ENTER}"\nEnd Sub \'DoIt\n
Run Code Online (Sandbox Code Playgroud)\n\n

在 Autoit 中,这将是:

\n\n
;\n; \xe2\x80\x94 toggle-screen.au3\n;\n\n; exec cpanel app `display settings`\nRun(\xe2\x80\x9dC:\\WINDOWS\\system32\\control.exe desk.cpl,@0,3?\xe2\x80\x9d)\n\n; wait for window to be active\nWinWaitActive(\xe2\x80\x9dDisplay Settings\xe2\x80\x9d)\n\n; select 2nd display\nSend(\xe2\x80\x9d{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d{DOWN}\xe2\x80\x9d)\n\n; work back to the \xe2\x80\x98extend desktop\xe2\x80\x99 control\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d+{TAB}\xe2\x80\x9d)\n\n; toggle \xe2\x80\x98extend desktop\xe2\x80\x99 control and apply\nSend(\xe2\x80\x9d{SPACE}\xe2\x80\x9d)\nSend(\xe2\x80\x9d{ENTER}\xe2\x80\x9d)\n\n; wait for window to be active\nWinWaitActive(\xe2\x80\x9dDisplay Settings\xe2\x80\x9d)\n\n; accept\nSend(\xe2\x80\x9d{TAB}\xe2\x80\x9d)\nSend(\xe2\x80\x9d{ENTER}\xe2\x80\x9d)\n\n;\n; \xe2\x80\x94 E.O.F.\n; \n
Run Code Online (Sandbox Code Playgroud)\n

  • 恶心!我知道有一些悲惨的情况,你所能做的就是 GUI 机器人,但不知怎的,我不认为这是其中之一。 (3认同)