2012-02-10 43 views
9

我想让用户为当前未注册的文件扩展名选择一个关联(打开)。如何显示未注册文件扩展名的“打开方式”对话框?

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

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

+0

这可能会这样做:'rundll32.exe shell32.dll,OpenAs_RunDLL“C:\ Path \ TEXT.TXT”' – 2012-02-10 08:27:26

+0

可能重复的[如果ShellExecute由于没有文件关联?C++](HTTP://计算器。com/questions/6364879/how-to-open-a-default-dialog-for-window-if-shellexecute-fails-due-to-no-file-ass) – Anders 2012-02-10 14:06:09

回答

11

我用

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

编辑(由大卫的评论和https://stackoverflow.com/a/13229516/1431618启发):

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; 

还有SHOpenWithDialog在Windows上: 人们可以通过调用OpenAs_RunDLL直接省略ShellExecuteRunDll32 Vista和更高版本。 (我觉得有趣的是微软写了RUNDLL兼容的入口点,但直到Vista中并没有刻意去提供一个普通的API函数)。

+0

谢谢,我将添加这个作为回退if第一个失败,因为如果我不能打开它,我只想要对话框。 – 2012-02-10 10:04:03

+1

调用对话框的正确方法是使用'openas'动词代替:'ShellExecute(AHandle,'openas',PChar(AFileName),nil,nil,SW_SHOWNORMAL); ' – 2012-02-10 21:22:25

+0

@Remy:这对我不起作用(Windows 7 64位)。我得到系统错误1155 - 从德语翻译:“指定的文件没有关联的应用程序”。 – 2012-02-13 08:53:35

3

转到与下面的代码,你会得到你的解决方案 -

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

简单不要使用明确的动词。使用特定的动词,如“开放”是一个很大的错误:

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

它是一种更正确的简单地传递零作为动词。系统会自动选择最合适的动词:

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

换句话说,简单

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

将显示“打开方式”对话框。

仅限使用特定动词如果您想要特定操作。例如。 '打印','探索','跑步'。否则 - 只是通过零。

相关问题