Donnerstag, 30. Dezember 2010

Youtube durchsuchen

In diesem Post möchte ich euch zeigen, wie man mit C# Youtube durchsuchen, also auf der Plattform nach bestimmten Videos suchen kann.
Hierfür benötigen wie die Google Data API, insbesondere das Youtube SDK. Mit diesen Programmierbibliotheken funktioniert der Zugriff auf Youtube & Co ganz einfach.
Zum Herunterladen gibt's die Google Data API auf dieser Seite, zum Zugriff auf Youtube brauchen wir aber nur diese Datei, das Youtube SDK.
Damit wir es später in das Projekt einbinden können, muss es installiert werden.
Das Durchsuchen von Youtube läuft über sogenannte Feeds.
Feeds sind so etwas wie Inhalte einer Website in Kurzform, meistens in reinem Textformat, so können sich Leser schnell über neueste Themen informieren, außerdem lesen viele Programme diese Textdateien (Suchmaschinen benutzen sie beispielsweise zur Indizierung).
Auch dieser Blog hat einen Feed, den man sogar abonnieren kann ;-)
Mit dem Youtube SDK können wir Feeds mit einem C# Programm auslesen, zum Durchsuchen von Youtube benutzen wir den Feed unter http://gdata.youtube.com/feeds/videos?q=Suchbegriff.
Dieser Feed wird von Youtube bereitgestellt und liefert die zu Suchbegriff passenden Ergebnisse in textueller Form, der Feed lässt sich auch im Browser betrachten.

Im Folgenden werde ich den Code erläutern, über den dieser Feed in C# ausgewertet werden kann.
Zuerst müssen die heruntergeladenen Bibliotheken Google.GData.Client.dll und Google.GData.Extensions.dll eingebunden werden.
Diese befinden sich im Redist Verzeichnis des Installationsordners (bei mir C:\Program Files (x86)\Google\Google YouTube SDK for .NET\Redist).
Das Einbinden lässt sich über Projekt - Verweis hinzufügen - Durchsuchen erledigen.
Zum benutzen im Projekt sind dann die Codezeilen

using Google.GData.Client;
using Google.GData.Extensions;

nötig.
Wichtig ist auch, dass unter Projekteigenschaften - Anwendung das Zielframework auf .Net Framework 4 und nicht etwa .Net Framework 4 Client Profile gestellt wird, denn für ersteres wurden die dlls kompilliert und nur hiermit funktioniert der Code.

Ich denke, der kommentierte Code ist eigentlich selbsterklärend, wesentlich hierbei ist, dass die Suchergebnisse letztendlich in Form eines Feeds (beim Programmieren als Objekt vom Typ AtomFeed) vorliegen, wessen Einträge dann ausgelesen werden können.

Das folgende Konsolenprogramm sucht auf Youtube nach dem Begriff "VLC einbinden" und gibt die ersten 10 Ergebnisse auf der Konsole aus:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.Client;
using Google.GData.Extensions;

namespace YoutubeToolkit
{
    class YoutubeQuery
    {
        static void Main(string[] args)
        {
            FeedQuery Abfrage = new FeedQuery(); // Objekt zur Handhabung von Feeds
            Abfrage.Uri = new Uri("http://gdata.youtube.com/feeds/videos?q=VLC+einbinden"); // Feed URL
            Abfrage.StartIndex = 0; // Index, ab welchem die Suchergebnisse angezeigt werden sollen
            Abfrage.NumberToRetrieve = 10; // maximale Anzahl an anzuzeigenden Suchergebnissen

            Service Service = new Service(); // Objekt zur Durchführung der Suchabfrage über das FeedQuery Objekt
            AtomFeed Feed = Service.Query(Abfrage); // Ergebnis der Suchabfrage als Feed

            // für jedes Ergebnis den Titel des Videos ausgeben
            foreach (AtomEntry Ergebnis in Feed.Entries)
            {
                Console.WriteLine(Ergebnis.Title.Text);
            }
        }
    }
}

Montag, 27. Dezember 2010

Ton ausschalten (Windows XP / Vista / 7)

Im Post Ton ausschalten / Lautstärke einstellen stellte ich vor, wie man den PC stumm stellen und die Lautstärke anpassen kann. Die vorgestellte Methode funktioniert allerdings nur mit Windows XP.
Deswegen zeige ich in diesem Post kurz, wie man unter Windows Vista und 7 (aber auch XP kompatibel) den PC stummschalten (muten) kann.
Die Lösung führt uns wieder über die WinAPI,
weswegen folgende using - Direktive nötig ist: using System.Runtime.InteropServices;.
Die benötigte P/Invoke Methode heißt SendMessageW und hat die Signatur IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam).
Diese Funktion schickt eine Nachricht an ein bestimmtes Programm oder Fenster.
Um den Ton am PC auszuschalten, schicken wir den richtigen Befehl an einen Systemprozess.
Und so sieht der Code im Ganzen aus:
Der Deklarationsteil:

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
        private const int WM_APPCOMMAND = 0x319;

Und die Funktion:

private void Mute()
{
    SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle, (IntPtr)APPCOMMAND_VOLUME_MUTE);
}

Freitag, 24. Dezember 2010

Weihnachtspost

using System;
using System.Text;

namespace Weihnachtsprogramm
{
    class Frosty
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}{17}", (char)70, (char)114, (char)111, (char)104, (char)101, (char)32, (char)87, (char)101, (char)105, (char)104, (char)110, (char)97, (char)99, (char)104, (char)116, (char)101, (char)110, (char)33);
        }
    }
}

Dienstag, 7. Dezember 2010

Menüs und Untermenüs dynamisch hinzufügen

In diesem Post widme ich mich den Menüsteuerelementen in C# und zeige, wie man Menüs und Untermenüs zur Laufzeit hinzufügen kann.
Wie ich feststellen musste, ist diese Funktion nämlich nicht ganz klar ersichtlich.
Ich zeige hier meine Methode die über ein paar Umwege läuft, wer also direkteren Code kennt bitte Bescheid sagen.
Ziel des Beispielprogramms soll es sein, folgende Menüstruktur zu erzeugen:

Wir ziehen nun erstmal mit dem Designer ein Steuerelement vom Typ menuStrip auf das Formular (kann natürlich auch dynamisch gemacht werden, siehe Steuerelemente zur Laufzeit hinzufügen).
Nun wird lediglich oben im Formular eine noch unsichtbare Menüleiste bereitgestellt, die aber noch leer ist.
Im Designer kann man jetzt in diese schreiben, um Menüs zu erstellen, wir beschränken uns jedoch auf den dynamischen Teil.
Obermenüs, also Menüs auf höchster Ebene in der Menüleiste (im Beispiel "Obermenü 1" und "Obermenü 2") können über das Attribut Items der Klasse menuStrip bearbeitet werden.
Folgende Codezeilen legen die 2 Obermenüs an:

menuStrip1.Items.Add("Obermenü 1");
menuStrip1.Items.Add("Obermenü 2");

Über einen Index (z.B. über menuStrip1.Items[0]) können wir nun auf die Menüeinträge zugreifen, in diesen aber keine Untermenüs anlegen.
Dafür müssen wir das Objekt explizit in ein Objekt vom Typ ToolStripMenuItem konvertieren. Dieses hat nun die Eigenschaft DropDownItems, über die wir Untermenüs anlegen können.
Um beispielsweise die Untermenüs "Untermenü 1" und "Untermenü 2" zu erzeugen, führen wir folgenden Code aus:

((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems.Add("Untermenü 1");        
((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems.Add("Untermenü 2");

Diese Untermenüs sind nun so ersteinmal nicht mehr greifbar. Wir brauchen sie jedoch, wenn wir weitere Untermenüs anlegen wollen, die nach rechts aufklappen (im Beispiel "rechtes Untermenü 1" und "rechtes Untermenü 2").
Deswegen speichern wir einfach beim Anlegen des Untermenü dieses in einem Objekt vom Typ ToolStripMenuItem, z.B. so:

ToolStripMenuItem Untermenue1 = (ToolStripMenuItem)((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems.Add("Untermenü 1");

(Vor der Zuweisung muss wieder eine explizite Typumwandlung stehen.)
Nun haben wir über die Variable dauerhaft Zugriff auf das gewünschte Untermenü, und können diesem über DropDownItems.Add() eigene Untermenüs hinzufügen.
Hier zum Abschluss der komplette Beispielcode:

            menuStrip1.Items.Add("Obermenü 1");
            menuStrip1.Items.Add("Obermenü 2");

            ToolStripMenuItem Untermenue1 = (ToolStripMenuItem)((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems.Add("Untermenü 1");
            ((ToolStripMenuItem)menuStrip1.Items[0]).DropDownItems.Add("Untermenü 2");

            Untermenue1.DropDownItems.Add("rechtes Untermenü 1");
            Untermenue1.DropDownItems.Add("rechtes Untermenü 2");

Sonntag, 5. Dezember 2010

Tastendruck von mehreren Tasten gleichzeitig prüfen

In den Methoden KeyDown() und KeyPress(), die nahezu jedes Steuerelement implementiert, können Tastaturereignisse untersucht werden.
Der Parameter e vom Typ KeyEventArgs stellt die hierfür benötigten Methoden und Eigenschaften bereit.
So kann z.B. über e.KeyCode geprüft werden, welche Taste gedrückt wurde.
Werden mehrere Tasten (gleichzeitig) gedrückt, wird für jede Taste ein Ereignis aufgerufen, was aber nicht hilft, wenn man den Druck von Tastenkombinationen abfragen möchte.
In diesem Post beschreibe ich, wie man diese Fälle mittels der Eigenschaft KeyData bzw. Flags abdeckt, wobei diese Methoden nur funktionieren, wenn die Kombinationen nur aus Alt und / oder Shift und / oder Strg und / oder maximal einer anderen Taste besteht.
Zuerst über KeyData:
Diese Eigenschaft wird in 4 Bytes gespeichert, die unteren beiden geben die gedrückte Taste wieder, die oberen beiden die gedrückten Funktionstasten (Alt, Shift, Strg (Control)).
Werden mehrere Tasten drückt, werden die Byte - Werte Oder verknüpft.
Drückt man nun nur die Zustandstasten und maximal eine andere Taste, erhält man in KeyData eine eindeutige Bitkombination. Es sollte allerdings klar sein, dass die Eindeutigkeit beim Drücken von mehreren "normalen" Taste nicht mehr gewährleistet ist, da die Bits sich dann überschneiden können.
Zum Prüfen der gedrückten Kombination wird der Wert aus e.KeyData mit einer bitweisen Oder - Verknüpfung des gewünschten Wertes verglichen.
Folgendes Beispiel beendet das Programm, wenn die Tastenkombination Strg + Shift + Alt + "E" gedrückt wurde.

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyData == (Keys.Shift | Keys.Alt | Keys.Control | Keys.E))
        this.Close();
}

Das gleiche Ergebnis lässt sich aber auch erreichen, wenn man über e.KeyCode die gedrückte Taste abfragt und zusätzlich noch die Eigenschaften e.Shift, e.Alt und e.Control überprüft (diese Eigenschaften sind sogenannte Flags), die angeben, ob die entsprechenden Funktionstasten gedrückt sind:

if (e.KeyCode == Keys.E && e.Shift && e.Alt && e.Control)
    this.Close();

Freitag, 3. Dezember 2010

Status eines Netzwerkadapters überprüfen

Im vorigen Post wurde gezeigt, wie man prüfen kann, ob der Computer mit einem Netzwerk verbunden ist, ob also ein beliebiger Netzwerkadapter eine Verbindung hat.
In diesem Post untersuchen wir den Status von nur einer Netzwerkschnittstelle, und das etwas genauer. Wir möchten nun nicht mehr nur zwischen "verbunden" und "nicht verbunden" unterscheiden, sondern mehr Informationen erhalten.
Wir benutzen wieder die Klasse System.Net.NetworkInformation, fragen aber dieses Mal die Eigenschaft OperationalStatus ab.
Diese kann folgende Werte annehmen:
  • Dormant - Die Schnittstelle wartet auf ein externes Ereignis, sie kann keine Daten übertragen.
  • Down - Keine Verbindung.
  • LowerLayerDown - Die Schnittstelle kann keine Daten übertragen, da sie auf "tieferliegende" Schnittstellen zugreift und mindestens eine dieser nicht in Betrieb ist.
  • NotPresent - Nicht funktionsfähig, meistens wegen einem Hardwaredefekt.
  • Testing - Die Schnittstelle führt Tests aus.
  • Unknown - Unbekannter Status.
  • Up - Die Schnittstelle ist in Betrieb.

Ein kleines Beispiel, es listet alle Netzwerkverbindungen auf, die in Betrieb sind:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (System.Net.NetworkInformation.NetworkInterface n in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
            {
                if (n.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up)
                    Console.WriteLine(n.Name + " ist Up.");
            }      
        }
    }
}

Verfügbare Netzwerkadapter auflisten und weitere Informationen anzeigen

Wie im vorigen Post benutzen wir wieder die Klasse System.Net.NetworkInformation. Die Methode NetworkInterface.GetAllNetworkInterfaces() liefert ein Array vom Typ System.Net.NetworkInformation.NetworkInterface zurück, wobei jeder Eintrag eine Netzwerkschnittstelle bzw. einen Netzwerkadapter repräsentiert.
Über dieses Array können wir nun iterieren und so alle verfügbaren Netzwerkadapter auflisten.
Das folgende Beispiel gibt den Namen sowie den Status (wird im nächsten Post näher erläutert) jedes einzelnen aktivierten Netzwerkadapters aus:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (System.Net.NetworkInformation.NetworkInterface n in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
            {
                Console.WriteLine("Name: " + n.Name + " Status: " + n.OperationalStatus.ToString());
            }
        }
    }
}