Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Hidden run of a third party application (silent print from Adobe Reader)

Posted on 2008-11-11
7
Medium Priority
?
2,412 Views
Last Modified: 2012-05-05
I would like to run a third party application (Adobe Reader 9) completely hidden, without displaying the splash screen, application window, taskbar button etc.

The background story: I have to print PDF files from my application, the Adobe Reader 9 with the /t command line switch does it fine, but the Reader window pops up while printing, which is very annoying and unprofessional (the same thing happens with the ActiveX control). I didn't consider using third party PDF applications (as recommended on Experts-Exchange before) due to various reasons (press quality transparency flattening is needed, done well only by Adobe products).

Therefore the only solution I see is to manage somehow to hide the Reader window. Here are the things I've tried so far:

1. CreateProcess with the SW_HIDE switch specified -- works fine with other apps, Adobe ignores it.

2. Calling ShowWindow(Handle, SW_HIDE) right after the Reader window is created (I have even installed a shell hook for that), but the window appears for a moment on the screen, of if called with the /t switch, it even stays there until the print operation completes (apparently the message loop is blocked while it prints).

3. Starting it as a different user: the window will still appear on the active desktop.

My further ideas are to launch Reader on a different desktop or a different window station, but Ive never used them before and have no idea whether they will work or not. Any other ideas for hiding Acrobat or printing silently in any other way are welcome.
0
Comment
Question by:biroadam
7 Comments
 
LVL 28

Expert Comment

by:2266180
ID: 22935098
use createprocess and in the startupinfo structure use the dwX and dwY members to move the window out of the screen.

not tested, and it might not work, because it could be that the splash window is created after the main window and displayed before it.

if this is indeed the case, then the only practical solution would be to hook showwindow api function and not show that window at all :)
there might be other workable solutions too, but it all depends on how the slash screen is created and whether some values are forced or not in that window.
0
 

Author Comment

by:biroadam
ID: 22938359
Hi Ciuly,

Thanks for the comment. The results:

1. dwX and dwY members are ignored, the Reader uses instead he position values saved in the registry (in a key called SDI). Setting these values out of the screen has no effect, it will take care to keep the window entirely on the screen.

2. "Hook showwindow api function and not show that window at all" -- how exactly would you do this? As I said, I managed to install a shell hook that notified me when the Acrobat window has been created, but I couldn't see a way to block displaying the window.

3. Don't worry about the splash screen, there is a bDisplayedSplash registry item, setting it to 1 will hide it (it only appears on the first launch after installation anyway, as far as I see).

So we should concentrate on hiding the main form or displaying it somewhere (other desktop, other window station) where nobody can see it. Any suggestions?

Regards,
Adam
0
 
LVL 28

Expert Comment

by:2266180
ID: 22939106
can you give me more info on 2) ? like what things you have available in your callback function. if you have access to the windows handle right after creation and before displaying it, then you can move that off screen.

my hook idea requires code injection. I'd leave that as a last resort.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 1

Expert Comment

by:swiatlo
ID: 22939939
I had the same problem. Poping up Acrobat at printing PDF.
Because I had to print a batch of PDF I have noticed that acrobat stays/displays itself only for the first document in the loop. Other documents from the batch went behind. I can imagnie that could be some sort of a trace to investigate.
I had to rewrite the part of my application that generated PDF, to print directly to the file instead, and then I printed that file not PDF. But I have a control over it and you seem to be fixed with PDF, don't you.
0
 

Author Comment

by:biroadam
ID: 22942380
Hi everyone,

It seems that in the meanwhile I've found the solution, though it needs a bit more work. My multiple desktop idea seems to work fine: I create a new desktop called 'HideAcrobat', and will create the Acrobat process on that desktop. The result: there is absolutely no interaction with the current desktop, not even the printer icon will appear in the system tray (which would have happened if I would have just hide the main window).

The code is something like this:

procedure SilentPrint(FileName, PrinterName: string);
var Desk: cardinal; si: TStartupInfo; pi: TProcessInformation; AcrobatCmd: string;
begin
  AcrobatCmd := '"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" /t "' +
    FileName + '" ' + PrinterName;
  Desk := Windows.CreateDesktop(PChar('HideReader'), nil, nil, 0, MAXIMUM_ALLOWED, nil);
  zeromemory(@si, sizeof(si));
  si.cb := SizeOf(TStartupInfo);
  si.lpDesktop := 'HideReader';
  CreateProcess(nil, pchar(AcrobatCmd), nil, nil, false, 0, nil, nil, si, pi);
  ... then wait for the file to be printed, close the Reader, and close the desktop
end;

The solution isn't yet 100% working, we're experiencing the following problems:

1. If there is a Reader already running on the current desktop, a second Reader will be started on the second desktop, but won't print.

2. While a Reader prints on the second desktop, the Reader cannot be started on the current desktop.

3. If I don't close the reader on the second desktop, then the next print operation will crash -- the only cure for this seems to be to close the Reader after printing.

4. On Vista Home Basic, the CreateDesktop function will only work after a registry key is defaulted (see MSDN documentation of CreateDesktop).

Possible idea to cure problems 1-3: to start the Reader not just on a different desktop, but also as a different user.

Any ideas, comments, test results are welcome.

Regards,
Adam
0
 

Accepted Solution

by:
biroadam earned 0 total points
ID: 23020290
Hi everyone,

I have developed a solution that seems to work perfectly: Acrobat Reader will print in the background, without affecting instances opened in the user accounts. The difference from the solution presented above is that the Reader runs not just on a different desktop, but also in the SYSTEM account, this will ensure that it will have no interference with other Reader instances running in user accounts. The Reader in the System account uses a different set of settings, and can be started-stopped independently from the Reader instances running in user accounts.

Here is what has to be done:

1. To get consistent results that do not depend on the current user settings of the Reader (e.g. fit to page), the registry settings of Acrobat Reader needs to be copied into the .DEFAULT user (which is used by the SYSTEM account), and then modified according to your needs (e.g. fit to page turned off). You may also set the \AdobeViewer\Launched value to TRUE (to avoid first time launch problems).
Source:
HKEY_CURRENT_USER\Software\Adobe\Acrobat Reader\9.0
Destination:
HKEY_USERS\.DEFAULT\Software\Adobe\Acrobat Reader\9.0.

2. Set up printers for the SYSTEM account, so then applications running in the system account can use the printers installed in the system. For this, you'll have to copy three registry keys:
Source:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Current Version\Devices
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Current Version\PrinterPorts
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\Current Version\Windows
Destination:
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows NT\Current Version\Devices
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows NT\Current Version\PrinterPorts
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows NT\Current Version\Windows.

3. Restart the spooler:
command line: "net stop spooler /y", then "net start spooler".

4. Run the following code FROM THE SYSTEM ACCOUNT(!):

procedure SilentPrint(FileName, PrinterName: string);
var Desk: cardinal; si: TStartupInfo; pi: TProcessInformation; AcrobatCmd: string;
begin
  AcrobatCmd := '"C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe" /t "' +
    FileName + '" ' + PrinterName;
  Desk := Windows.CreateDesktop(PChar('HideReader'), nil, nil, 0, MAXIMUM_ALLOWED, nil);
  zeromemory(@si, sizeof(si));
  si.cb := SizeOf(TStartupInfo);
  si.lpDesktop := 'HideReader';
  CreateProcess(nil, pchar(AcrobatCmd), nil, nil, false, 0, nil, nil, si, pi);
end;

The safest way to run the Reader from the system account is to install a system service, and then run the code above from that system service. It will do the job even from Vista with UAC. You can send the parameters (FileName and PrinterName) through a mailslot from your application.

I hope it will be useful.

Regards,
Adam
0
 

Expert Comment

by:ContactRK
ID: 23361037
not soloved our problem.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Integration Management Part 2
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question