2012-02-10 12 views
9

Quiero permitir que el usuario seleccione una asociación (abrir con) para una extensión de archivo actualmente no registrada.¿Cómo puedo mostrar el diálogo "abrir con" para una extensión de archivo no registrada?

Actualmente le estoy diciendo a la API que abra el archivo usando ShellExecute y devuelve un código de error ERROR_NO_ASSOCIATION.

¿Hay alguna manera de decirle a la API que debería permitir al usuario seleccionar una nueva asociación?

+0

esto podría hacerlo: 'rundll32.exe shell32.dll, OpenAs_RunDLL" C: \ Path \ TEXT.TXT "' –

+0

posible duplicado de [Cómo abrir un cuadro de diálogo predeterminado para la ventana si ShellExecute falla debido a la asociación de archivos no en C++?] (Http: // stackoverflow.com/questions/6364879/how-to-open-a-default-dialog-for-window-if-shellexecute-failed-due-to-no-file-ass) – Anders

Respuesta

11

utilizo

procedure ShellOpenAs(const AFileName: string; AHandle: HWND); 
begin 
    ShellExecute(AHandle, 'open', PChar('rundll32.exe'), PChar('shell32.dll,OpenAs_RunDLL ' + AFileName), nil, SW_SHOWNORMAL); 
end; 

Editar (inspirado por el comentario de David y https://stackoverflow.com/a/13229516/1431618): Uno puede omitir ShellExecute y RunDll32 llamando OpenAs_RunDLL directamente:

procedure OpenAs_RunDLL(hwnd: HWND; hinst: HINST; lpszCmdLine: LPSTR; nCmdShow: Integer); stdcall; external shell32; 

procedure ShellOpenAs(AHandle: HWND; const AFileName: string); 
begin 
    OpenAs_RunDLL(AHandle, HInstance, PChar(AFileName), SW_SHOWNORMAL); 
end; 

También SHOpenWithDialog es en Windows Vista y más tarde. (Me parece interesante que Microsoft escribió un punto de entrada compatibles RunDLL pero hasta Vista no se molestó en proporcionar una función de API regular.)

+0

Gracias, agregaré esto como la alternativa si el primero falla, ya que solo quiero el diálogo si no puedo abrirlo. –

+1

La forma correcta de invocar el diálogo es usar el verbo 'openas' en su lugar:' ShellExecute (AHandle, 'openas', PChar (AFileName), nil, nil, SW_SHOWNORMAL); ' –

+0

@Remy: Esto no funciona para mí (Windows 7 de 64 bits). Recibo el error de sistema 1155 - traducido del alemán: "El archivo especificado no tiene una aplicación asociada". –

3

Ir con la siguiente código obtendrá su Solución

public const uint SEE_MASK_INVOKEIDLIST = 12;//add this line in your code 


CoInitializeEx(NULL, COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE); 
SHELLEXECUTEINFO sei = { sizeof(sei) }; 
sei.nShow = SW_SHOWNORMAL; 
sei.lpVerb = "openas"; 
sei.lpFile = "C:\\yourfile.ext"; 
sei.lfmask= SEE_MASK_INVOKEIDLIST;//add this line in your code 
ShellExecuteEx(&sei); 

SEE_MASK_INVOKEIDLIST this variable set "Verb" from presented system registry. 
3

Simplemente no use el verbo explícito. El uso de un verbo específico como 'abierto' es un gran error:

  • 'abierto' puede ser no un verbo predeterminado (por ejemplo, puede ser el 'juego', 'editar' o 'correr')
  • 'abierto' puede que no existe

es una manera más correcto simplemente pasan nula como verbo. El sistema seleccionará automáticamente verbo más apropiado: se utilizará

  • verbo defecto, si se establece
  • será utilizado
  • verbo 'abierta', si no hay verbo predeterminado se establece será utilizado
  • primer verbo si no es por defecto y los verbos 'abiertas' están disponibles
  • Si no se asignan los verbos - el sistema se recuperará "Abrir con" diálogo

En otras palabras, simple

ShellExecute(0, nil, 'C:\MyFile.StrangeExt', ...); 

mostrará el cuadro de diálogo "Abrir con".

Utilice sólo un verbo específica si desea una acción específica. P.ej. 'imprimir', 'explorar', 'runas'. De lo contrario, simplemente pase nil.

Cuestiones relacionadas