2009-09-07 22 views
38

Me gustaría saber la manera más limpia de registrar una extensión de archivo con mi aplicación C++ para que cuando se haga doble clic en un archivo de datos asociado a mi programa, la aplicación se abra y el nombre de archivo se pasa como un parámetro a la aplicación.Crear entrada de registro para asociar la extensión de archivo con la aplicación en C++

Actualmente, lo hago a través de mi instalador wix, pero hay algunos casos en que la aplicación no se instalará en la computadora del usuario, así que también necesito la opción de crear la clave de registro a través de la aplicación.

Además, ¿esto también significa que si se elimina la aplicación, las entradas no utilizadas en el registro se quedarán por ahí?

Respuesta

68

Su descripción básica del proceso se encuentra en this MSDN article. Las partes claves están en la parte inferior de la lista:

  • Registrar el identificador de programa

Un identificador de programa (en esencia, la clave de registro tipo de archivo) es lo que contiene sus importantes propiedades de tipo de archivo, como icono, descripción y elementos del menú contextual, incluida la aplicación utilizada cuando se hace doble clic en el archivo. Muchas extensiones pueden tener el mismo tipo de archivo. Esa transformación se realiza en el siguiente paso:

  • registrar la extensión del nombre de archivo para el tipo de archivo

Aquí, se establece un valor de registro para su extensión, establecer el tipo de archivo que la extensión a la ProgID se creado en el paso anterior.

La cantidad mínima de trabajo requerida para abrir un archivo con su aplicación es establecer/crear dos claves de registro. En este ejemplo de archivo .reg, creo un tipo de archivo (blergcorp.blergapp.v1) y asocio una extensión de archivo (.blerg) con él.

Windows Registry Editor Version 5.00 

[HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\shell\open\command] 
@="c:\path\to\app.exe \"%1\"" 
[HKEY_CURRENT_USER\Software\Classes\.blerg] 
@="blergcorp.blergapp.v1" 

Ahora, probablemente desee lograr esto programáticamente. Para ser absolutamente kosher, podría verificar la existencia de estas claves y cambiar el comportamiento de su programa en consecuencia, especialmente si está asumiendo el control de alguna extensión de archivo común. Sin embargo, el objetivo se puede lograr estableciendo esas dos teclas usando la función SetValue.

no estoy positivo de la sintaxis exacta de C++, pero en C# la sintaxis se ve algo como esto:

Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\blergcorp.blergapp.v1\shell\open\command", null, @"c:\path\to\app.exe \"%1\""); 
Registry.SetValue(@"HKEY_CURRENT_USER\Software\Classes\.blerg", null, "blergcorp.blergapp.v1"); 

Por supuesto podría abrir manualmente cada sub clave, crear manualmente el identificador de programa y extensión subclave, y luego establece el valor de la clave, pero algo bueno sobre la función SetValue es que si las claves o valores no existen, se crearán automáticamente. Muy útil.

Ahora, una palabra rápida sobre qué colmena usar. Muchos ejemplos de asociación de archivos en línea, incluidos los de MSDN, muestran que estas claves se configuran en HKEY_CLASSES_ROOT. No recomiendo hacer esto Esa colmena es una vista virtual combinada de HKEY_LOCAL_MACHINE\Software\Classes (los valores predeterminados del sistema) y HKEY_CURRENT_USER\Software\Classes (la configuración por usuario), y escribe en cualquier subclave en la colmena se redirigen a la misma clave en HKEY_LOCAL_MACHINE\Software\Classes. Ahora, no hay un problema directo al hacerlo, pero puede encontrarse con este problema: si escribe en HKCR (redirigido a HKLM) y el usuario ha especificado las mismas claves con diferentes valores en HKCU, prevalecerán los valores de HKCU. Por lo tanto, sus escrituras tendrán éxito pero no verá ningún cambio, porque la configuración HKEY_CURRENT_USER tiene prioridad sobre las configuraciones HKEY_LOCAL_MACHINE.

Por lo tanto, debe tener esto en cuenta al diseñar su aplicación. Ahora, en la otra cara puede escribir solo a HKEY_CURRENT_USER, como muestran mis ejemplos aquí. Sin embargo, esa configuración de asociación de archivos solo se cargará para el usuario actual, y si su aplicación se ha instalado para todos los usuarios, su aplicación no se iniciará cuando ese otro usuario abra el archivo en Windows.

Debe ser una cartilla decente para lo que quiere hacer. Para la lectura adicional Sugiero

Y veo también mi respuesta similar a una pregunta similar:

+3

Para editar la clave (predeterminada), debe usar: @ =" c: \\ ruta \\ a \\ app.exe \ "% 1 \" " Nota: la doble" \\ " – Fraga

+0

Me parece que agregar estos elementos de registro en el código sobrescribe los existentes de otras aplicaciones. Me gusta _add_ mine sin reemplazar los existentes. Regedit me muestra que esos multi -las entradas de elección utilizan claves adicionales como "OpenWithList". ¿Tengo que crearlas manualmente si hay una clave existente, o hay un método más simple? ¿O será mejor que pregunte esto en mi propia pregunta de SO? –

+0

Respondiendo a mi propia pregunta: lo he descubierto. Si necesita la respuesta, señale una pregunta de SO adecuada y la completaré. –

7

Este es un proceso de dos pasos:

 
1. Define a program that would take care of extension: (unless you want to use existing one) 
     1.1 create a key in "HKCU\\Software\\Classes\\" for example 
      "Software\\Classes\\YourProgramName.file.ext" 
     1.2 create subkey "Software\\Classes\\YourProgramName.file.ext\\DefaultIcon" 
     1.2.1 set default value ("") to your application full path to get 
       icon from resources 
     1.3 create a subkey "Software\\Classes\\YourProgramName.file.ext\\Shell\\OperationName\\Command" 
      OperationName = for example Open, Print or Other 
     1.3.1 set default value ("") to your application full path +optional runtime params (filename) 

2.Associate file extension with program. 
    2.1 create a key HKCU\\Software\\Classes\\.ext - here goes your extension 
    2.2 set default value to the program definition key 
    ("YourProgramName.file.ext") 

A continuación se muestra parte del programa escrito en C#, que la extensión de archivo asociado. No es C++, pero creo que es simple suficiente como para explicarse a sí misma y que yo sepa es verv simmilar si no es idéntico al código en C++

1.

 

    RegistryKey keyPFCTExt0 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc", true); 
     if (keyPFCTExt0 == null) 
     { 
      keyPFCTExt0 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc"); 
      keyPFCTExt0.CreateSubKey("DefaultIcon"); 
       RegistryKey keyPFCTExt0ext = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\DefaultIcon", true); 
        keyPFCTExt0ext.SetValue("", Application.ExecutablePath +",0"); 
       keyPFCTExt0ext.Close(); 
      keyPFCTExt0.CreateSubKey("Shell\\PFCT_Decrypt\\Command"); 
     } 
    keyPFCTExt0.SetValue("", "PFCT.file.enc"); 
    keyPFCTExt0.Close(); 
 

2.

 

    RegistryKey keyPFCTExt1 = Registry.CurrentUser.OpenSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command", true); 
     if (keyPFCTExt1 == null) 
      keyPFCTExt1 = Registry.CurrentUser.CreateSubKey("Software\\Classes\\PFCT.file.enc\\Shell\\PFCT_Decrypt\\Command"); 
     keyPFCTExt1.SetValue("", Application.ExecutablePath + " !d %1"); //!d %1 are optional params, here !d string and full file path 
     keyPFCTExt1.Close(); 
 
5

No sé por qué la gente sigue diciendo que el valor predeterminado de HKEY_CURRENT_USER\Software\Classes\<.ext> (que lo redirigirá a otra clase (creada por software).

Sí funciona, pero va a ser anulado por

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\<.ext>\UserChoice 

y creo que Microsoft recomienda la segunda práctica- porque es lo que la incorporada en el "abrir con" lo está haciendo. El valor de la clave Progid "es igual al valor predeterminado de HKEY_CURRENT_USER\Software\Classes\<.ext> en este caso.

Cuestiones relacionadas