Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I display the "open with" dialog for an unregistered file extension? [duplicate]

I want to let the user select an association (open with) for an currently unregistered file extension.

Currently I'm telling the API to open the file by using ShellExecute and it returns an ERROR_NO_ASSOCIATION error code.

Is there a way to tell the API that it should let the user select a new association?

like image 526
Tobias R Avatar asked Feb 10 '12 08:02

Tobias R


3 Answers

Go with following code you will get your solution-

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.

like image 153
Sammed Bagwade Avatar answered Oct 23 '22 02:10

Sammed Bagwade


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.)

like image 33
Uli Gerhardt Avatar answered Oct 23 '22 02:10

Uli Gerhardt


Simply do not use explicit verb. Using a specific verb like 'open' is a big mistake:

  • 'open' may be not a default verb (for example, it may be 'play', 'edit' or 'run')
  • 'open' may not exists

It is a way more correct to simply pass nil as verb. The system will automatically select most appropriate verb:

  • Default verb will be used, if it is set
  • 'open' verb will be used, if no default verb is set
  • first verb will be used, if no default and 'open' verbs are available
  • if no verbs are assigned - the system will bring "Open with" dialog

In other words, simple

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

will show "Open with" dialog.

Only use a specific verb if you want a specific action. E.g. 'print', 'explore', 'runas'. Otherwise - just pass nil.

like image 32
Alex Avatar answered Oct 23 '22 02:10

Alex