如何显示未注册文件扩展名的“打开方式”对话框?

我想让用户为当前未注册的文件扩展名select一个关联(打开)。

目前我告诉API通过使用ShellExecute打开文件,它返回一个ERROR_NO_ASSOCIATION错误代码。

有没有办法告诉API它应该让用户select一个新的关联?

Solutions Collecting From Web of "如何显示未注册文件扩展名的“打开方式”对话框?"

我用

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

编辑 (由David的评论和https://stackoverflow.com/a/13229516/1431618启发):通过直接调用OpenAs_RunDLL可以省略ShellExecuteRunDll32

 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; 

在Windows Vista和更高版本上还有SHOpenWithDialog 。 (我发现微软写了一个兼容RunDLL的入口点是有趣的,但是直到Vista不打算提供一个常规的API函数)。

去下面的代码,你会得到你的解决方案 –

 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. 

只是不要使用明确的动词。 使用“开放”这样的特定动词是一个很大的错误:

  • “打开”可能不是默认的动词(例如,可能是“播放”,“编辑”或“运行”)
  • “打开”可能不存在

简单地通过nil作为动词是一种更正确的方法。 系统将自动选择最合适的动词:

  • 默认动词将被使用,如果它被设置
  • 如果没有设置默认动词,将使用“打开”动词
  • 如果没有默认和“开放”动词可用,将使用第一个动词
  • 如果没有动词分配 – 系统将带来“打开”对话框

换句话说,简单

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

将显示“打开”对话框。

如果你想要一个特定的动作只能使用一个特定的动词。 例如“打印”,“探索”,“跑步”。 否则 – 只是通过零。