Recherche de l'application par défaut pour l'ouverture d'un type de fichier particulier sous Windows
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.
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());
}
}