Hi!
I'm using a C program to open PDF files with this code:

ShellExecute(GetDesktopWindow(), "open", "c:\\someFolder\\myFile.pdf",  NULL, NULL, SW_SHOWNORMAL);

Now I need to go furthrer; I need to open the PDF file at a certain page. I've tried

"c:\\someFolder\\myFile.pdf#page=5"...

...as is suggested in Adobe's docs, but this does not work.

Any hints?

Dani AI

Generated

The reason adding #page=5 after a file path does nothing in a desktop app is that the fragment is a browser feature. Adobe documents note that #page= works for URLs in a web browser, but not for local-drive paths like c:\.... When you launch a local PDF via the Windows shell, any extra string you tack onto the document path is not treated as an open parameter. Instead, pass open parameters to the PDF viewer executable itself. Also note that ShellExecute ignores lpParameters when lpFile is a document, which is why putting arguments next to the PDF file did not work. ()

Practical approach: launch the viewer executable and pass the page via its command line. Using CreateProcessW keeps quoting and Unicode reliable.

// Minimal example: open a PDF on page 5
// Tip: discover the default PDF viewer path at runtime; hardcoding is for illustration.
wchar_t cmd[] =
  L"\"C:\\Program Files\\Adobe\\Acrobat\\Acrobat.exe\" /A \"page=5\" "
  L"\"C:\\path\\to\\myFile.pdf\"";
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi = {0};
if (CreateProcessW(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
}

Notes:

  • Pass NULL for the ShellExecute/CreateProcess window handle; you do not need GetDesktopWindow. Quote both the EXE and PDF paths. lpDirectory is just a working directory and does not need to contain the PDF. (learn.microsoft.com)
  • For Adobe viewers, multiple open parameters are supported with the /A switch (for example, page, zoom, navpanes); see Adobe’s examples for combining them. (community.adobe.com)
  • If you truly need programmatic control (as hinted), the Acrobat SDK exposes APIs that open a PDF and accept an open-parameter string (for example, AVDocOpenFromFileWithParamString), but that route targets Acrobat and has Reader limitations. (opensource.adobe.com)

This should behave the same on XP, Vista, and newer, provided paths and quoting are correct.

Recommended Answers

All 13 Replies

EDIT:

On second thoughts, you are right.

Just a little change

ShellExecute(GetDesktopWindow(), "open", "c:\\someFolder\\myFile.pdf #page=4",  NULL, NULL, SW_SHOWNORMAL);

Just add a space, cause page=4 is an argument.

----------------
I don't know if there are any real ways to do it. But how about triggering some keyboard inputs with keybd_event()
All you have to do is Ctrl+Shift+N to open the "go to page" dialog box. and then the input the number 4(say) and also "Enter" with the same function. Before all this you have to give time for the pdf to get opened and become active(You may have to use the function Sleep())

You can get the complete set of Virtual key codes in msdn

Hope it helps

The official way is with Win32 COM
(never use keybd_event, not professonal at all...)

The official way is with Win32 COM
(never use keybd_event, not professonal at all...)

I'll take a note of that.

And the actual answer is not either. Its just to give an argument to the pdf we are opening;)

Well, so far I've not succeeded in making it work.
It is very easy to get the righ result when you open PDF files in a web browser: all you have to do is follow the PDF file name with the #page=n parameter (and without space).

However it does not work when calling the PDF from C/C++. I know it is possible, I've seen it work somewhere...

I'll post the solution here when I find it... :)

Sorry to have suggested an untested code.
My little Google search found me this

Have a look at it.

This time I have tested the code and it really works.

ShellExecute(GetDesktopWindow(), "open", "\"D:\\program files\\Adobe Reader 9.exe\"", "/A page=45 Ubuntu.Pdf", NULL, SW_SHOWNORMAL);

D:\Program files\Adobe Reader 9.exe is the path to the portable reader in my computer(I always try to get portable versions).

Ubuntu.pdf was in the same folder as my CPP program, hence I did not specify its path.

Details about parameter options could be found int the link above.

Good Luck

commented: Very helpful, saved my day with a great solution +1

THANK YOU!!!
Thank you VERY MUCH!
You saved my day!!!
Thanks!
All the Best!

Well.... I was too quick to celebrate...

It works fine in Win XP, but not on Vista.... oh well...

I wonder why!!

Hey Prabakar,

You mentioned you use a portable reader. Maybe this is a solution, where do I get it?

I've googled it and found so many different options... is there one from Adobe?

Thanks!

I do not have vista, to help you:( I don't know why it is not working in vista, these functions are ment to work on windows after all. Perhaps you'll have to wait for others to respond

Hi Prabakar,

What I've found out is GetDesktopWindow() works a bit different in Vista: it does not accept the directory info in the third parameter. So you have to indicate the directory in the fifth parameter. Kind of an ugly solution, as I will have to place the PDF files in the same directory where the reader exe is. Not good, but this is the only solution I could find for the moment.
Thanks very much for your help!!

Same directory as the reader? Why not give the full address fo the file?

Like this,

ShellExecute(NULL, "open", "\"D:\\program files\\Adobe Reader 9.exe\"", 
				"/A page=45 \"C:\\Documents and Settings\\Prabakar\\My Documents\\Downloads\\How to Do Everything _ Ubuntu (McGraw-Hill).pdf\"", NULL, SW_SHOWNORMAL);

Same directory as the reader? Why not give the full address fo the file?

Paths must never be hard coded. You must get them from Shell.

Paths must never be hard coded. You must get them from Shell.

That's what I always do, but, it looked like the OP was not satisfied with it.

What if he can't move it from a particular folder? ( happens often when it is a shared computer)

Copying the pdf and pasting it on a specific directory just to make your program work is not a good option

And adding the program to that directory might be irritating. It will be annoying to see a document in my songs folder.

Sometimes we need to use full address, or at least to use environment variables.;)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.