الطباعة برمجياً في Adobe Reader 9 باستخدام .NET Interop
-
04-07-2019 - |
سؤال
أنا أستخدم VB.Net WinForms.أرغب في استدعاء عنصر تحكم Adobe Reader 9 ActiveX لطباعة بعض ملفات PDF.لقد قمت بإضافة عنصر تحكم ActiveX إلى مربع أدوات VS (ملف dll هو AcroPDF.dll، واسم COM "Adobe PDF Reader".بعد بعض التجارب يعمل الكود التالي.
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
بدون وحدة بت Yuk، لن يؤدي هذا إلا إلى طباعة بعض ملفات PDF، ويبدو أن عبارة "إنهاء الاستخدام" تستدعي التخلص من عنصر التحكم قبل الانتهاء من الطباعة.
لذلك يبدو أن استدعاء printAll غير محظور ولكن لا يمكنني العثور على رد اتصال أو خاصية حالة يمكنني الاستعلام عنها لمعرفة ما إذا كان التخزين المؤقت للطباعة قد اكتمل.أفتقد خاصية/طريقة أم أن هناك حلاً أكثر أناقة (وأكثر استجابة)؟
المحلول
وباستخدام هذه الطريقة لطباعة وثائق متعددة لا يذهب للعمل جيدة كما كنت وجدت.
وبعد ذلك عمل صعب جدا ولكن هنا هو وصف عام من الحل.
وأنا استخدم System.Diagnostics.Process الطباعة باستخدام myProcess.StartInfo.Verb = "طباعة" ثم أتحقق من حالة ودولة قائمة انتظار الطابعة في خطوتين للتأكد من أن الطباعة جاهزة بما فيه الكفاية لتكون قادرة على طباعة المستند المقبلة. استخدام WMI وManagementObjectSearcher تعداد معلومات الطابعة باستخدام "SELECT * FROM Win32_Printer". المنطق هو أن أحاول معرفة ما إذا كان يتم تشغيل التخزين المؤقت قبل الاستمرار في طباعة واحد القادم.
http://msdn.microsoft.com/en-us/ مكتبة / aa394363.aspx عن الطبقة Win32_Printer WMI.
نصائح أخرى
وكان لي نفس المشكلة باستخدام AcroPDF في دلفي .. ثم فكنت أحسب أنني عندما "وقف" معالج باستخدام رسالة، AcroPDF يبدأ لطباعة.
وحتى أنا فقط إنشاء TForm مشروط أن يغلق نفسه بعد بضع ثوان.
var
formModal : TFormModal;
begin
formModal := TFormModal.Create(self);
//PrintMethodHere
frmPecas.CarregarDocumentoParaImpressao();
formModal.ShowModal;
end;
ووTFormModal هذا وأنا فقط إدراج رمز التحميل على شكل ليمثل شيء من هذا القبيل "الطباعة".
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;
لقد انتهى بنا الأمر باستخدام برنامج Adobe's PDF Verifier لأغراض الاختبار الخاصة بنا.وللقيام بذلك، كان علينا إطلاق برنامج أكروبات والتعامل مع واجهته برمجيًا باستخدامه إرسال الإدخال.
سأكون مهتمًا جدًا بمعرفة ما إذا كان من الممكن استخدام واجهة برمجة التطبيقات الداخلية بدلاً من ذلك.
ويمكنك استخدام هذا الرمز لعرض أي ملف مع البرنامج المناسب لها.
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