如何在C#中立即强制显示器进入省电模式?

我有两台显示器(HP Elitedisplay E190i),两台都连接到两台电脑(2x VGA DP).
这些显示器也支持DVI,因此我不想使用愚蠢的切换按钮,每次我希望在计算机之间切换时,我都需要浏览显示器的菜单.我以前有笨重的显示器和切换真的很容易,但我不能习惯整个导航的东西 – 它经常让人感到困惑……

所以这是交易 – 我希望能够通过执行命令在计算机之间快速切换.显然这不能直接完成(计算机没有以任何方式相互连接),但是当监视器进入省电模式时(或当操作系统关闭它们时),监视器开始扫描可用输入.这样他们就会锁定另一台计算机并解决问题.

虽然足够的介绍,我已经尝试过this solution并且效果很好,但它并不完美:

>它有一个淡出动画,在显示器实际关闭前需要几秒钟
>在上述淡出动画期间,我不得触摸鼠标/键盘,否则会被取消

我尝试在将监视器发送到睡眠状态之前根据this answer禁用输入,然后在5秒后重新启用它,但这也无效,因为:

>它要求我使用管理员权限运行应用程序,否则不会阻止输入
>即使在使用管理员权限运行时输入被阻止,我仍然可以在淡出动画期间移动鼠标或点击键盘上的某些键来取消它(即使指针没有移动,或键盘输入被忽略) .

这是我的代码

[DllImport("user32.dll")]
private static extern int SendMessage(int hWnd,int hMsg,int wParam,int lParam);

[DllImport("user32.dll")]
private static extern int BlockInput(int fBlockIt);

static void Main()
{
    SendMessage(0xFFFF,0x112,0xF170,2);
    try
    {
        int result = BlockInput(1);
        Console.WriteLine(result);
        Thread.Sleep(5000);
    }
    finally
    {
        BlockInput(0);
    }
}

我在两台计算机上都使用Windows 7 Enterprise x64.

有没有办法让整个仪式上班?

解决方法

我不得不编辑我的答案,因为愚蠢的是我没有完整地阅读你的问题.

我建议创建一个位于两台计算机上的应用程序,它们通过简单的TCP服务器/客户端套接字相互发送请求.

例如,这将允许您按下PC 1上的一个按钮,使其进入睡眠状态并对监视器执行相同操作,并向PC 2发送消息以唤醒并窃取监视器输入.就速度而言,我猜这取决于几个变量,但这可以在以后进行.

TCP客户端/服务器:

using System;
using System.Net;
using System.Net.sockets;
using System.Diagnostics;
using System.IO;

namespace ClientSocket_System
  {
   class tcpClientSocket
   {

    #region Global Variables

    TcpClient tcpservice;
    IPEndPoint serverEndPoint;
    NetworkStream netStream;

    #endregion


    public void commToServer()
    {
        tcpservice = new TcpClient();
        serverEndPoint = new IPEndPoint(IPAddress.Parse("xxx.xxx.xxx.xx"),xxxx); //Enter IP address of computer here along with a port number if needed
        try
        {
            tcpservice.Connect(serverEndPoint);
            netStream = tcpservice.GetStream();
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] buffer = encoder.GetBytes("SwitchComputers");
            netStream.Write(buffer,buffer.Length);
            netStream.Flush();
            tcpservice.Close();
        }
        catch(Exception ex)
        {
        }
    }
   }
}

和服务器:

using System.Net;
using System.Net.sockets;
using System.Diagnostics;
using System.IO;

namespace ClientSocket_System
{
    class tcpserverTerminal
    {



        private TcpListener tcpListener;
        private Thread listenThread;
        private TcpClient tcpservice;
        string msgFromClient;



        public void ServerStart()
        {
            tcpListener = new TcpListener(IPAddress.Any,5565);
            listenThread = new Thread(new ThreadStart(ListenForClients));
            listenThread.Start();
        }

        public void ListenForClients()
        {
            tcpListener.Start();

            while (true)
            {
                //blocks until a client has connected to the server
                TcpClient client = this.tcpListener.AcceptTcpClient();

                //create a thread to handle communication 
                //with connected client
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        public void HandleClientComm(object client)
        {
            tcpservice = (TcpClient)client;

            NetworkStream netStream = tcpservice.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = netStream.Read(message,4096);
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }

                //message has successfully been received
                ASCIIEncoding encoder = new ASCIIEncoding();

                msgFromClient = encoder.GetString(message,bytesRead);

                if (msgFromClient == "SwitchComputers")
                {

                    //RUN CODE HERE TO ACTION PC SLEEP AND MONITOR SLEEP

                    msgFromClient = null;
                }
            }
        }

        public void SocketSend()
        {
            NetworkStream streamToClient = tcpservice.GetStream();
            ASCIIEncoding encoder = new ASCIIEncoding();
            byte[] buffer = encoder.GetBytes("SwitchComputers");

            streamToClient.Write(buffer,buffer.Length);
            streamToClient.Flush();
        }

    }
}

这样的事情或许至少值得研究一下,上面的代码并不完全精确,但它允许你通过家庭网络控制两台计算机的动作,允许同时执行特定的命令:睡眠/唤醒等.

希望这能给你一个新的调查方向.

此外,我认为最佳做法是将阻止输入的代码格式化为:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll",CharSet=CharSet.Auto,ExactSpelling=true)]
public static extern bool BlockInput([In,MarshalAs(UnmanagedType.Bool)] bool fBlockIt);

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...