我希望能夠通過代碼設置「將我的Windows桌面擴展到此顯示器上」。一個PowerShell腳本將是理想的。 WMI似乎是前進的方向,但我對WMI沒有任何認識。「以編程方式將我的Windows桌面擴展到此顯示器上」
回答
一個第一可能的解決方案是...通過GUI(但無需用戶交互)
VB script(也described here但在Autoit語言):
Option Explicit
Dim WshShell, Dummy, Splash
On Error Resume Next
Set WshShell = WScript.CreateObject("WScript.Shell")
'Main
Call DoIt
WScript.Quit
Sub DoIt
wshshell.Run("%systemroot%\system32\control.exe desk.cpl,@0,3")
' Give Display Properties time to load
WScript.Sleep 1000
WshShell.SendKeys "2"
WScript.Sleep 10
WshShell.SendKeys "%E"
WScript.Sleep 500
WshShell.SendKeys "%A"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{TAB}"
WshShell.SendKeys "{ENTER}"
End Sub 'DoIt
在AutoIt的,這將是:
;
; — toggle-screen.au3
;
; exec cpanel app `display settings`
Run(」C:\WINDOWS\system32\control.exe desk.cpl,@0,3?」)
; wait for window to be active
WinWaitActive(」Display Settings」)
; select 2nd display
Send(」{TAB}」)
Send(」{DOWN}」)
; work back to the ‘extend desktop’ control
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
Send(」+{TAB}」)
; toggle ‘extend desktop’ control and apply
Send(」{SPACE}」)
Send(」{ENTER}」)
; wait for window to be active
WinWaitActive(」Display Settings」)
; accept
Send(」{TAB}」)
Send(」{ENTER}」)
;
; — E.O.F.
;
這種操作不能從PowerShell直接訪問,因爲沒有.NET接口這些設置。很多核心操作系統的東西都是非託管代碼,只能通過win32 API調用進行操作。雖然您可能正在使用WMI進行某些操作,但我搜索了一段時間,但無法找到能夠操作此設置的令人滿意的WMI類。
下一步是直接修改註冊表。它看起來像設置位於HKLM:\ system \ CurrentControlSet \ control \ video - 某處。我相信這是一個名爲「Attach.ToDesktop」的人。
這是一個部分解決方案,所以我將其標記爲社區wiki答案。
我不確定這是正確的註冊表鍵,而且我沒有可以在此刻測試多顯示器的系統。這樣做的目的是確定哪個是主控制器,然後輸出Attach.ToDesktop鍵的值。
param (
$ControllerName = "$(throw 'ControllerName is a mandatory parameter')"
)
$regPath = "HKLM:\system\CurrentControlSet\control\video"
$devDescStr = "Device Description"
Set-Location -path $regPath
$regSubKey = Get-ChildItem -recurse -include 0000
$devDescProperty = $regSubKey | Get-ItemProperty -name $devDescStr -erroraction SilentlyContinue
$priDescProperty = $devDescProperty | Where-Object { $_.$devDescStr -match $ControllerName }
Set-Location -path $priDescProperty.PSPath
Get-ItemProperty -path . -name "Attach.ToDesktop"
我不得不做一些小的修改來讓VonC的腳本在我的機器上工作。現在它更通用一些。
;
; — toggle-screen2.au3
;
#include <WinAPI.au3>
; exec cpanel app `display settings`
Run(_WinAPI_ExpandEnvironmentStrings("%windir%") & "\system32\control.exe desk.cpl,@0,3?")
; wait for window to be active
WinWaitActive("Display Properties")
; select 2nd display
Send("!d")
Send("{DOWN}")
; toggle the ‘extend desktop’ checkbox
Send("!e")
; close the dialog
Send("{ENTER}")
我做了一個不使用sendkeys的清潔版本。
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;
}
}
我只在新安裝的計算機上測試過。 I created a a snippet here if you would like to make changes to it
這是我用於切換顯示器的AutoIt腳本,因爲我的ATI顯卡不允許我同時有3個顯示器處於活動狀態。我有2臺顯示器和一臺電視機。該腳本正在做VonC的腳本,但以更有效和更快的方式進行。
Run("C:\WINDOWS\system32\control.exe desk.cpl", "C:\Windows\system32\")
WinWait("Screen Resolution")
ControlCommand("Screen Resolution", "", "ComboBox1", "SetCurrentSelection", "SAMSUNG")
if (ControlCommand("Screen Resolution", "", "ComboBox3", "GetCurrentSelection", "") = "Disconnect this display") Then
ControlCommand("Screen Resolution", "", "ComboBox1", "SetCurrentSelection", "2")
ControlCommand("Screen Resolution", "", "ComboBox3", "SetCurrentSelection", "3")
ControlCommand("Screen Resolution", "", "ComboBox1", "SetCurrentSelection", "0")
ControlCommand("Screen Resolution", "", "ComboBox3", "SetCurrentSelection", "1")
ControlClick("Screen Resolution", "", "Button4")
WinWait("Display Settings")
ControlClick("Display Settings", "", "Button1")
Else
ControlCommand("Screen Resolution", "", "ComboBox3", "SetCurrentSelection", "3")
ControlCommand("Screen Resolution", "", "ComboBox1", "SetCurrentSelection", "2")
ControlCommand("Screen Resolution", "", "ComboBox3", "SetCurrentSelection", "1")
ControlClick("Screen Resolution", "", "Button4")
WinWait("Display Settings")
ControlClick("Display Settings", "", "Button1")
EndIf
只需更換「SAMSUNG」與第三顯示器/電視機的名字和你所有的設置! 正如你一定知道你可以將它轉換成即使沒有安裝AutoIt的任何機器上運行的可執行文件。
Windows 7,8和10應該有一個小程序來完成這個工作:displayswitch.exe。 This page列出了以下參數:
displayswitch.exe/internal Disconnect projector
displayswitch.exe/clone Duplicate screen
displayswitch.exe/extend Extend screen
displayswitch.exe/external Projector only (disconnect local)
對於一鍵式解決方案所提出的問題,只需創建一個*。包含單行的蝙蝠文件
call displayswitch.exe/extend
並將其保存到桌面。
[我測試了在Windows 8.1中,它已被證實在Windows 10運行]
- 1. 以編程方式顯示桌面
- 2. Powershell將桌面擴展到顯示器並禁用程序切換的顯示?
- 3. 如何以編程方式將文件上載到Windows Server 2003遠程桌面
- 4. 切換「擴展這些顯示」和「僅顯示桌面上1」
- 5. 遠程桌面連接以編程方式模擬windows C++
- 6. 擴展桌面
- 7. 以編程方式禁用Firefox擴展
- 8. 如何以編程方式操縱Windows桌面圖標位置?
- 9. 如何以編程方式更改Windows桌面主題
- 10. 以編程方式在Silverlight TreeView上顯示展開箭頭
- 11. 以編程方式擴展Windows Azure角色
- 12. 如何以編程方式確定我的桌面的大小?
- 13. 如何以編程方式將大型文件從桌面上傳到BigQuery?
- 14. 我可以通過編程方式(服務器端)將ASP.NET AJAX擴展添加到頁面嗎?
- 15. 使用Windows API以編程方式確定主顯示器上的VGA或DVI?
- 16. 以編程方式在WP7上顯示軟輸入面板(SIP)
- 17. 以編程方式更新桌面「在拖動時顯示窗口內容」
- 18. 以編程方式控制Spotify桌面播放器
- 19. 以編程方式在Safari 8上安裝擴展OSX 10.10
- 20. 以編程方式將終端擴展至特定大小
- 21. 以編程方式將Windows機器加入到域名
- 22. 如何以編程方式將擴展的ascii字符發佈到Facebook發佈?
- 23. Chrome擴展程序:如何以編程方式檢查擴展程序的後臺頁面
- 24. 以編程方式在用戶桌面上創建Web快捷方式
- 25. Installshield桌面快捷方式圖標顯示Windows默認圖標
- 26. 如何以編程方式在此頁面上獲取圖像?
- 27. 如何以編程方式將小工具安裝到用戶桌面?
- 28. 以編程方式登錄到Windows XP
- 29. WPF:全屏同時顯示兩個窗口(擴展桌面)
- 30. 面向協議的編程,隱式調用擴展方法
請不要把這個投入生產代碼 – 2008-11-09 05:57:29