سؤال

هذا على الأرجح ليس بالأمر السهل ولكن هنا هو الوضع:

لقد قمت بكتابة تطبيق سطر أوامر C# والذي:

  • يقوم بإنشاء ملف PDF باستخدام ITextSharp
  • يكتبه على القرص
  • الاستخدامات Acrord32.exe (هذا هو برنامج أكروبات ريدر) عبر System.Diagnostics.Process من أجل طباعة ملف PDF الذي تم إنشاؤه بصمت

إذا قمت ببناء الحل الخاص بي وانقر نقرًا مزدوجًا فوق pdfGen.exe, ، يعمل كما هو متوقع.يتم إنشاء ملف PDF وطباعته.

الآن، يجب نشر تطبيقي على خادم داخلي يعمل بنظام التشغيل Windows Vista الذي يعمل بنظام IIS 7.يحتوي هذا الخادم على بعض تطبيقات الويب PHP قيد التشغيل.وسيتم استدعاؤه عبر PHP باستخدام shell_exec() بحيث تتم طباعة ملف PDF الناتج على الطابعة المرفقة بالخادم.

لذا فإن صفحتي PHP تبدو بشكل أساسي كما يلي:

shell_exec('/path/to/pdfGen.exe');

ولكن هنا تسوء الأمور.ما يحدث وفقًا لمدير المهام وما إلى ذلك:

  • pdfGen.exe يبدأ
  • يتم إنشاء ملف PDF
  • Acrord32.exe يبدأ
  • pdfGen.exe يتوقف إلى الأبد (وكذلك البرنامج النصي PHP) ولا تتم طباعة أي شيء

أنا متأكد من أنه بعض مشكلة متعلقة بالإذن.لقد أعطيت بالفعل IIS_IUSRS الوصول إلى الطابعة الافتراضية، وإلى الدليل حيث Acrord32.exe يقع.ولكن لا يزال، لا الطباعة.ومع ذلك، إذا قمت بتشغيل ملف pdfGen.exe يدويًا، فسيعمل.

هل لديك أي فكرة عما أفتقده؟

يحرر:

لست ملزمًا باستخدام Acrobat Reader لطباعة ملف PDF.إذا كان هناك طريقة أخرى لذلك بصمت طباعة جانب خادم PDF الذي تم إنشاؤه، لا أمانع على الإطلاق.

هل كانت مفيدة؟

المحلول 5

شكرا جميعا لتعليقاتكم.لسوء الحظ، كان هذا الشيء "php start printjob" جزءًا من مشروع أكبر تم إلغاؤه اليوم بسبب، حسنًا...لا أعرف...أسباب سياسية.أعتقد أن المشروع قد مات إلى حد كبير.

على أي حال، حاولت بنفسي عدة مرات في الأيام الأخيرة ولم أتمكن من تشغيله مع IIS.الحل الذي قمت بتنفيذه واختباره بالفعل:قم بإزالة IIS، وقم بتثبيت حزمة XAMPP أو WAMPP باستخدام Apache محلي وPHP الذي يعمل معه حقوق وصول المسؤول.

لقد فعلت هذه الحيلة.إستعملت pclose(popen('...command...', 'r')); في PHP من أجل بدء .exe وحتى لا تنتظر PHP حتى ينتهي ملف PDF.كل شيء يعمل بشكل رائع.

هذا هو رمز C# الخاص بي الذي يبدأ مهمة الطباعة باستخدام Acrobat Reader

public void Print(string pathname, string acrobatDirectory)
{
    var proc = new Process
    {
        StartInfo =
        {
            Arguments               = String.Format("/t \"{0}\"", pathname),
            FileName                = acrobatDirectory,
            UseShellExecute         = false,
            CreateNoWindow          = true,
            RedirectStandardOutput  = false,
            RedirectStandardError   = false,
        }
    };

    proc.Start();  
}  

الوسيطة الأولى هي المسار إلى ملف PDF الذي يجب طباعته، أما المعلمة الثانية فهي المسار المطلق إلى ملف AcroRd32.exe.

المشكلة الوحيدة المتبقية هي ذلك AcroRd32.exe بدأ وطبع ولم يتم إغلاقه مرة أخرى.لذلك بدأت كل مهمة طباعة مثيلًا جديدًا لـ AcroRd32.exe (أنا أستخدم برنامج Acrobat Reader 9.0).وبالتالي، إذا قمت بالطباعة 10 مرات، فسيتم إنشاء 10 مثيلات لبرنامج Acrobat Reader.

ما فعلته هو بدء مهمة الطباعة، ثم الانتظار لمدة X ثانية، على أمل أن تكون الطابعة قد انتهت ثم قتل الجميع AcroRd32.exe الحالات:

public void Print(string pathname, string acrobatDirectory)
{
    Debug.WriteLine("Printing...");

    Printer.Print(pathname, acrobatDirectory);

    Thread.Sleep(30000);

    try
    {
        Debug.WriteLine("Trying to kill runnung AcroRd32.exe's ");

        FindAndKillProcess("AcroRd32");
    }
    catch (Exception)
    {
        Debug.WriteLine("AcroRd32.exe could not be killed...");
    }
}

private bool FindAndKillProcess(string name)
{
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.StartsWith(name))
        {
            clsProcess.Kill();
            return true;
        }
    }

    return false;
}

لقد نجح هذا بشكل جيد.


لاحظ أن ما سبق (قتل الكل AcroRd32.exe وتشغيل PHP مع امتيازات المسؤول) كان ممكنًا فقط للأسباب التالية: يتم استخدام كل شيء من قبل مستخدم واحد فقط في كل مرة وله مساحة استخدام محدودة للغاية.

ويجب استخدامه على تطبيق شاشة تعمل باللمس يتم نشره في نقاط البيع الخاصة بالعملاء.يستخدم البائع تطبيق PHP لتكوين منتج، ثم يقوم PHP باستدعاء ملف .exe الخاص بي والذي من شأنه إنشاء ملف PDF وطباعته في الخلفية.ثم يتم تسليم المستند المطبوع إلى العميل. لذلك الأمن وما إلى ذلك.لم يكن حقا مصدر قلق في هذه الحالة.


إذا كان لدى أي شخص حل لاستخدامه مع IIS، فأنا لا أزال على استعداد لقبوله كإجابة.

نصائح أخرى

In order to check what is going on, try to run the مراقبة العملية من Sysinternals وقم بتصفية الأحداث إلى عملية Adobe Acrobat.ستشاهد مكالمات النظام الخاصة بـ Acrobat وسيسمح لك بمعرفة ما يحدث من خطأ بشكل أو بآخر.

أعرف تحسنًا طفيفًا في الحل الخاص بك:يحتوي SumatraPDF على واجهة سطر أوامر رائعة يمكن استخدامها لإغلاق Sumatra تلقائيًا بعد الطباعة.

لقد استخدمت PHP وظائف "النظام" أو "exec" لتنفيذ ملف دفعي لفتح SumatraPDF:

sumatrapdf.exe -print-to-default -exit-on-print <path_to_PDF_file>

(يمكنك أيضًا تحديد اسم الطابعة للطباعة عليها)

هذا برنامج مثير للاهتمام.

IIS_IUSRS يبدو أنه ليس لديه إذن للطباعة، حاول إضافة IIS_IUSRS لمجموعة عوامل الطباعة / منح إذن الطباعة للمستخدم.

shell_exec () مخصص تقريبًا لأوامر shell (ls/dir ، cp ، إلخ) هل حاولت استخدام exec () بدلاً من shell_exec ()؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top