2016-03-08 14 views
7

Mam dwa monitory (HP EliteDisplay E190i), oba są podłączone do dwóch komputerów (2x VGA + DP).
Monitory te obsługują również DVI, więc zamiast mieć głupi przycisk przełączania, za każdym razem, gdy chcę przełączać się między komputerami, muszę poruszać się po menu monitorów. Miałem kiedyś głupsze monitory i przełączanie było naprawdę łatwe, ale po prostu nie mogę się przyzwyczaić do całej nawigacji - często mylą się ...Jak mogę natychmiast wcisnąć monitor w tryb oszczędzania energii w C#?

A oto oferta - chcę szybko zmienić między komputerami, wykonując polecenie. Oczywiście nie można tego zrobić bezpośrednio (komputery nie są ze sobą w żaden sposób połączone), ale kiedy monitory wchodzą w tryb oszczędzania energii (lub gdy system operacyjny je wyłącza), monitory rozpoczynają skanowanie w poszukiwaniu dostępnych wejść. W ten sposób zablokują się na innym komputerze i problem zostanie rozwiązany.

Dość wprowadzenie choć próbowałem this solution i to działało świetnie, ale to nie było idealne:

  • Miał zanikanie animacji, które trwało kilka sekund przed monitor faktycznie wyłączony
  • musiałem nie dotykać myszy/klawiatury na czas trwania powyższego wyciszeniem animacji, w przeciwnym razie byłoby to anulowane

próbowałem wyłączyć wejście według this answer przed wysłaniem monitora do snu, a następnie ponowne włączenie go po 5 sekundach, ale to również nie działa, ponieważ:

  • Wymagało mnie do uruchomienia aplikacji z prawami administratora, inaczej wejście nie będzie blokowane
  • Chociaż wejście zostało zablokowane podczas działania z prawami administratora, nadal mogłem poruszać myszą lub uderzać w klawisze klawiatury podczas animacji zaniku, aby ją anulować (mimo że wskaźnik się nie poruszył lub wejście klawiatury zostało zignorowane).

Oto mój kod:

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

używam Windows 7 Enterprise 64 na obu komputerach.

Czy istnieje sposób, aby cała ta ceremonia zadziałała?

+0

Więc problem z drugiego rozwiązania było to, że nie byli w stanie go uruchomić z uprawnieniami administratora? –

+0

Nie, dane wejściowe zostały zablokowane, gdy uruchomiłem je z prawami administratora, zgodnie z oczekiwaniami. Jednak mimo że wejście zostało zablokowane, przesuwanie myszy lub naciśnięcie klawisza na klawiaturze (fizycznie) anulowało animację zaniku - pomimo, że _pointer_ nie poruszyło się, a wejście klawiatury zostało zignorowane (naciśnięto klawisze, ale tekst nie był wpisane do notatnika). –

+0

Jak zablokować wejście przed wysłaniem polecenia sleep – RomCoo

Odpowiedz

0

Musiałem edytować moją odpowiedź, ponieważ głupio nie przeczytałem twojego pytania w całości.

Proponuję utworzyć aplikację, która znajduje się na obu komputerach, które wysyłają do siebie żądania za pośrednictwem prostego gniazda TCP/klient serwera TCP.

Pozwoliłoby to na przykład na naciśnięcie przycisku na komputerze 1, który uśpi go i wykonanie tego samego dla monitorów, i wysłanie komunikatu do komputera 2, aby obudzić i wykraść wejścia monitora. Jeśli chodzi o szybkość tego, to myślę, że zależy to od kilku zmiennych, ale można to później przerobić.

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) 
     { 
     } 
    } 
    } 
} 

a serwerem:

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

    } 
} 

Coś w tym być może, warto przyjrzeć się przynajmniej, powyższy kod nie jest dokładnie dopracowane ale pozwoli Ci kontrolować działania obu komputerów za pośrednictwem sieci domowej, pozwalając na jednoczesne wykonywanie określonych poleceń: Uśpienie/Obudź itp.

Mam nadzieję, że to daje nowe kierunek do zbadania.

Również uważam, że jest najlepsze praktyki dla kodu do blokowania wejścia do sformatowania jako takie:

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

To nie wystarczy. Komputery nie są ze sobą w żaden sposób połączone (również wspomniane w moim pytaniu). Poza tym mam głównie problem z częścią "RUN CODE TUTAJ DO DZIAŁANIA PC SLEEP AND MONITOR SLEEP", a nie z komunikacją między komputerami. –

+0

Przeprosiny Podjąłem założenie, że oba urządzenia będą przynajmniej połączone z routerem lub modemem w domu. Powodem, dla którego to zasugerowałem, było przede wszystkim to, że gdy jeden komputer śpi, a drugi się budzi, automatycznie przesyła dane do wizualnych szpilek, które kradnie, więc byłby to interesujący sposób na rozwiązanie problemu. Mówiąc to, kiedy wrócę do domu, przekażę trochę kodu, którego używam do zatrzymania wizualnego sygnału z mojego komputera na moje monitory i możemy sprawdzić, czy działa lepiej niż obecne rozwiązanie. – Digitalsa1nt

Powiązane problemy