我使用ShellExecute
打开快捷方式
代码:
ShellExecute(Handle, 'open', 'C:\Users\hi2012\AppData\Roaming\Microsoft\Windows\Recent\xxx.gif.lnk', nil, nil, SW_SHOWNORMAL)
如果 xxx.gif 存在,代码可以打开它,如果不存在则不提供任何内容。
但是,当我用Windows资源管理器打开它时,它会显示:
我想当我使用代码打开一个不存在的快捷方式时,它也可以显示,我该怎么办?
这是使用ShellExecute
打开快捷方式的错误方法吗?
答案 0 :(得分:3)
ShellExecute
在失败时不显示对话框。并且它不会代表您删除文件。该对话框由Explorer
app。
为了处理错误,您需要检查对ShellExecute
的调用的返回值。如果该返回值大于32,则调用成功。否则出现错误。可能报告的错误列在文档中。
为了更好地处理错误,请使用ShellExecuteEx
。如果对ShellExecuteEx
的调用失败,则可以通过调用GetLastError
来获取错误代码。
答案 1 :(得分:1)
您应该使用IShellLink::Resolve
自行解决快捷方式。 IShellLink::Resolve
提供标志来控制是否显示搜索UI。
答案 2 :(得分:0)
你可以invoke "open" from context popup menu on .lnk file。这将提供与在资源管理器中双击.lnk文件相同的行为:
function SHBindToParent(pidl: PItemIDList; const riid: TIID; out ppv; out ppidlLast: PItemIDList): HResult; stdcall; external 'shell32.dll' name 'SHBindToParent';
procedure ExecuteFile(const AWnd: HWND; const AFileName: String);
function GetUIObjectOfFile(wnd: HWND; const pszPath: WideString; const riid: TGUID; out ppv): HRESULT;
var
pidl: PItemIDList;
sfgao: DWord;
psf: IShellFolder;
pidlChild: PItemIDList;
begin
DWord(ppv) := 0;
Result := SHParseDisplayName(PWideChar(pszPath), nil, pidl, 0, sfgao);
if SUCCEEDED(Result) then
try
Result := SHBindToParent(pidl, IID_IShellFolder, psf, pidlChild);
if SUCCEEDED(Result) then
try
Result := psf.GetUIObjectOf(wnd, 1, pidlChild, riid, nil, ppv);
finally
psf := nil;
end;
finally
CoTaskMemFree(pidl);
end;
end;
const
SCRATCH_QCM_FIRST = 1;
SCRATCH_QCM_LAST = $7FFF;
var
pcm: IContextMenu;
Menu: HMENU;
Info: TCMInvokeCommandInfo;
Id: UINT;
begin
if SUCCEEDED(GetUIObjectOfFile(AWnd, PChar(AFileName), IID_IContextMenu, pcm)) then
try
Menu := CreatePopupMenu;
if Menu <> 0 then
try
if SUCCEEDED(pcm.QueryContextMenu(Menu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_DEFAULTONLY)) then
begin
Id := GetMenuDefaultItem(Menu, 0, 0);
if Id <> UINT(-1) then
begin
FillChar(Info, SizeOf(Info), 0);
Info.cbSize := SizeOf(info);
Info.hwnd := Handle;
Info.lpVerb := MAKEINTRESOURCEA(Id - SCRATCH_QCM_FIRST);
SetLastError(pcm.InvokeCommand(Info));
if GetLastError <> 0 then
RaiseLastOSError;
end;
end;
finally
DestroyMenu(Menu);
end;
finally
pcm := nil;
end;
end;
通过使用SEE_MASK_INVOKEIDLIST标志调用ShellExecuteEx,可以实现同样的目的。