C# 断开和重新连接以编程方式显示

C# 断开和重新连接以编程方式显示,c#,windows-7,multiple-monitors,C#,Windows 7,Multiple Monitors,问题:以编程方式断开和重新连接显示器的最佳方式是什么 目标:关闭显示器上的视频输出(无背光的黑屏),然后重新打开。想象一下,将视频线从显示器上拔下,然后重新插入 我的尝试: // Get the monitor to disable uint iDevNum = 0; DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE(); displayDevice.cb = Marshal.SizeOf(displayDevice); EnumDisplayD

问题:以编程方式断开和重新连接显示器的最佳方式是什么

目标:关闭显示器上的视频输出(无背光的黑屏),然后重新打开。想象一下,将视频线从显示器上拔下,然后重新插入

我的尝试:

// Get the monitor to disable
uint iDevNum = 0;
DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
displayDevice.cb = Marshal.SizeOf(displayDevice);
EnumDisplayDevices(null, iDevNum, ref displayDevice, 0))

DEVMODE devMode = new DEVMODE();
EnumDisplaySettings(displayDevice.DeviceName, 0, ref devMode);

//
// Do something here to disable this display device!
//

// Save the display settings
ChangeDisplaySettingsEx(displayDevice.DeviceName, ref devMode, 
    IntPtr.Zero, ChangeDisplaySettingsFlags.CDS_NONE, IntPtr.Zero);
我可以与每个显示器交互,但我不知道如何断开一个显示器

这类似于Windows 7中屏幕分辨率属性中的“断开此显示”:

注意事项:

  • 关闭所有显示器上的视频输出将不起作用,因为我需要其他显示器保持打开状态
  • 关闭时,“死机”显示屏上的桌面区域不需要可用。此外,如果窗口移动也可以
参考文献:

// Get the monitor to disable
uint iDevNum = 0;
DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
displayDevice.cb = Marshal.SizeOf(displayDevice);
EnumDisplayDevices(null, iDevNum, ref displayDevice, 0))

DEVMODE devMode = new DEVMODE();
EnumDisplaySettings(displayDevice.DeviceName, 0, ref devMode);

//
// Do something here to disable this display device!
//

// Save the display settings
ChangeDisplaySettingsEx(displayDevice.DeviceName, ref devMode, 
    IntPtr.Zero, ChangeDisplaySettingsFlags.CDS_NONE, IntPtr.Zero);

  • 有一个github项目我还没有找到,但这是一个起点您需要使用Win7特定的API来更改设置。ChangeDisplaySettings无法工作

    看看:

    这是您需要做的:

    更新
    IDisplay
    接口以支持关闭()方法

    然后称之为:

    var displayModel = DisplayFactory.GetDisplayModel();
    var displayList = displayModel.GetActiveDisplays().ToList();
    var firstDisplay = displayList[0].TurnOff();
    
    如何实现关闭()?我想这就是为什么(我现在可能错了):

    您需要通过断开“路径”来断开GPU和监视器之间的连接。您可以像这样中断源和目标之间的路径:

    调用
    SetDisplayConfig
    ()并在特定路径内传递,确保从
    DISPLAYCONFIG\u PATH\u INFO
    structure标志中映射出
    DISPLAYCONFIG\u ACTIVE

    很抱歉没有提供更多帮助,但这是非常核心的东西,我花了相当长的时间才理解该API的基础知识。这是一个起点:-)

    查看如何在Win7中旋转特定监视器的示例:

    老实说,只需包装Win7的DisplaySwitch.exe,并传递/internal或/external(取决于您是否要禁用/启用第一个/第二个监视器),这可能对>2个监视器有效,也可能对>2个监视器无效。1)从这里获取MultiMonitorHelper

    2)Win7Display扩展到断开显示器的连接

    using MultiMonitorHelper.DisplayModels.Win7.Enum;
    using MultiMonitorHelper.DisplayModels.Win7.Struct;
    
    /// <summary>
    /// Disconnect a display.
    /// </summary>
    public void DisconnectDisplay(int displayNumber)
    {
        // Get the necessary display information
        int numPathArrayElements = -1;
        int numModeInfoArrayElements = -1;
        StatusCode error = CCDWrapper.GetDisplayConfigBufferSizes(
            QueryDisplayFlags.OnlyActivePaths,
            out numPathArrayElements,
            out numModeInfoArrayElements);
    
        DisplayConfigPathInfo[] pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements];
        DisplayConfigModeInfo[] modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements];
        error = CCDWrapper.QueryDisplayConfig(
            QueryDisplayFlags.OnlyActivePaths,
            ref numPathArrayElements,
            pathInfoArray,
            ref numModeInfoArrayElements,
            modeInfoArray,
            IntPtr.Zero);
        if (error != StatusCode.Success)
        {
            // QueryDisplayConfig failed
        }
    
        // Check the index
        if (pathInfoArray[displayNumber].sourceInfo.modeInfoIdx < modeInfoArray.Length)
        {
            // Disable and reset the display configuration
            pathInfoArray[displayNumber].flags = DisplayConfigFlags.Zero;
            error = CCDWrapper.SetDisplayConfig(
                pathInfoArray.Length,
                pathInfoArray,
                modeInfoArray.Length,
                modeInfoArray,
                (SdcFlags.Apply | SdcFlags.AllowChanges | SdcFlags.UseSuppliedDisplayConfig));
            if (error != StatusCode.Success)
            {
                // SetDisplayConfig failed
            }
        }
    }
    
    使用MultiMonitorHelper.DisplayModels.Win7.Enum;
    使用MultiMonitorHelper.DisplayModels.Win7.Struct;
    /// 
    ///断开显示器的连接。
    /// 
    公共无效断开连接显示(int displayNumber)
    {
    //获取必要的显示信息
    int numPathArrayElements=-1;
    int numdeInfo数组元素=-1;
    状态代码错误=CCDWrapper.GetDisplayConfigBufferSizes(
    QueryDisplayFlags.OnlyActivePath,
    在Numpatarrayelements,
    输出NummodeInformationElements);
    DisplayConfigPathInfo[]pathInfoArray=新的DisplayConfigPathInfo[numPathArrayElements];
    DisplayConfigModeInfo[]modeInfoArray=新的DisplayConfigModeInfo[numModeInfoArrayElements];
    错误=CCDWrapper.QueryDisplayConfig(
    QueryDisplayFlags.OnlyActivePath,
    参考Numpatarrayelements,
    pathInfoArray,
    参考NUMMODEINFORRAYLEments,
    modeInfoArray,
    IntPtr.0);
    如果(错误!=StatusCode.Success)
    {
    //QueryDisplayConfig失败
    }
    //检查索引
    if(pathInfoArray[displayNumber].sourceInfo.modeInfoIdx
    3)扩展Win7Display重新连接显示器,回答如下:

    使用系统诊断;
    /// 
    ///重新连接所有显示器。
    /// 
    公共空间重新连接显示()
    {
    DisplayChanger.Start();
    }
    私有静态进程DisplayChanger=新进程
    {
    StartInfo=
    {
    CreateNoWindow=true,
    WindowsStyle=ProcessWindowsStyle.Hidden,
    FileName=“DisplaySwitch.exe”,
    Arguments=“/extend”
    }
    };
    
    4)更新IDisplay中的方法

    5)实施以下方法:

    IDisplayModel displayModel = DisplayFactory.GetDisplayModel();
    List<IDisplay> displayList = displayModel.GetActiveDisplays().ToList();
    
    displayList[0].DisconnectDisplay(0);
    displayList[0].ReconnectDisplays();
    
    IDisplayModel displayModel=DisplayFactory.GetDisplayModel();
    List displayList=displayModel.GetActiveDisplays().ToList();
    显示列表[0]。断开显示(0);
    显示列表[0]。重新连接显示();
    
    CCDWrapper
    现在只是CCD名称空间中的包装器。您的github已关闭,是否可以重新打开