Tom
Tom

Reputation: 321

Delphi - open PDF with parameters without a default path for the reader application

I have a problem with opening pdf file from Delphi. I need to open pdf with parameters, because I want to create help manual for my program. I try to use shellExecute, but this function needs path for reader 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;

The program runs, but it is not a solution for me. Some users can use other pdf reader. Do you know a way to skip adding a reader path?

The other way is

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;

I think, that I need to some method, which pull the path from the pdf reader. Is this the best solutions for this problem?

Upvotes: 2

Views: 6200

Answers (4)

Johan
Johan

Reputation: 255

pdf files could be associated with another program, so "FindExecutable" is not a reliable way to find the installed Acrobat Reader program. I use the registry key : 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;

Upvotes: 0

Tom
Tom

Reputation: 321

This is a best answer to my question

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

Upvotes: 0

fantaghirocco
fantaghirocco

Reputation: 4878

Open a PDF with the default system application

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

If lpOperation is nil the default verb is used.


Open a PDF file with parameters

The way to open a PDF file with parameters from command line on Windows is:

"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"

The above opens the PDF file with a x1000 zoom (not very useful indeed).

To achieve the same result with ShellExecute do the following:

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;

Here is PDF Open Parameters for reference.

Finally (with no try) notice that PDF Open Parameters are specific of an application so a different reader may ignore them in the best case; in the worst, the application will simply refuse to start.
I'd recommend to use open parameters only after being sure that the correct application is available on the client; if not, use the first method.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 613602

If you wish to pass parameters to an executable, then you are going to ignore any associations and require the presence of a specific executable. Because specific parameters will only be valid for one specific executable. That is, parameters for Acrobat won't be understood by Foxit, and vice versa.

In which case you should invoke it with CreateProcess. To locate the executable for Acrobat Reader, refer to this question: How to get Adobe Reader full path(including executable file name)? There will be similar approaches for other PDF programs.


The real point of ShellExecute is that it understands the system and user preferences for file associations. The shell knows which application should be used to open different file types, and where to find that application.

As a broad rule, if you know the location of the executable, use CreateProcess. If you know the location of a document and want the system to find the executable, use ShellExecute(Ex).

So, pass the full path to the PDF file to ShellExecute and let the system find and open the associated application.

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

If you want to have proper error handling use ShellExecuteEx. You might also replace 'open' with nil and let the system choose the default action.

Upvotes: 2

Related Questions