Luke
Luke

Reputation: 443

IIS Print PDF through CMD using acrord32.exe

I have a web application where i'm trying to print directly to a printer. The code works locally, however, I can't seem to get it to work on the test server.

The method is as follows;

internal void PrintStockTransactionPdf(string documentNumber, EnStockTransactionType transType)
{
    Guid fileName = Guid.NewGuid();
    string tempFilePath = String.Format("{0}{1}.pdf", Path.GetTempPath(), fileName.ToString());
    string adobePath = this._blSettings.GetSettingByName<string>("adobeReaderPath");
    string printerPath = this._blSettings.GetSettingByName<string>("printerPath");
    string url = "";

        // Retrieve the correct PDF
     if(transType == EnStockTransactionType.StockAdjustment)
         url = string.Format(this._blSettings.GetSettingByName<string>("stockadjustmentreporturl"), "PDF", documentNumber);
     else if (transType == EnStockTransactionType.StockRelocation)
         url = string.Format(this._blSettings.GetSettingByName<string>("stockrelocationreporturl"), "PDF", documentNumber);
     else if (transType == EnStockTransactionType.StockCheckout)
         url = string.Format(this._blSettings.GetSettingByName<string>("stockcheckoutreporturl"), "PDF", documentNumber);
     else if (transType == EnStockTransactionType.StockReturn)
         url = string.Format(this._blSettings.GetSettingByName<string>("stockreturnreporturl"), "PDF", documentNumber);

    // Save temp file
    File.WriteAllBytes(tempFilePath, this._blStock.GetStockTransactionFile(url));
    Process p = new Process()
    {
        StartInfo = new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            RedirectStandardInput = true,
            UseShellExecute = false
        }
    };
    p.Start();

    using (StreamWriter sw = p.StandardInput)
        if (sw.BaseStream.CanWrite)
        {
            // Print command
            sw.WriteLine(@"""{0}"" /h /t ""{1}"" ""{2}""", adobePath, tempFilePath, printerPath);
            // Delay 5 seconds to allow print to complete before killing Adobe
            sw.WriteLine("ping 1.1.1.1 -n 1 -w 5000 > nul");
            // Kill Adobe
            sw.WriteLine("taskkill /F /IM acroRD32.exe");
        }

    // Delay 5 seconds server side, before removing the temp file
    if (p.HasExited == false)
        p.WaitForExit(5000);
    p.Close();

    // Remove the temp file
    File.Delete(tempFilePath);

I've tried redirecting the standard output, which yields the following result;

Microsoft Windows [Version 6.2.9200](c) 2012 Microsoft Corporation. All rights reserved.
c:\windows\system32\inetsrv>"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" /h /t "C:\Windows\TEMP\b15df292-8fd5-46fb-8f8e-3427b6cc37b4.pdf" "\\<loc>\<printer>"
c:\windows\system32\inetsrv>ping 1.1.1.1 -n 1 -w 5000 > nul
c:\windows\system32\inetsrv>taskkill /F /IM acroRD32.exe
SUCCESS: The process "AcroRd32.exe" with PID 9652 has been terminated.
c:\windows\system32\inetsrv>

Which is all correct, and works if i run it directly through a command prompt.

The web app impersonates a user (on the server, not locally), which i've logged into the server as, and tried running the command through a cmd prompt as well (this also works).

I've also tried running a powershell command through the web app, which lists the available printers - the printer i'm trying to print to comes up as well.

Any information in rectifying this, or an alternate approach that is sure to work, would be greatly appreciated.

Thanks.

Upvotes: 1

Views: 1404

Answers (1)

yms
yms

Reputation: 10418

This cannot be done with Acrobat Reader, since it will always shows it's UI when printing, and you are not allowed to show a UI from a windows service. This is what you are doing when you use IIS on Windows Server.

As @PeterHahndorf mentioned in a comment, you should use a PDF component that can print the PDF for you. If a commercial component is ok for you, you can try with Amyuni PDF Creator .Net (Disclaimer: I work for Amyuni Technologies). If a library/application with an AGPL license is ok, you can try calling ghostscript from the command line for printing the file.

Upvotes: 1

Related Questions