Laden...

Eigenes Dateiformat einrichten

Erstellt von SeeQuark vor 15 Jahren Letzter Beitrag vor 15 Jahren 8.117 Views
SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren
Eigenes Dateiformat einrichten

In einem Programm habe ich ein eigenes Dateiformat erstellt. Nun möchte ich per Code
- diesem Format ein eigenes Icon zuweisen, sowie
- mein Programm als Standardprogramm zum Öffnen dieses Datentyps festlegen.

16.835 Beiträge seit 2008
vor 15 Jahren

Da gibts in der Windows Registry den HKEY_CLASSES_ROOT -Pfad.
Dort sind die einzelnen, bekannten Dateitypen drin, sowie mit einer "OpenWithList" versehen.

Ob und wie das mit C# direkt geht weiß ich nicht.
Aber ist ja wenigstens nen Anfang ;o)

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Danke für den Tip 🙂! Den RegistryKey Registry.ClassesRoot habe ich gefunden. Nur finde ich mich nicht in der Klasse zurecht 😦. Die "OpenWithList" konnte ich nicht finden.

Hier die Eigenschaften und Member der Klasse Registry:

public string Name { get; }
public int SubKeyCount { get; }
public int ValueCount { get; }

public void Close();
public RegistryKey CreateSubKey(string subkey);
public RegistryKey CreateSubKey(string subkey, RegistryKeyPermissionCheck permissionCheck);
public Registr yKey CreateSubKey(string subkey, RegistryKeyPermissionCheck permissionCheck, RegistrySecurity registrySecurity);
public void DeleteSubKey(string subkey);
public void DeleteSubKey(string subkey, bool throwOnMissingSubKey);
public void DeleteSubKeyTree(string subkey);
public void DeleteValue(string name);
public void DeleteValue(string name, bool throwOnMissingValue);
public void Flush();
public RegistrySecurity GetAccessControl();
public RegistrySecurity GetAccessControl(AccessControlSections includeSections);
public string[] GetSubKeyNames();
public object GetValue(string name);
public object GetValue(string name, object defaultValue);
public object GetValue(string name, object defaultValue, RegistryValueOptions options);
public RegistryValueKind GetValueKind(string name);
public string[] GetValueNames();
public static RegistryKey OpenRemoteBaseKey(RegistryHive hKey, string machineName);
public RegistryKey OpenSubKey(string name);
public RegistryKey OpenSubKey(string name, bool writable);
public RegistryKey OpenSubKey(string name, RegistryKeyPermissionCheck permissionCheck);
public RegistryKey OpenSubKey(string name, RegistryKeyPermissionCheck permissionCheck, RegistryRights rights);
public void SetAccessControl(RegistrySecurity registrySecurity);
public void SetValue(string name, object value);
public void SetValue(string name, object value, RegistryValueKind valueKind);
public override string ToString();

16.835 Beiträge seit 2008
vor 15 Jahren

Mach einfach ma die Registry mit RegEdit auf und schau wie die Keys, zB .txt aufgebaut sind.
OpenWithList ist nen Unter"Key" von .txt

5.941 Beiträge seit 2005
vor 15 Jahren

Salute See Sharp

Such mal hier im Forum nach "Registry" / "Registrierung" und "Dateiformat"....
Da ist schon einiges vorhanden, bitte die besten Links posten, danke.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Bitte die besten Links posten, danke

Habe folgende Links gefunden:Herausfinden welches Programm einen Dateityp öffnet!
Galileo Openbook

J
237 Beiträge seit 2008
vor 15 Jahren

Hier ist eine Freeware-Klasse die genau das kann: http://mentalis.org/soft/class.qpx?id=5

Beim Programmieren löst man die Probleme, die man nicht hätte, programmierte man nicht.

1.044 Beiträge seit 2008
vor 15 Jahren

Hallo See Sharp,

ich hatte über dieses Thema vor langer Zeit mal ein Tutorial geschrieben, jedoch nicht ganz zuende gebracht. Es sind noch einige Fehler dabei und es ist nicht vollständig, aber ich hoffe es macht dir keine Umstände! Nun gut, hier das Tutorial:

Ein Dateiformat einrichten:

da es bei größeren Projekten manchmal sinnvoll ist ein eigenes Dateiformat zu haben, wie beispielsweise "MeineDatei.xyz" mit einen eigenen Icon, Dateityp(frei wählbar) und ein erweiterten Kontextmenü, wenn man auf die Datei mit rechtsklickt anklickt, möchte es dies kurz erläutern. Mit diesen Dateien sind Dateien gemeint, welche auf der Windows-Oberfläche sind. Nehmen wir den Windows-Media-Player bzw. eine MP3-Datei, welches sich mit Windows-Media-Player öffnen lässt. Wenn wir diese datei mittels rechtklick anschauen öffnet sich ein Kontextmenü mit einigen Einträgen vom Windows-Media-Player. Auch mit anderen Programmen wie beispielsweise WinRAR ist es sehr toll zu erkennen. So ein eigenes Dateiformat zu implementieren sind einige Einträge im Registery notwenig, d.h. möchte ich darauf hinweisen, dass man sorgfältig sein sollte und nicht versehendlich Fehler unterlaufen! Es sollten auch Kenntnisse vorausgesetzt sein über das Registery, also das man weiß was ein Schlüssel oder eine Zeichenfolge ist.

Für das erstellen für Einträge gibt es die Möglichkeit in C# die die Registry-Klase zu verwenden, die sich im Namensraum Microsoft.Win32 befindet, somit muss man das using-Klausel verwenden.

using Microsoft.Win32;

Unsere Informationen müssen in Registery unter HKEY_CLASSES_ROOT gespeichert werden bzw. unter HKEY_CLASSES_ROOT.xyz. Das ".xyz" ist der Platzhalter dafür für das Format, was wir verwenden wollen. Wir können natürlich .xyz verwenden oder ein anderes Format verwenden - es ist euch überlassen. Als zweiten Schritt brauchen wir ein Icon, am besten im .ico-Format. Um nun das Symbol des Icons auf das Dateiformat zuzuweisen müssen wir unter den Pfad HKEY_CLASSES_ROOT.xyz einen Unterschlüssel mit dem Namen: DefaultIcon hinzufügen. Unter DefaultIcon gibt es einen Standardwert der noch leer ist. In diesen Eintrag fügen wir nun den Pfad des Icons ein. Falls wir kein Icon zuweisen wird es trozdem funktionieren, jedoch wird kein Icon angezeigt sondern ein "Fehler"-Icon von Windows. Alternativ gibt es die Möglichkeit aus den Resourcen einer Anwendung es zuzuweisen. Wollen wir es mittels einer Resource zuweisen müssen wir den Pfad der Anwendung und ein "-123" hinzufügen. Die Zahl "123" muss natürlich mit der Resource übereinstimmen!

Fügen wir nun die folgenden Einträge in das Registery ein und staren den Computer neu(oder beenden wir die explorer.exe und starten diese wieder) und erstellen eine Datei mit den von euch gewählen Format wird nun das entsprechende Icon angezeigt. Der erste Schritt ist nun gemacht. Nun folgt der nächste Schritt, wie man damit ein Programm öffnen und die Datei anzeigen lassen kann.

Wie wir in den Beispiel von Windows-Media-Player gesehen habe gibt es dort auch ein erweitertes Kontextmenü. Um das zu erzielen müssen wir im Reistery einige weitere Einträge erstellen. Für das Kontextmenü müsen wir den Schlüssel unter HKEY_CLASSES_ROOT.DATEIFORMAT mit dem Namen "shell" erstellen. Die Namen der Einträge die im Kontextmenü angezeigt werden sollen müssen einen Unterordner im Schlüssel "shell" haben. Fügen wir einfach zwei Schlüssel hinzu mit den Namen "Eintrag1" und "Eintrag2". Für jeden dieser Einträge müssen wir einen Schlüssel mit dem Namen "command" erstellen! In den Standard-Wert müssen wir die Befehle festlegen. Nun ist es wichtig, dass wir ein Programm haben womit auch Argumente/Paramter übergeben werden können. Die Argumente von C# sehen folgendermaßen aus:

static void Main(string[] args)

die Variable "args" ist ein Array für jedes Argument was wir übergeben. Somit ist es wichtig, dass wenn wir nun ein eigenes Dateiformat erstellen auch über die "args" arbeiten. Nehmen wir das Beispiel von Notepad mit dem .txt Format. Erstellen wir eine Textdatei und schreiben wir einen Text und öffnen es mit einen anderen Editor wie Word wird der eingegebene Text trozdem angezeigt. Nun, Warum? In beiden Editoren gibt es es die Paramter. Man kann somit über die Kommandozeile Notepad eine Datei öffnen, indem wir es folgendermaßen schreiben:

"%windir%\notepad.exe PfadDerTextdatei.txt"
// %windir% ist eine Variable die für das Windows-Verzeich steht.

Damit wir diese Funktionsweise in unseren Programm auch haben müssen wir über die Argrumente die Textdatei ermitteln und diese einlesen. Es können natürlich auch andere Befehle ausgeführt werden. Der letze und wichtigste Schritt ist nun unseren Dateiformat das gewünschte Programm zuzuweisen. Wollen wir die selbe Funktionsweise wie von Notepad erziehlen, also .txt-Dateien einlesen und darstellen so müssen wir mittels StreamReader die Datei über die Argumte ermitteln und einlesen bzw. darstellen. .... %1 ... !

Damit es ein wenig klarer wird sind im Anhang noch eine simple Anwendung programmiert und ein kleinen Screenshot.

zero_x =)

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Hallo zero_x
Ersteinmals danke für dieses gute Tutorial, aber hast wohl den Dateianhang vergessen 😉!

Leider habe ich Probleme mit folgendem Teil:

Um nun das Symbol des Icons auf das Dateiformat zuzuweisen müssen wir unter den Pfad HKEY_CLASSES_ROOT.xyz einen Unterschlüssel mit dem Namen: DefaultIcon hinzufügen. Unter DefaultIcon gibt es einen Standardwert der noch leer ist.

Unter regedit.exe konnte ich keinen Eintrag mit DefaultIcon finden.
Mit C# hat es allerdings auch nicht geklappt. Mein Code mit Fehlermeldung:


RegistryKey rk = Registry.ClassesRoot.CreateSubKey(".xyz"); // funktioniert einwandfrei
rk = rk.CreateSubKey("DefaultIcon");                        // löst UnauthorizedAccessException aus 

Der Zugriff auf den Registrierungsschlüssel "HKEY_CLASSES_ROOT.xyz\DefaultIcon" wurde verweigert.

Was ich da etwas falsch gemacht?

1.044 Beiträge seit 2008
vor 15 Jahren

Hallo See Sharp,

versuch doch einfach im Registry einen Untereintrag anzulesen, mit dem Namen DefaultIcon. Als Standardwert musst du den Pfad des Icons zuweisen.

zero_x

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Mit welchem Member sollte das gehen? Der Pfad "....xyz\DefaultIcon" existiert nicht und keine Überladung von RegistryKey.CreateSubKey(...) und RegistryKey.OpenSubKey(...) nimmt 2 strings als Argument an
Den Pfad des Icons kann ich also gar nicht angeben 😦.

1.820 Beiträge seit 2005
vor 15 Jahren

Hallo!

Bitte schaue dir zunächst die Doku der Registry-Klasse an. Mit OpenSubKey öffnet man Schlüssel, die Werte werden mit weiteren Methoden bearbeitet. In der MSDN finden sich sogar Beispiele dazu, die dir weiterhelfen sollten.

Nobody is perfect. I'm sad, i'm not nobody 🙁

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Hallo zurück!

Die MSDN nützte mir nicht besonders viel, da ich erst seit 2 Jahren Englisch lerne (bin ein Schüler der seit erst weniger als einem Jahr angefangen hat, zu programmieren). Jetzt hat es aber doch geklappt, der regedit.exe zeigt aber erst jetzt den SubKey "DefaultIcon" an.

1.044 Beiträge seit 2008
vor 15 Jahren

Hallo See Sharp,

alternativ kannst du eine Registrierungsdatei anlegen und diese ausführen.

zero_x

P.S.: die meisten Dokumentationen sind auf Englisch geschrieben und es wird auch auf Englisch programmiert. 😉

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo See Sharp,

Die MSDN nützte mir nicht besonders viel, da ich erst seit 2 Jahren Englisch lerne (bin ein Schüler der seit erst weniger als einem Jahr angefangen hat, zu programmieren).

gibt es alles auf deutsch. Siehe :rtfm:

Siehe auch Anfänger und die MSDN-Doku - Ein Widerspruch?

herbivore

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Hallo Herbvoire
wenn ich unter der MSDN-Suche "RegistryKey" eingegeben habe (war öfters) erschienen:

Fehler bei der Suche
Der Wert für einen Int32 war zu gross oder zu klein
klicken sie auf :::

Bei den englischen Ergebnissen wurden dagegen 100 angezeigt (und wahrscheinlich noch mehr gefunden).

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo See Sharp,

dann scheint bei dir die Doku leider nicht richtig installiert zu sein. Eigentlich sollte deine Vorgehensweise problemlos funktionieren. Davon abgesehen ist es meistens schneller und besser den Index statt der Suche zu verwenden.

herbivore

M
198 Beiträge seit 2007
vor 15 Jahren

im Zweifel Google -> [Gesuchte Klasse] msdn, also Registrykey msdn -> zu 99% ist der erste Eintrag der englische MSDN Eintrag, und an zweiter Stelle der deutsche

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Hallo herbivore
Ich habe die MSDN schon unzählige Male erfolgreich benutzt und noch nie einen Fehler erhalten. Mag sein, dass sie irgendwie einen Fehler hat, aber die Quote liegt weit unter 0.1%, meiner Meinung nach kein Grund sie neu zu installieren.
Den Index habe ich vorher noch nicht genutzt, er ist aber wirklich besser und vor allem schneller als die Suche.

@MaXeM
Dies habe ich im nachhinein auch gemacht und auch eine deutsche Beschreibung von der Klasse Registrykey gefunden.

See Sharp

J
1.114 Beiträge seit 2007
vor 15 Jahren

Solche Dateizuordnungsgeschichten sind normalerweise Aufgabe des Installers. Ich würde aus mehreren Gründen nicht direkt in der Registry rumfuschen:

  1. Du bist nicht sicher obs auf allen Windows Versionen wirklich korrekt funktioniert, grad was künftige Versionen angehet

  2. Normaler User haben keine SchreibtRechte auf die Registry. Daher muss eh ein Adminuser her, der ja auch die Anwendung installiert.

Der 2. Punkt ist natürlich nur von Relevanz in Systemen, wo die Benutzer eben kein Admin Account haben. Privat natürlich eher unüblich, aber in Firmen natürlich Standard.

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

Hallo Jelli,

Solche Dateizuordnungsgeschichten sind normalerweise Aufgabe des Installers.

Vermutlich hast du Recht (ich weiss das nicht so genau). Die Argumente kann ich aber nachvollziehen.
über den Windows Installer wollte ich mich sowieso schon bilden und das werde ich jetzt auch machen. Melde mich wieder wenn ich eine Frage habe.

See Sharp =)

199 Beiträge seit 2006
vor 15 Jahren

Unter regedit.exe konnte ich keinen Eintrag mit DefaultIcon finden.
Mit C# hat es allerdings auch nicht geklappt. Mein Code mit Fehlermeldung:

  
RegistryKey rk = Registry.ClassesRoot.CreateSubKey(".xyz"); // funktioniert einwandfrei  
rk = rk.CreateSubKey("DefaultIcon");                        // löst UnauthorizedAccessException aus   

Der Zugriff auf den Registrierungsschlüssel "HKEY_CLASSES_ROOT.xyz\DefaultIcon" wurde verweigert.

Was ich da etwas falsch gemacht?

  1. Normaler User haben keine SchreibtRechte auf die Registry. Daher muss eh ein Adminuser her, der ja auch die Anwendung installiert.

Und damit ist das Problem eigentlich auch schon erklärt. .NET arbeitet in der Regel mit eingeschränkten Rechten, so weit ich informiert bin. Dadurch ist es nicht so ohne weiteres möglich auf die Registry schreibend zuzugreifen. Ich würde aber auf jeden Fall auch den Weg über den Installer empfehlen. Der Vorteil daran ist, dass die Schlüssel dann auch beim Deinstallieren wieder entfernt werden können.
Ich weiß jetzt nur den Weg über InnoSetup. Hier ist es kein Problem ein paar Registry-Schlüssel anlegen zu lassen. Ich vermisse diese Funktion allerdings beim Visual-Studio Setup-Projekt. Oder ich hab sie einfach noch nicht gesehen.

SeeQuark Themenstarter:in
946 Beiträge seit 2008
vor 15 Jahren

.NET arbeitet in der Regel mit eingeschränkten Rechten, so weit ich informiert bin. Dadurch ist es nicht so ohne weiteres möglich auf die Registry schreibend zuzugreifen.

Das stimmt nicht ganz! Ich konnte in die Registry schreiben.


RegistryKey rk = Registry.ClassesRoot.CreateSubKey(".xyz"); // funktioniert
rk.SetValue("DefaultIcon", @"C:\*pfad*\xyzFile.ico");       // klappt auch

Jetzt hat es aber doch geklappt, der regedit.exe zeigt aber erst jetzt den SubKey "DefaultIcon" an.

Im Nachhinein (ein bisschen zu spät) habe ich aber gemerkt, das das Icon gar nicht geändert wurde. Mit einem Installer sollte dies aber zu beheben sein.