2008-11-08 16 views
12

मैं कोड के माध्यम से "इस मॉनिटर पर अपने विंडोज डेस्कटॉप को विस्तारित" सेट करने में सक्षम होना चाहता हूं। एक PowerShell स्क्रिप्ट आदर्श होगा। डब्ल्यूएमआई आगे बढ़ता है लेकिन मुझे डब्लूएमआई में शून्य ज्ञान है।"इस मॉनिटर पर मेरा विंडोज डेस्कटॉप बढ़ाएं" प्रोग्रामेटिक रूप से

उत्तर

4

एक पहले संभव समाधान (लेकिन उपयोगकर्ता सहभागिता के बिना)

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. 
; 
+8

कृपया इस उत्पादन कोड –

+1

को भावुक में डाल नहीं है! मुझे पता है कि कुछ दुखी मामले हैं जहां आप जीयूआई रोबोटिक्स कर सकते हैं लेकिन किसी भी तरह से मुझे नहीं लगता कि यह उनमें से एक है। –

3

इस तरह का ऑपरेशन पावरशेल से सीधे उपलब्ध नहीं है इस अर्थ में कि .NET इंटरफ़ेस नहीं है इन सेटिंग्स। बहुत सी कोर ओएस सामान अप्रबंधित कोड है जिसे केवल Win32 API कॉल के माध्यम से छेड़छाड़ की जा सकती है। जबकि आप डब्लूएमआई के साथ कुछ हो सकते हैं, मैंने थोड़ी देर की खोज की और एक संतोषजनक डब्ल्यूएमआई कक्षा नहीं ढूंढ पाई जो इस सेटिंग में हेरफेर करने में सक्षम है।

अगला चरण सीधे रजिस्ट्री को संशोधित करना होगा। ऐसा लगता है कि सेटिंग HKLM के अंतर्गत है: \ system \ CurrentControlSet \ control \ video - कहीं। मेरा मानना ​​है कि यह "अटैच। टोडेस्कटॉप" नामक एक है।

यह एक आंशिक समाधान है, इसलिए मैं समुदाय विकी उत्तर के रूप में चिह्नित कर रहा हूं।

मुझे यकीन नहीं है कि यह सही रजिस्ट्री कुंजी है, और मेरे पास ऐसी प्रणाली नहीं है जिस पर मैं इस समय बहु-मॉनिटर का परीक्षण कर सकता हूं। इसका उद्देश्य यह निर्धारित करना है कि प्राथमिक नियंत्रक कौन सा है, और उसके बाद यह 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" 
0

मुझे अपनी मशीन पर काम करने के लिए वॉनसी की स्क्रिप्ट प्राप्त करने के लिए कुछ छोटे बदलाव करना पड़ा। यह अब थोड़ा और सामान्य है।

; 
; — 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}") 
2

मैंने एक क्लीनर संस्करण बनाया है जो प्रेषक का उपयोग नहीं करता है।

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

1

मॉनीटर स्विच करने के लिए मेरा ऑटोआईटी-स्क्रिप्ट यहां है क्योंकि मेरा अति ग्राफिक्स कार्ड मुझे एक ही समय में 3 मॉनीटर सक्रिय करने की अनुमति नहीं देता है। मेरे पास 2 मॉनीटर संलग्न हैं और एक टीवी है। यह स्क्रिप्ट वॉनसी की लिपि क्या कर रही है लेकिन एक अधिक प्रभावी और तेज़ तरीके से कर रही है।

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 

बस अपने तीसरे मॉनीटर/टीवी नाम के साथ "सैमसंग" को प्रतिस्थापित करें और आप सब तैयार हैं! जैसा कि आप निश्चित रूप से जानते हैं कि आप इसे निष्पादन योग्य में परिवर्तित कर सकते हैं जो ऑटोआईटी इंस्टॉल किए बिना भी किसी भी मशीन पर चलता है।

14

विंडोज 7, 8 और 10 को एक छोटे से प्रोग्राम के साथ आना चाहिए जो वास्तव में करता है: displaywitch.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 पर इस परीक्षण किया है, और यह विंडोज 10 पर काम करने की पुष्टि की गई है]

संबंधित मुद्दे