[英]Disconnect and Reconnect Displays Programmatically
Question: What is the best way to programmatically disconnect and reconnect displays programmatically? 问题:以编程方式以编程方式断开连接和重新连接显示的最佳方法是什么?
The Goal: Kill the video output (black screen with no backlight) on a display and later turn it back on. 目标:在显示器上杀死视频输出(没有背光的黑屏),然后再将其重新打开。 Imagine unplugging the video cord from the monitor, then plugging it back in.
想象一下,从显示器上拔下视频线,然后将其重新插入。
My Attempt: 我的尝试:
// 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);
I can interact with each display, but I can't figure out how to disconnect one. 我可以与每个显示器进行交互,但我无法弄清楚如何断开连接。
It is similar to "Disconnect this display" in the Screen Resolution properties in Windows 7: 它类似于Windows 7中屏幕分辨率属性中的“断开此显示”:
Notes: 笔记:
References: 参考文献:
There's a github project that I STILL haven't got around, but it's a starting point. 有一个github项目,我仍然没有,但它是一个起点。 You need to use Win7 specific API in order to change settings .
您需要使用Win7特定的API才能更改设置 。 ChangeDisplaySettings won't work.
ChangeDisplaySettings无效。
Have a look: https://github.com/ChrisEelmaa/MultiMonitorHelper 看看: https : //github.com/ChrisEelmaa/MultiMonitorHelper
This is what you need to do: 这是你需要做的:
update the IDisplay
interface to support TurnOff() method, 更新
IDisplay
接口以支持TurnOff()方法,
and then call it: 然后调用它:
var displayModel = DisplayFactory.GetDisplayModel();
var displayList = displayModel.GetActiveDisplays().ToList();
var firstDisplay = displayList[0].TurnOff();
How to implement TurnOff()? 如何实现TurnOff()? I WOULD imagine this is how(I might be wrong here now):
我想象这就是(我现在可能在这里错了):
You need to break the connection between GPU & monitor through breaking the "paths". 您需要通过打破“路径”来打破GPU和监视器之间的连接。 You can break path between source and target like this:
你可以像这样打破源和目标之间的路径:
Call SetDisplayConfig
() and pass inside specific paths and make sure you map out the DISPLAYCONFIG_PATH_ACTIVE
from the DISPLAY_PATH_INFO
structure flags integer. 调用
SetDisplayConfig
()并传递特定路径,并确保从DISPLAY_PATH_INFO
结构标记整数中映射出DISPLAYCONFIG_PATH_ACTIVE
。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553945(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/hardware/ff553945(v=vs.85).aspx
Sorry for not being more helpful, but this is pretty hardcore stuff, it took me quite a while to even understand the basics of that API. 很抱歉没有更多的帮助,但这是非常核心的东西,我花了很长时间甚至了解该API的基础知识。 It's a starting point :-),
这是一个起点:-),
take a look at the example how to rotate specific monitor in Win7: How do I set the monitor orientation in Windows 7? 看看如何在Win7中旋转特定监视器的示例: 如何在Windows 7中设置监视器方向?
In all honesty, just wrap the DisplaySwitch.exe for Win7, and pass /internal or /external(depending if you want to disable/enable first/second monitor), this might or might not work for >2 monitors. 老实说,只需将DisplaySwitch.exe包装为Win7,然后传递/ internal或/ external(取决于您是否要禁用/启用第一个/第二个监视器),这可能适用于> 2个监视器,也可能不适用。
1) Get MultiMonitorHelper from here: https://github.com/ChrisEelmaa/MultiMonitorHelper/tree/master 1)从这里获取MultiMonitorHelper : https : //github.com/ChrisEelmaa/MultiMonitorHelper/tree/master
2) Extend Win7Display to disconnect the display : 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
}
}
}
3) Extend Win7Display to reconnect the display using an answer from this post : 3)使用此帖子的答案扩展Win7Display以重新连接显示 :
using System.Diagnostics;
/// <summary>
/// Reconnect all displays.
/// </summary>
public void ReconnectDisplays()
{
DisplayChanger.Start();
}
private static Process DisplayChanger = new Process
{
StartInfo =
{
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "DisplaySwitch.exe",
Arguments = "/extend"
}
};
4) Update the methods in IDisplay . 4)更新IDisplay中的方法。
5) Implement the methods: 5)实施方法:
IDisplayModel displayModel = DisplayFactory.GetDisplayModel();
List<IDisplay> displayList = displayModel.GetActiveDisplays().ToList();
displayList[0].DisconnectDisplay(0);
displayList[0].ReconnectDisplays();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.