So horcht man mit C# auf den Bildschirmschoner


Thomas Wölfer
Thomas Wölfer

12. August 2009


Wie man in C# auf den Screensaver reagiert

Manchmal möchte man in einem Programm darauf reagieren, das der Benutzer das Programm nicht länger verwendet, obwohl es noch läuft. Solche Situationen treten zum Beispiel dann ein, wenn die Workstation gelockt, oder aber, wenn der Bildschirmschoner aktiviert wird.
Das geht mit Win32 schon seit geraumer Zeit relativ einfach, und zwar mit Hilfe der SensEvents - in diesem Fall mit dem ISensLogon Event Interface.

Für die Nutzung aus .Net heraus gibt es aber leider keine wirklich brauchbare Beschreibung dafür - zumindest konnte ich keine finden. Daher hier: Eine Kurzbeschreibung fürs horchen per ISensLogon Implementierung.

Die Sache ist danbarerweise viel einfacher, als die COM-Dokumentation vermuten läßt. Zunächst braucht man im Projekt zwei neue Referenzen: Eine auf die "COM+ Admin Type Library", und eine auf die "SENS Events Type Library".

Mit der "Admin" referenz kommt man an die COMAdminCatalgoClass, die man zum registrieren (und abmelden) von Event Listenern benötigt, die "SENS" Referenz liefert einem die benötigten Definitionen um mit dem ISensLogon Interface arbeiten zu können.

Im Beispiel erzeuge ich einfach eine Instance der COMAdminCatalogClass als Member einer Form. Mit Hilfe dieses Members kommt man dann an die Sammlung aus Subscriptions, und mit deren Hilfe kann man dann eine neue Subscription erzeugen: In diesem Fall eine, für die "SENS Logon Events". Das geht mit Hilfe der EventCLSID dieser Events (die man notfalls durch Suche in der Registry findet.).

Das anlegen eines neuen Abos verläuft dann wie folgt - wichtig ist dabei nur, das man sich die ID des Abos merkt - ansonsten kann man es später nicht mehr kündigen:

private
string Subscribe()
{
   var subscription = (ICatalogObject)_subscriptions.Add();
   subscription.set_Value("EventCLSID", "{D5978630-5B9F-11D1-8DD2-00AA004ABD5E}"); // (findet man per Suche nach SENS Logon Events in der registry)
   subscription.set_Value("Name", "Subscription to ISensLogon");
   subscription.set_Value("SubscriberInterface", this);
   subscription.set_Value("Enabled", true);
   subscription.set_Value("PerUser", true);

   _subscriptions.SaveChanges();

   return subscription.get_Value("ID").ToString();
}

Damit man die Notifizierungen auch bekommt  muss irgendwer das ISensLogon Interface implentieren: Im Beispiel tut das einfach die Form. Das Interface hat 7 Methoden, und im Beispiel wird einfach in einer Liste aus Strings mitgeführt, welches Ereignis eingetreten ist. (Diese Liste kann man sich dann später per Klick auf den Button der Form anzeigen lassen. Das ist darum so, weil man keine Desktop-Interaktionen durchführen kann, wenn kein Benutzer angemeldet ist: Würden die Methoden aus der Interface-Implementierung direkt in die Listbox schreiben, gäbe es nur eine Exception aus Windows.Forms.)

Zum abbestellen des Abos muss man einfach über die Liste der Abos laufen, und dann dasjenige entfernen, das die "eigene" ID hat, die beim bestellen gemerkt wurde.

private void Unsubscribe()
{
   for (int i = 0; i < _subscriptions.Count; i++ )
   {
      var subscription = (ICatalogObject)_subscriptions.get_Item(i);

      if (subscription.get_Value("ID").ToString() == _subscriptionId)
      {
         _subscriptions.Remove(i);
         _subscriptions.SaveChanges();
         return;
      }
   }
}

Das wars eigentlich schon: Wer mag kann sich das komplette Projekt (VS 2088, C# 3.0) runterladen und ausprobieren...

SensTest.zip (10.23 KB)