Stampa programmatica in Adobe Reader 9 utilizzando .NET Interop
-
04-07-2019 - |
Domanda
Sto usando VB.Net WinForms. Vorrei chiamare il controllo ActiveX di Adobe Reader 9 per stampare alcuni PDF. Ho aggiunto il controllo ActiveX alla casella degli strumenti VS (la dll è AcroPDF.dll, il nome COM " Adobe PDF Reader " ;. Dopo qualche esperimento il seguente codice funziona.
Dim files As String() = Directory.GetFiles(TextBoxPath.Text, "*.pdf", SearchOption.TopDirectoryOnly)
Using ActiveXPDF As New AxAcroPDFLib.AxAcroPDF
Me.Controls.Add(ActiveXPDF)
ActiveXPDF.Hide()
For Each filename As String In files
ActiveXPDF.LoadFile(filename)
ActiveXPDF.printAll()
'Begin Yukky Hack '
Dim endTime As Date = DateAdd(DateInterval.Second, 20, Now)
Do While Now < endTime
My.Application.DoEvents()
Loop
'End Yuk '
Next
End Using
Senza il bit Yuk questo stamperà solo alcuni dei PDF, sembra che l'istruzione End Using stia chiamando dispose sul controllo prima che abbia finito di stampare.
Quindi sembra che la chiamata a printAll non sia bloccante ma non riesco a trovare una proprietà di callback o status che posso interrogare per vedere se lo spool di stampa è stato completato. Mi manca una proprietà / metodo o c'è un modo più elegante (e più reattivo) di aggirare?
Soluzione
L'uso di questo metodo per stampare più documenti non funzionerà come hai trovato.
Farlo funzionare è piuttosto complicato, ma ecco una descrizione generale della soluzione.
Uso System.Diagnostics.Process per stampare usando myProcess.StartInfo.Verb = " Print " Quindi controllo lo stato e lo stato della coda di stampa in due passaggi per assicurarmi che la stampa sia abbastanza pronta per poter stampare il documento successivo. Usa WMI e ManagementObjectSearcher per enumerare le informazioni sulla stampante usando " SELECT * FROM Win32_Printer " ;. La logica è che provo a vedere se lo spooling viene avviato prima di continuare a stampare quello successivo.
Vedi http://msdn.microsoft.com/en-us/ libreria / aa394363.aspx per la classe WMI Win32_Printer.
Altri suggerimenti
Ho avuto lo stesso problema usando AcroPDF in Delphi .. poi ho capito che quando ho "fermato" il processo utilizzando un messaggio, AcroPDF inizia a stampare.
Quindi ho appena creato un TForm modale che si chiude dopo alcuni secondi.
var
formModal : TFormModal;
begin
formModal := TFormModal.Create(self);
//PrintMethodHere
frmPecas.CarregarDocumentoParaImpressao();
formModal.ShowModal;
end;
TFormModal è questo e inserisco semplicemente un'icona di caricamento sul modulo per rappresentare qualcosa come "stampa".
unit FModal;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Animate, GIFCtrl;
type
TFormModal = class(TForm)
Timer: TTimer;
imgGif: TRxGIFAnimator;
procedure TimerTimer(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormModal: TFormModal;
implementation
{$R *.dfm}
// Author: Anderson Mello Date: 09-fev-2012
// DEscription: Using TTimer after 5 seconds I close this form
procedure TFormModal.TimerTimer(Sender: TObject);
begin
close;
end;
// Author: Anderson Mello Date: 09-fev-2012
// Description: Enable the timer only when the form is shown
procedure TFormModal.FormShow(Sender: TObject);
begin
Timer.Enabled := true;
end;
// Description: disable when close
procedure TFormModal.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Timer.Enabled := false;
end;
// Author: Anderson Mello Date: 09-fev-2012
// Description: disable close button "X", so the user can't close
procedure TFormModal.FormCreate(Sender: TObject);
var
hSysMenu:HMENU;
begin
hSysMenu:=GetSystemMenu(Self.Handle,False);
if hSysMenu <> 0 then begin
EnableMenuItem(hSysMenu,SC_CLOSE,MF_BYCOMMAND or MF_GRAYED);
DrawMenuBar(Self.Handle);
end;
KeyPreview:=True;
end;
// Author: Anderson Mello Date: 09-fev-2012
// Description: disable shortcuts to close
procedure TFormModal.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = VK_F4) and (ssAlt in Shift) then
Key:=0;
end;
Abbiamo finito per utilizzare Adobe PDF Verifier per i nostri scopi di test. Per fare ciò abbiamo dovuto avviare effettivamente acrobat e manipolarne l'interfaccia in modo programmatico utilizzando SendInput .
Sarei molto interessato a vedere se fosse possibile utilizzare invece un'API interna.
Puoi usare questo codice per visualizzare qualsiasi file con il suo software appropriato.
Sub Show_Document(ByVal FILENAME As String)
Dim p As Process = Nothing
Try
If My.Computer.FileSystem.FileExists(FILENAME) Then
p = Process.Start(FILENAME)
p.Dispose()
End If
Catch ex As Exception
Finally
End Try
End Sub