Mittwoch, 11. April 2012

C# Anwendung als Standardprogramm zum Öffnen von Dateiendungen machen

Unter Windows ist vielen Dateiendungen ein Standardprogramm zugeordnet, mit welchem die Datei per Doppelklick geöffnet wird.
So wird zum Beispiel die Endung ".docx" Word und die Endung ".txt" einem Texteditor zugeordnet sein.
In diesem Post möchte ich zeigen, wie man eine neue oder bereits vorhandene Dateiendung der eigenen C# Anwendung (oder auch einem anderen Programm) zuordnet, sodass Dateien dieses Typs mit der Anwendung geöffnet werden.

Wo wird diese Zuordnung überhaupt festgelegt? In der Windows Registry.
Um diese also zu ändern, müssen wir "lediglich" in dieser die richtigen Schlüssel ändern.
Die Beispielanwendung, die dieses erledigt, muss einerseits mit Administrationsrechten laufen und andererseits setze ich im Code grundlegende Kenntnisse über die Arbeit in der Registry vorraus.
Wer mit diesen beiden Sachen noch nicht so ganz vertraut ist, kann sich zum Beispiel in den verlinkten Posts informieren.

In der Registry gibt es zu jeder registrierten Endung in der Oberkategorie HKEY_CLASSES_ROOT einen Schlüssel.
Dieser trägt zum Beispiel den Namen ".docx".
Für unsere Zwecke ist es ausreichend zu wissen, dass der Standardwert dieses Schlüssels den Namen der Anwendung enthält, mit dem die Endung standardmäßig geöffnet wird.
Mit diesem Namen gibt es ebenfalls einen Schlüssel in HKEY_CLASSES_ROOT, welcher die Anwendung beschreibt.
In diesem Schlüssel ist die Unterschlüsselkette "shell - Open - Command" wichtig.
In "Command" enthält der Standardwert den Link auf die ausführbare Datei der Anwendung, also z.B. "C:\Program Files (x86)\Microsoft Office\Office14\WINWORD.EXE"
Ist diesem Pfad noch ein "%1" nachgestellt, bedeudet dies, dass dem Programm die geöffnete Datei mit übergeben wird, in C# finden wir den Pfad zu dieser dann in den Befehlszeilenargumenten wieder.

Folgender Codeschnipsel legt oben beschriebene Registry Struktur an (using Microsoft.Win32 wird benötigt):


                RegistryKey Standards = Registry.ClassesRoot;
                Standards.CreateSubKey(".xyz");
                RegistryKey XYKey = Standards.OpenSubKey(".xyz", true);
                XYKey.SetValue("", "MyCSharpApp");

                RegistryKey SCKey = Standards.CreateSubKey("MyCSharpApp");
                RegistryKey ShKey = SCKey.CreateSubKey("shell");
                RegistryKey OpKey = ShKey.CreateSubKey("Open");
                RegistryKey CmdKey = OpKey.CreateSubKey("Command");
                CmdKey.SetValue("", Application.StartupPath + "\\MyCSharpApp.exe %1");