I use
procedure ShellOpenAs(const AFileName: string; AHandle: HWND);
begin
ShellExecute(AHandle, 'open', PChar('rundll32.exe'), PChar('shell32.dll,OpenAs_RunDLL ' + AFileName), nil, SW_SHOWNORMAL);
end;
Edit (inspired by David's comment and https://stackoverflow.com/a/13229516/1431618):
One can omit ShellExecute
and RunDll32
by calling OpenAs_RunDLL
directly:
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;
There is also SHOpenWithDialog on Windows Vista and later. (I find it interesting that Microsoft wrote a RunDLL compatible entry point but until Vista didn't bother to provide a regular API function.)