Recherche de l'application par défaut pour l'ouverture d'un type de fichier particulier sous Windows

StackOverflow https://stackoverflow.com/questions/162331

  •  03-07-2019
  •  | 
  •  

Question

Je développe une application ciblant .NET Framework 2.0 à l'aide de C # pour laquelle je dois pouvoir trouver l'application par défaut utilisée pour ouvrir un type de fichier particulier.

Je sais que, par exemple, si vous souhaitez simplement ouvrir un fichier à l'aide de cette application, vous pouvez utiliser quelque chose du genre:

System.Diagnostics.Process.Start( "C:\...\...\myfile.html" );

pour ouvrir un document HTML dans le navigateur par défaut ou

System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" );

pour ouvrir un fichier texte dans l'éditeur de texte par défaut.

Cependant, ce que je veux pouvoir faire, c'est ouvrir des fichiers ne portant pas nécessairement l'extension .txt (par exemple), dans l'éditeur de texte par défaut. capable de trouver l'application par défaut pour ouvrir les fichiers .txt , ce qui me permettra de l'invoquer directement.

Je suppose qu'il me faudra p / Invoke pour une API Win32, mais un rapide coup d'œil avec Google et MSDN n'a révélé aucun intérêt particulier; J'ai trouvé un très grand nombre de pages totalement hors de propos, mais rien de tel que je ne cherche.

Était-ce utile?

La solution

Vous pouvez vérifier sous la section de registre HKEY_CLASSES_ROOT les détails de l'extension et de l'action. La documentation à cet effet est sur MSDN . Vous pouvez également utiliser l'interface IQueryAssociations .

Autres conseils

Toutes les réponses actuelles ne sont pas fiables. Le registre est un détail d'implémentation et effectivement, ce code est cassé sur mon ordinateur Windows 8.1. Pour ce faire, utilisez l'API Win32, plus précisément AssocQueryString :

using System.Runtime.InteropServices;

[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(
    AssocF flags, 
    AssocStr str,  
    string pszAssoc, 
    string pszExtra, 
    [Out] StringBuilder pszOut, 
    ref uint pcchOut
); 

[Flags]
public enum AssocF
{
    None = 0,
    Init_NoRemapCLSID = 0x1,
    Init_ByExeName = 0x2,
    Open_ByExeName = 0x2,
    Init_DefaultToStar = 0x4,
    Init_DefaultToFolder = 0x8,
    NoUserSettings = 0x10,
    NoTruncate = 0x20,
    Verify = 0x40,
    RemapRunDll = 0x80,
    NoFixUps = 0x100,
    IgnoreBaseClass = 0x200,
    Init_IgnoreUnknown = 0x400,
    Init_Fixed_ProgId = 0x800,
    Is_Protocol = 0x1000,
    Init_For_File = 0x2000
}

public enum AssocStr
{
    Command = 1,
    Executable,
    FriendlyDocName,
    FriendlyAppName,
    NoOpen,
    ShellNewValue,
    DDECommand,
    DDEIfExec,
    DDEApplication,
    DDETopic,
    InfoTip,
    QuickTip,
    TileInfo,
    ContentType,
    DefaultIcon,
    ShellExtension,
    DropTarget,
    DelegateExecute,
    Supported_Uri_Protocols,
    ProgID,
    AppID,
    AppPublisher,
    AppIconReference,
    Max
}

Documentation pertinente:

Exemple d'utilisation:

static string AssocQueryString(AssocStr association, string extension)
{
    const int S_OK = 0;
    const int S_FALSE = 1;

    uint length = 0;
    uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length);
    if (ret != S_FALSE)
    {
        throw new InvalidOperationException("Could not determine associated string");
    }

    var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination
    ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length);
    if (ret != S_OK)
    {
        throw new InvalidOperationException("Could not determine associated string"); 
    }

    return sb.ToString();
}

Doh! Bien sûr.

HKEY_CLASSES_ROOT\.txt

inclut une référence à

HKEY_CLASSES_ROOT\txtfile

qui contient une sous-clé

HKEY_CLASSES_ROOT\txtfile\shell\open\command

qui fait référence au Bloc-notes.

Trié, merci beaucoup!

Bart

Voici un article de blog sur ce sujet topic. Les exemples de code sont en VB.net, mais il devrait être facile de les porter en C #.

Vous pouvez simplement interroger le registre. Commencez par récupérer l'entrée par défaut sous HKEY_CLASSES_ROOT \ .ext

Cela vous donnera le nom de la classe. Par exemple, .txt a la valeur par défaut txtfile

Ouvrez ensuite HKEY_CLASSES_ROOT \ txtfile \ Shell \ Open \ Command

Cela vous donnera la commande par défaut utilisée.

  

Une réponse tardive, mais un bon package NUGET gère les associations de fichiers: Association de fichiers

Association de fichiers NUGET de liens

L'utilisation est simple, par exemple pour ajouter toutes les extensions de fichier autorisées à un menu contextuel:

private void OnMenuSourceFileOpening(object sender, ...)
{   // open a context menu with the associated files + ".txt" files
    if (File.Exists(this.SelectedFileName))
    {
        string fileExt = Path.GetExtension(this.SelectedFileNames);
        string[] allowedExtensions = new string[] { fileExt, ".txt" };
        var fileAssociations = allowedExtensions
            .Select(ext => new FileAssociationInfo(ext));
        var progInfos = fileAssociations
            .Select(fileAssoc => new ProgramAssociationInfo (fileAssoc.ProgID));
        var toolstripItems = myProgInfos
            .Select(proginfo => new ToolStripLabel (proginfo.Description) { Tag = proginfo });
        // add also the prog info as Tag, for easy access
        //  when the toolstrip item is selected
        // of course this can also be done in one long linq statement

        // fill the context menu:
        this.contextMenu1.Items.Clear();
        this.contextMenuOpenSourceFile.Items.AddRange (toolstripItems.ToArray());
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top