【问题标题】:Delphi - open PDF with parameters without a default path for the reader applicationDelphi - 打开带有参数的 PDF,没有阅读器应用程序的默认路径
【发布时间】:2015-05-23 07:53:35
【问题描述】:

我从 Delphi 打开 pdf 文件时遇到问题。 我需要用参数打开 pdf,因为我想为我的程序创建帮助手册。我尝试使用 shellExecute,但是这个函数需要阅读器 pdf 的路径。

procedure TForm3.Button2Click(Sender: TObject);
var e,s:String;
begin
   s:='/A nameddest=somePlaceInPDF pathToMyFile.pdf';
   e:='AcroRd32';
   ShellExecute(handle,'open',pchar(e),pchar(s),nil,sw_show);
end;

程序运行,但它不是我的解决方案。一些用户可以使用其他 pdf 阅读器。你知道跳过添加阅读器路径的方法吗?

另一种方法是

if ShellExecute(handle,'open',pchar(e),pchar(s),nil,sw_show) < 32 then
  begin
  ShellExecute(0,0,'rundll32.exe','shell32.dll,OpenAs_RunDLL pathToMyFile.pdf',0,SW_SHOW);
  end;

我认为,我需要一些方法,从 pdf 阅读器中提取路径。这是解决这个问题的最佳方案吗?

【问题讨论】:

  • - “某些用户可以使用其他 pdf 阅读器” - 确实。在这种情况下,将参数传递给它不会理解的读者有什么意义?
  • 我必须假设每个用户都会有 Acrobat 阅读器?所以我必须在 ShellExecute 中写 pathToReader 或 'acrord32' 作为第三个参数?如果有人使用 X-change 查看器(我使用的)而不是 Acrobat 会怎样。我在 X-change 查看器中为 namedest 创建了关键词。 Acrobat Reader 和 X-change 可以理解这个参数。但是 ShellExecute 在没有指向某些 Reader 的路径时无法正常运行。

标签: delphi winapi pdf


【解决方案1】:

如果您希望将参数传递给可执行文件,那么您将忽略任何关联并要求存在特定的可执行文件。因为特定参数仅对一个特定的可执行文件有效。也就是说,Acrobat 的参数不会被 Foxit 理解,反之亦然。

在这种情况下,您应该使用CreateProcess 调用它。要找到 Acrobat Reader 的可执行文件,请参考以下问题:How to get Adobe Reader full path(including executable file name)? 其他 PDF 程序也会有类似的方法。


ShellExecute 的真正意义在于它了解系统和用户对文件关联的偏好。 shell 知道应该使用哪个应用程序来打开不同的文件类型,以及在哪里可以找到该应用程序。

一般来说,如果您知道可执行文件的位置,请使用CreateProcess。如果您知道文档的位置并希望系统找到可执行文件,请使用ShellExecute(Ex)

所以,将 PDF 文件的完整路径传递给ShellExecute,让系统找到并打开相关的应用程序。

ShellExecute(0, 'open', PChar(PdfFileName), nil, nil, SW_SHOW);

如果您想进行正确的错误处理,请使用ShellExecuteEx。您也可以将'open' 替换为nil 并让系统选择默认操作。

【讨论】:

    【解决方案2】:

    使用默认系统应用打开 PDF

    ShellExecute(Handle, nil, 'pathToMyFile.pdf', nil, nil, SW_SHOW);

    如果lpOperationnil,则使用默认的动词


    打开带有参数的 PDF 文件

    在 Windows 上通过命令行打开 PDF 文件的方法是:

    "C:\Program Files\Adobe\Reader 11.0\Reader\AcroRd32.exe" /A "zoom=1000=OpenActions" "C:\Documents and Settings\winUser\Desktop\wss-v1.1-spec-errata-os-SOAPMessageSecurity.pdf"
    

    以上以 x1000 缩放打开 PDF 文件(确实不是很有用)。

    要使用ShellExecute 获得相同的结果,请执行以下操作:

    var
      application, appParams, fileName,
      shellParams: string;
    begin
      application := 'AcroRd32.exe';
      appParams:= '/A "zoom=1000=OpenActions"';
      fileName := 'C:\Documents and Settings\winUser\Desktop\wss-v1.1-spec-errata-os-SOAPMessageSecurity.pdf';
      shellParams := Format('%s "%s"', [appParams, fileName]);
    
      ShellExecute(Handle, nil, PChar(application), PChar(shellParams), nil, SW_SHOW);
    end;
    

    这里是PDF Open Parameters供参考。

    最后(没有try)请注意,PDF 打开参数 是特定于应用程序的,因此其他读者可能会在最好的情况下忽略它们;在最坏的情况下,应用程序只会拒绝启动。
    我建议仅在确保客户端上提供正确的应用程序后才使用 open parameters;如果没有,请使用第一种方法。

    【讨论】:

      【解决方案3】:

      这是我问题的最佳答案

      procedure TForm3.Button2Click(Sender: TObject);
          var s, result:String;
          path: array[0..250] of char
          begin
             s:='/A nameddest=somePlaceInPDF "pathToMyFile.pdf"';
             FindExecutable('pathToMyFile.pdf',nil,path);
             result := trim(StrPas(path));
             ShellExecute(handle,nil,pchar(result),pchar(s),nil,sw_show);
          end
      

      【讨论】:

        【解决方案4】:

        pdf 文件可能与另一个程序相关联,因此“FindExecutable”不是查找已安装 Acrobat Reader 程序的可靠方法。 我使用注册表项:HKEY_CLASSES_ROOT\Software\Adobe\Acrobat\Exe

        procedure TfrmFsYtd.btnPdfHelpTestClick(Sender: TObject);
        var strAcro, strParam:string;
            Registry: TRegistry;
        begin
          // Get the users' installed Adobe Reader from the registry >>
          Registry:=TRegistry.Create;
          Registry.RootKey:=HKEY_CLASSES_ROOT;
          Registry.OpenKey('Software\Adobe\Acrobat\Exe',False);
          strAcro :=Registry.ReadString('');
          Registry.Free;
          // Use the installed Adobe Reader to open your pdf- help- file at a specific page >>
          strParam := ' /A page=4 "'+ProgPath+'FsYtd_Manual.pdf"';
          ShellExecute(Handle, 'open', PChar(strAcro), PChar(strParam),nil, SW_SHOWNORMAL);
        end;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多