2012-02-10 42 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', ...); 

將顯示「打開方式」對話框。

僅限使用特定動詞如果您想要特定操作。例如。 '打印','探索','跑步'。否則 - 只是通過零。

相關問題