it-swarm-eu.dev

Zuweisen einer Dateierweiterung zur aktuellen ausführbaren Datei in C #

Ich möchte der aktuellen ausführbaren Datei in C # .. eine Dateierweiterung zuordnen. Wenn der Benutzer die Datei anschließend im Explorer anklickt, wird meine ausführbare Datei mit der angegebenen Datei als erstes Argument ausgeführt. Idealerweise würde es auch das Symbol für die angegebenen Dateierweiterungen auf das Symbol für meine ausführbare Datei setzen. Vielen Dank.

51
Chris

Offenbar gibt es keine .Net-API zum direkten Verwalten von Dateizuordnungen. Sie können jedoch die Registrierungsklassen zum Lesen und Schreiben der benötigten Schlüssel verwenden.

Sie müssen unter HKEY_CLASSES_ROOT einen Schlüssel erstellen, dessen Name auf Ihre Dateierweiterung gesetzt ist (z. B. ".txt"). Setzen Sie den Standardwert dieses Schlüssels auf einen eindeutigen Namen für Ihren Dateityp, z. B. "Acme.TextFile". Erstellen Sie dann unter HKEY_CLASSES_ROOT einen weiteren Schlüssel mit dem Namen "Acme.TextFile". Fügen Sie einen Unterschlüssel mit dem Namen "DefaultIcon" hinzu, und setzen Sie den Standardwert des Schlüssels auf die Datei, die das Symbol enthält, das Sie für diesen Dateityp verwenden möchten. Fügen Sie ein weiteres Geschwister namens "Shell" hinzu. Fügen Sie unter der "Shell" -Taste einen Schlüssel für jede Aktion hinzu, die Sie über das Explorer-Kontextmenü zur Verfügung haben möchten. Setzen Sie den Standardwert für jeden Schlüssel auf den Pfad zu Ihrer ausführbaren Datei, gefolgt von einem Leerzeichen und "% 1", um den Pfad darzustellen auf die ausgewählte Datei.

Im Folgenden finden Sie eine Beispielregistrierungsdatei zum Erstellen einer Verknüpfung zwischen TXT-Dateien und EmEditor:

 Windows Registry Editor Version 5.00 

 [HKEY_CLASSES_ROOT\.txt] 
 @ = "Emeditor.txt" 

 [HKEY_CLASSES_ROOT\emeditor.txt] 
 @ = "Text Dokument "

 [HKEY_CLASSES_ROOT\emeditor.txt\DefaultIcon] 
 @ ="% SystemRoot% \\ SysWow64 \\ imageres.dll, -102 "

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell] 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\open] 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\open\command] 
 @ = "\: C:\\ Programme \\ EmEditor \\ EMEDITOR.EXE\"\"% 1\"" 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print] 

 [HKEY_CLASSES_ROOT\emeditor.txt\Shell\print\command] 
 @ = "\" C: \\ Programme \\ EmEditor \\ EMEDITOR.EXE\"/ p \"% 1\"" 
40
X-Cubed

Wenn Sie sich für die Registrierung entscheiden, denken Sie auch daran, dass die aktuellen Benutzerverbindungen unter HKEY_CURRENT_USER\Software\Classes liegen. Es ist möglicherweise besser, Ihre Anwendung dort anstelle von lokalen Computerklassen hinzuzufügen.

Wenn Ihr Programm von eingeschränkten Benutzern ausgeführt wird, können Sie CLASSES_ROOT trotzdem nicht ändern.

25
Ishmaeel

Wenn Sie die ClickOnce-Bereitstellung verwenden, wird dies alles für Sie erledigt (zumindest in VS2008 SP1). einfach:

  • Projekteigenschaften
  • Veröffentlichen
  • Optionen
  • Dateizuordnungen
  • (fügen Sie hinzu, was Sie brauchen)

(Beachten Sie, dass es voll vertrauenswürdig sein muss und .NET 3.5 als Ziel haben muss.

Siehe auch MSDN: Gewusst wie: Erstellen von Dateizuordnungen für eine ClickOnce-Anwendung

11
Marc Gravell

Hier ist ein vollständiges Beispiel:

public class FileAssociation
{
    public string Extension { get; set; }
    public string ProgId { get; set; }
    public string FileTypeDescription { get; set; }
    public string ExecutableFilePath { get; set; }
}

public class FileAssociations
{
    // needed so that Explorer windows get refreshed after the registry is updated
    [System.Runtime.InteropServices.DllImport("Shell32.dll")]
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);

    private const int SHCNE_ASSOCCHANGED = 0x8000000;
    private const int SHCNF_FLUSH = 0x1000;

    public static void EnsureAssociationsSet()
    {
        var filePath = Process.GetCurrentProcess().MainModule.FileName;
        EnsureAssociationsSet(
            new FileAssociation
            {
                Extension = ".binlog",
                ProgId = "MSBuildBinaryLog",
                FileTypeDescription = "MSBuild Binary Log",
                ExecutableFilePath = filePath
            },
            new FileAssociation
            {
                Extension = ".buildlog",
                ProgId = "MSBuildStructuredLog",
                FileTypeDescription = "MSBuild Structured Log",
                ExecutableFilePath = filePath
            });
    }

    public static void EnsureAssociationsSet(params FileAssociation[] associations)
    {
        bool madeChanges = false;
        foreach (var association in associations)
        {
            madeChanges |= SetAssociation(
                association.Extension,
                association.ProgId,
                association.FileTypeDescription,
                association.ExecutableFilePath);
        }

        if (madeChanges)
        {
            SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
        }
    }

    public static bool SetAssociation(string extension, string progId, string fileTypeDescription, string applicationFilePath)
    {
        bool madeChanges = false;
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + extension, progId);
        madeChanges |= SetKeyDefaultValue(@"Software\Classes\" + progId, fileTypeDescription);
        madeChanges |= SetKeyDefaultValue([email protected]"Software\Classes\{progId}\Shell\open\command", "\"" + applicationFilePath + "\" \"%1\"");
        return madeChanges;
    }

    private static bool SetKeyDefaultValue(string keyPath, string value)
    {
        using (var key = Registry.CurrentUser.CreateSubKey(keyPath))
        {
            if (key.GetValue(null) as string != value)
            {
                key.SetValue(null, value);
                return true;
            }
        }

        return false;
    }
9
Kirill Osenkov

Es kann bestimmte Gründe dafür geben, warum Sie kein Installationspaket für Ihr Projekt verwenden. Ein Installationspaket ist jedoch ein großartiger Ort, um Anwendungskonfigurationsaufgaben wie das Registrieren von Dateierweiterungen, Hinzufügen von Desktop-Verknüpfungen usw. einfach auszuführen.

So erstellen Sie eine Dateierweiterungszuordnung mit den integrierten Installationstools von Visual Studio:

  1. Fügen Sie in Ihrer vorhandenen C # -Lösung ein neues Projekt hinzu, und wählen Sie als Other Project Types -> Setup and Deployment -> Setup Project den Projekttyp aus (oder versuchen Sie den Setup-Assistenten).

  2. Konfigurieren Sie Ihr Installationsprogramm (viele vorhandene Dokumente dazu, wenn Sie Hilfe benötigen)

  3. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Setup-Projekt, wählen Sie View -> File Types aus und fügen Sie dann die Erweiterung hinzu, die Sie zusammen mit dem Programm registrieren möchten, um es auszuführen.

Diese Methode hat den zusätzlichen Vorteil, dass sie selbst nach dem Aufräumen entfernt wird, wenn ein Benutzer die Deinstallation für Ihre Anwendung ausführt.

7
Paul J

Um auf die "Windows-Registrierung" zu achten:

Ich erstelle Schlüssel unter HKEY_CURRENT_USER\Software\Classes (wie Ishmaeel sagte)

und befolgen Sie die Anweisungen von X-Cubed.

Der Beispielcode sieht folgendermaßen aus:

private void Create_abc_FileAssociation()
{
    /***********************************/
    /**** Key1: Create ".abc" entry ****/
    /***********************************/
    Microsoft.Win32.RegistryKey key1 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key1.CreateSubKey("Classes");
    key1 = key1.OpenSubKey("Classes", true);

    key1.CreateSubKey(".abc");
    key1 = key1.OpenSubKey(".abc", true);
    key1.SetValue("", "DemoKeyValue"); // Set default key value

    key1.Close();

    /*******************************************************/
    /**** Key2: Create "DemoKeyValue\DefaultIcon" entry ****/
    /*******************************************************/
    Microsoft.Win32.RegistryKey key2 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key2.CreateSubKey("Classes");
    key2 = key2.OpenSubKey("Classes", true);

    key2.CreateSubKey("DemoKeyValue");
    key2 = key2.OpenSubKey("DemoKeyValue", true);

    key2.CreateSubKey("DefaultIcon");
    key2 = key2.OpenSubKey("DefaultIcon", true);
    key2.SetValue("", "\"" + "(The icon path you desire)" + "\""); // Set default key value

    key2.Close();

    /**************************************************************/
    /**** Key3: Create "DemoKeyValue\Shell\open\command" entry ****/
    /**************************************************************/
    Microsoft.Win32.RegistryKey key3 = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software", true);

    key3.CreateSubKey("Classes");
    key3 = key3.OpenSubKey("Classes", true);

    key3.CreateSubKey("DemoKeyValue");
    key3 = key3.OpenSubKey("DemoKeyValue", true);

    key3.CreateSubKey("Shell");
    key3 = key3.OpenSubKey("Shell", true);

    key3.CreateSubKey("open");
    key3 = key3.OpenSubKey("open", true);

    key3.CreateSubKey("command");
    key3 = key3.OpenSubKey("command", true);
    key3.SetValue("", "\"" + "(The application path you desire)" + "\"" + " \"%1\""); // Set default key value

    key3.Close();
}

Zeigen Sie einfach eine kurze Demo, die sehr leicht zu verstehen ist. Sie können diese Schlüsselwerte ändern und alles ist gut für Sie.

5
Strong

Die Dateizuordnungen sind in der Registry unter HKEY_CLASSES_ROOT definiert.

Es gibt ein VB.NET-Beispiel hier , das Sie problemlos nach C # portieren können.

2
Steve Morgan

Der folgende Code ist eine Funktion, die funktionieren sollte. Er fügt die erforderlichen Werte in der Windows-Registrierung hinzu. Normalerweise führe ich SelfCreateAssociation (". Abc") in meiner ausführbaren Datei aus. (Formularkonstruktor oder Onload oder Onshown) Er aktualisiert den Registrierungseintrag für den aktuellen Benutzer jedes Mal, wenn die ausführbare Datei ausgeführt wird. (Gut für das Debuggen, wenn Sie Änderungen vorgenommen haben.) Wenn Sie detaillierte Informationen zu den betroffenen Registrierungsschlüsseln benötigen, überprüfen Sie diesen MSDN-Link.

https://msdn.Microsoft.com/en-us/library/windows/desktop/dd758090(v=vs.85).aspx

Weitere Informationen zum allgemeinen Registrierungsschlüssel ClassesRoot erhalten. Siehe diesen MSDN-Artikel.

https://msdn.Microsoft.com/en-us/library/windows/desktop/ms724475(v=vs.85).aspx

public enum KeyHiveSmall
{
    ClassesRoot,
    CurrentUser,
    LocalMachine,
}

/// <summary>
/// Create an associaten for a file extension in the windows registry
/// CreateAssociation(@"vendor.application",".tmf","Tool file",@"C:\Windows\SYSWOW64\notepad.exe",@"%SystemRoot%\SYSWOW64\notepad.exe,0");
/// </summary>
/// <param name="ProgID">e.g. vendor.application</param>
/// <param name="extension">e.g. .tmf</param>
/// <param name="description">e.g. Tool file</param>
/// <param name="application">e.g.  @"C:\Windows\SYSWOW64\notepad.exe"</param>
/// <param name="icon">@"%SystemRoot%\SYSWOW64\notepad.exe,0"</param>
/// <param name="Hive">e.g. The user-specific settings have priority over the computer settings. KeyHive.LocalMachine  need admin rights</param>
public static void CreateAssociation(string ProgID, string extension, string description, string application, string icon, KeyHiveSmall Hive = KeyHiveSmall.CurrentUser)
{
    RegistryKey selectedKey = null;

    switch (Hive)
    {
        case KeyHiveSmall.ClassesRoot:
            Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(ProgID);
            break;

        case KeyHiveSmall.CurrentUser:
            Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + ProgID);
            break;

        case KeyHiveSmall.LocalMachine:
            Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + extension).SetValue("", ProgID);
            selectedKey = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"Software\Classes\" + ProgID);
            break;
    }

    if (selectedKey != null)
    {
        if (description != null)
        {
            selectedKey.SetValue("", description);
        }
        if (icon != null)
        {
            selectedKey.CreateSubKey("DefaultIcon").SetValue("", icon, RegistryValueKind.ExpandString);
            selectedKey.CreateSubKey(@"Shell\Open").SetValue("icon", icon, RegistryValueKind.ExpandString);
        }
        if (application != null)
        {
            selectedKey.CreateSubKey(@"Shell\Open\command").SetValue("", "\"" + application + "\"" + " \"%1\"", RegistryValueKind.ExpandString);
        }
    }
    selectedKey.Flush();
    selectedKey.Close();
}

 /// <summary>
    /// Creates a association for current running executable
    /// </summary>
    /// <param name="extension">e.g. .tmf</param>
    /// <param name="Hive">e.g. KeyHive.LocalMachine need admin rights</param>
    /// <param name="description">e.g. Tool file. Displayed in Explorer</param>
    public static void SelfCreateAssociation(string extension, KeyHiveSmall Hive = KeyHiveSmall.CurrentUser, string description = "")
    {
        string ProgID = System.Reflection.Assembly.GetExecutingAssembly().EntryPoint.DeclaringType.FullName;
        string FileLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
        CreateAssociation(ProgID, extension, description, FileLocation, FileLocation + ",0", Hive);
    }
2
Carsten R.

Seit Windows 7 gibt es zwei cmd-Tools, mit denen sich einfache Dateizuordnungen sehr einfach erstellen lassen. Sie sind assoc und ftype . Hier ist eine grundlegende Erklärung jedes Befehls.

  • Assoc - ordnet eine Dateierweiterung (wie '.txt') einem "Dateityp" zu.
  • FType - definiert eine ausführbare Datei, die ausgeführt wird, wenn der Benutzer einen bestimmten "Dateityp" öffnet.

Beachten Sie, dass dies Cmd-Tools und keine ausführbaren Dateien (exe) sind. Dies bedeutet, dass sie nur in einem Cmd-Fenster oder mithilfe von ShellExecute mit "cmd/c assoc" ausgeführt werden können. Sie können mehr über die Links erfahren oder "assoc /?" und "ftype /?" bei einem cmd Prompt. 

Um eine Anwendung mit der Erweiterung .bob zu verknüpfen, können Sie ein Cmd-Fenster öffnen (WindowKey + R, geben Sie cmd ein, drücken Sie die Eingabetaste) und führen Sie Folgendes aus:

assoc .bob=BobFile
ftype BobFile=c:\temp\BobView.exe "%1"

Dies ist viel einfacher als das Durcheinander mit der Registry, und es ist wahrscheinlicher, dass es in zukünftigen Windows-Versionen funktioniert. 

Zusammenfassend ist hier eine C # -Funktion zum Erstellen einer Dateizuordnung:

public static int setFileAssociation(string[] extensions, string fileType, string openCommandString) {
    int v = execute("cmd", "/c ftype " + fileType + "=" + openCommandString);
    foreach (string ext in extensions) {
        v = execute("cmd", "/c assoc " + ext + "=" + fileType);
        if (v != 0) return v;
    }
    return v;
}
public static int execute(string exeFilename, string arguments) {
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = false;
    startInfo.UseShellExecute = true;
    startInfo.FileName = exeFilename;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.Arguments = arguments;
    try {
        using (Process exeProcess = Process.Start(startInfo)) {
            exeProcess.WaitForExit();
            return exeProcess.ExitCode;
        }
    } catch {
        return 1;
    }
}
0
Mike