0

ShellExecute用来打开快捷方式

代码 :

ShellExecute(Handle, 'open', 'C:\Users\hi2012\AppData\Roaming\Microsoft\Windows\Recent\xxx.gif.lnk', nil, nil, SW_SHOWNORMAL)

如果xxx.gif存在,则代码可以打开它,如果不存在,则不提供任何内容。

但是,当我用 Windows 资源管理器打开它时,它会显示:

在此处输入图像描述

我想当我使用代码打开一个不存在的快捷方式时,它也可以显示,我该怎么办?

ShellExecute这是打开快捷方式的错误方法吗?

4

3 回答 3

3

ShellExecute失败时不显示对话框。它不会代表您删除文件。该对话框由Explorer应用程序显示。

为了处理错误,您需要检查调用的返回值ShellExecute。如果该返回值大于 32,则调用成功。否则出现错误。文档中列出了可能报告的错误。

为了更好地处理错误,请使用ShellExecuteEx. 如果调用ShellExecuteEx失败,那么您可以通过调用获取错误代码GetLastError

于 2012-11-05T09:01:22.883 回答
1

You should use IShellLink::Resolve to resolve the shortcut yourself. IShellLink::Resolve offers flags to control whether to show search UI.

于 2012-11-05T23:36:55.057 回答
0

您可以从 .lnk 文件的上下文弹出菜单中调用“打开”。这将为您提供与在资源管理器中双击 .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 来归档。

于 2015-03-11T21:52:52.557 回答