2016-03-08 18 views
7

Ho due monitor (HP EliteDisplay E190i), entrambi sono collegati a due computer (2x VGA + DP).
Questi monitor supportano anche DVI, quindi, invece di avere uno stupido pulsante di commutazione, ogni volta che desidero passare da un computer all'altro, devo navigare nel menu dei monitor. Avevo i monitor più scomodi e il passaggio è stato davvero semplice, ma non riesco ad abituarmi all'intera navigazione - spesso confonde ...Come posso forzare il monitor in modalità risparmio energetico immediatamente in C#?

Quindi ecco l'accordo: voglio essere in grado di passare rapidamente tra i computer eseguendo un comando. Ovviamente questo non può essere fatto direttamente (i computer non sono collegati tra di loro in alcun modo), ma quando i monitor entrano in modalità risparmio energetico (o quando il sistema operativo li spegne), i monitor iniziano a cercare gli input disponibili. In questo modo si bloccavano nell'altro computer e il problema veniva risolto.

introduzione Basta, però, ho provato this solution e ha funzionato grande, ma non è stato perfetto:

  • Aveva un fade out di animazione che ha avuto un paio di secondi prima che il monitor effettivamente spento
  • ho dovuto a non toccare il mouse/tastiera per tutta la durata della dissolvenza sopra fuori animazione, altrimenti si otterrebbe annullato

ho provato a rendere invalido l'ingresso in base alla this answer prima di inviare il monitor a dormire, poi ri-consenta dopo 5 secondi, ma che anche non ha funzionato perché:

  • Mi c'è necessario per eseguire l'applicazione con diritti di amministratore, altrimenti ingresso non sarebbe stato bloccato
  • Anche se la input è stato bloccato durante l'esecuzione con diritti di amministratore, potevo comunque spostare il mouse o premere alcuni tasti sulla tastiera durante l'animazione fade out per cancellarlo (anche se il puntatore non si spostava, o l'input della tastiera era ignorato).

Ecco il mio codice:

[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); 
    } 
} 

Io uso Windows 7 Enterprise x64 su entrambi i computer.

C'è un modo per far funzionare tutta questa cerimonia?

+0

Quindi il problema con la seconda soluzione era che non erano in grado di eseguirlo con privilegi di amministratore? –

+0

No, l'input è stato bloccato quando l'ho eseguito con diritti di amministratore, come previsto. Tuttavia, anche se l'input è stato bloccato, spostando il mouse o premendo un tasto sulla mia tastiera (fisicamente) è stata annullata l'animazione in dissolvenza, anche se il _pointer_ non si spostava e l'input della tastiera veniva ignorato (i tasti erano premuti, ma non c'era testo digitato nel blocco note). –

+0

come fare per bloccare l'input prima di inviare il comando sleep – RomCoo

risposta

0

Ho dovuto modificare la mia risposta perché stupidamente non ho letto la tua domanda nella sua interezza.

Suggerirei di creare un'applicazione che si trovi su entrambi i computer che inviano le richieste l'un l'altro tramite un semplice socket TCP Server/Client.

Ciò consentirebbe, ad esempio, di premere un pulsante sul PC 1 che lo metterà in stato di stop e di fare lo stesso per i monitor e di inviare un messaggio al PC 2 per riattivare e rubare gli ingressi del monitor. In termini di velocità, suppongo che dipenda da diverse variabili, ma ciò può essere risolto in un secondo momento.

TCP Client/Server:

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, 0, buffer.Length); 
      netStream.Flush(); 
      tcpService.Close(); 
     } 
     catch(Exception ex) 
     { 
     } 
    } 
    } 
} 

e il server:

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, 0, 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, 0, 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, 0, buffer.Length); 
      streamToClient.Flush(); 
     } 

    } 
} 

Qualcosa del genere, forse, merita di essere esaminata per lo meno, il codice di cui sopra non è esattamente raffinato ma consentirebbe di controllare le azioni di entrambi i computer tramite la rete domestica consentendo l'esecuzione contemporanea di comandi specifici: Sleep/Wake ecc.

Spero che questo ti dia una nuova direzione da investigare.

Inoltre credo che sia delle migliori pratiche per il codice per il blocco di ingresso da formattare come tale:

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

Questo non funzionerà. I computer non sono collegati tra loro in alcun modo (citato anche nella mia domanda). Inoltre, ho principalmente problemi con la parte 'SUGGERISCI IL CODICE QUI AZIONE PC SLEEP E MONITOR SLEEP', e non la comunicazione tra i computer. –

+0

Mi scuso dal presupposto che avrebbero almeno dovuto essere connessi a un router o modem all'interno della casa. La ragione per cui l'ho suggerito è principalmente perché quando un computer è addormentato e un altro si sveglia, esso invia automaticamente i dati ai pin visivi che è ciò che ruba, quindi sarebbe stato un modo interessante per risolvere il tuo problema. Detto questo però quando torno a casa invierò parte del codice che uso per interrompere il segnale visivo dal mio computer ai miei monitor e possiamo vedere se funziona meglio della tua attuale soluzione. – Digitalsa1nt