Encontrar la aplicación predeterminada para abrir un tipo de archivo en particular en Windows

Estoy desarrollando una aplicación dirigida a .NET Framework 2.0 usando C # para lo cual necesito poder encontrar la aplicación predeterminada que se usa para abrir un tipo de archivo en particular.

Sé que, por ejemplo, si solo quieres abrir un archivo con esa aplicación puedes usar algo como:

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

para abrir un documento HTML en el navegador predeterminado, o

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

para abrir un archivo de texto en el editor de texto predeterminado.

Sin embargo, lo que quiero hacer es abrir archivos que no necesariamente tienen una extensión .txt (por ejemplo), en el editor de texto predeterminado, así que necesito poder encontrar la aplicación predeterminada para abrir . txt , lo que me permitirá invocarlo directamente.

Supongo que hay alguna API de Win32 que necesitaré para P / invocar para hacer esto, sin embargo, un vistazo rápido con Google y MSDN no reveló nada de mucho interés; Encontré una gran cantidad de páginas completamente irrelevantes, pero nada de lo que estoy buscando.

Puede verificar en la sección de registro HKEY_CLASSES_ROOT la extensión y los detalles de la acción. La documentación para esto está en MSDN . Alternativamente, puede usar la interfaz IQueryAssociations .

Todas las respuestas actuales no son confiables. El registro es un detalle de implementación y, de hecho, dicho código está roto en mi máquina con Windows 8.1. La forma correcta de hacerlo es usar la API de Win32, específicamente 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 } 

Documentación relevante:

  • AssocQueryString
  • ASSOCF
  • ASSOCSTR

Uso de muestra:

 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! Por supuesto.

 HKEY_CLASSES_ROOT\.txt 

incluye una referencia a

 HKEY_CLASSES_ROOT\txtfile 

que contiene una subclave

 HKEY_CLASSES_ROOT\txtfile\shell\open\command 

que hace referencia al Bloc de notas.

Ordenado, muchas gracias!

Bart

Aquí hay una publicación de blog sobre este tema. Los ejemplos de código están en VB.net, pero debería ser fácil portarlos a C #.

Solo puede consultar el registro. Primero obtén la entrada Predeterminada en HKEY_CLASSES_ROOT \ .ext

Eso te dará el nombre de clase. Por ejemplo, .txt tiene un valor predeterminado de txtfile

A continuación, abra HKEY_CLASSES_ROOT \ txtfile \ Shell \ Open \ Command

Eso le dará el comando predeterminado utilizado.

Una respuesta tardía, pero hay un buen paquete NUGET que maneja asociaciones de archivos: File Association

Enlace NUGET File Association

El uso es simple, por ejemplo, para agregar todas las extensiones de archivo permitidas a un menú contextual:

 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()); } }