使用Adobe Acrobat静默打印PDF

时间:2011-02-01 23:03:32

标签: c# acrobat

尝试使用adobe acrobat在C#中静默打印pdf时,我遇到了两个问题。我正在使用Process.Start()打印pdf。

第一个问题是,如果没有指定可执行文件的完整路径,我就无法启动Adobe Acrobat。我假设它在安装时不会将其添加到您的路径中。 是否有一种简单的方法可以在计算机上启动最新版本的acrobat而无需指定完整路径名?我担心客户端会进行更新并破坏启动此操作的代码。我也关心他们在具有不同版本的Windows的机器上安装它(64位环境和32位安装路径不同)。

我的第二个问题是,每当我启动acrobat并打印时,它仍然会打开acrobat窗口。我认为我使用的命令行参数会抑制所有这些,但显然不是。

我正在尝试使用以下语法从命令行启动adobe acrobat:

C:\ Program Files(x86)\ Adob​​e \ Reader 10.0 \ Reader> AcroRd32.exe / t“Label.pdf”“HP4000”“HP LaserJet 4100 Series PCL6”“out.pdf”

它打印得很好,但它仍然离开了acrobat窗口。 除了外出并以编程方式终止该流程之外还有其他解决方案吗?

9 个答案:

答案 0 :(得分:25)

我最终在这里使用Adobe Acrobat,并使用FoxIt Reader(免费pdf阅读器)进行pdf打印。这是我用来通过FoxIt在C#中打印的代码:

Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = @"C:\Program Files (x86)\Foxit Software\Foxit Reader\Foxit Reader.exe";
pdfProcess.StartInfo.Arguments = string.Format(@"-p {0}", fileNameToSave);
pdfProcess.Start();

上面的代码打印到默认打印机,但有一些命令行参数可用于指定文件和打印机。您可以使用以下语法:

Foxit Reader.exe -t“pdf filename”“打印机名称”

更新

显然早期版本的acrobat也没有上面列出的问题。如果你使用更旧的版本(4.x或类似的东西),它不会出现这个问题。

有些打印机也支持原生pdf打印,因此可以将原始pdf数据发送到打印机,然后打印出来。有关将原始数据发送到打印机的信息,请参阅https://support.microsoft.com/en-us/kb/322091

更新2

在我们软件的更高版本中,我们最终使用付费产品:

http://www.pdfprinting.net/

答案 1 :(得分:9)

尼克的回答对我很好,所以我把它翻译成了c#。它有效!

using System.Diagnostics;

namespace Whatever
{
static class pdfPrint
{
    public static void pdfTest(string pdfFileName)
    {
       string processFilename = Microsoft.Win32.Registry.LocalMachine
            .OpenSubKey("Software")
            .OpenSubKey("Microsoft")
            .OpenSubKey("Windows")
            .OpenSubKey("CurrentVersion")
            .OpenSubKey("App Paths")
            .OpenSubKey("AcroRd32.exe")
            .GetValue(String.Empty).ToString();

        ProcessStartInfo info = new ProcessStartInfo();
        info.Verb = "print";
        info.FileName = processFilename;
        info.Arguments = String.Format("/p /h {0}", pdfFileName);
        info.CreateNoWindow = true;
        info.WindowStyle = ProcessWindowStyle.Hidden; 
        //(It won't be hidden anyway... thanks Adobe!)
        info.UseShellExecute = false;

        Process p = Process.Start(info);
        p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

        int counter = 0;
        while (!p.HasExited)
        {
            System.Threading.Thread.Sleep(1000);
            counter += 1;
            if (counter == 5) break;
        }
        if (!p.HasExited)
        {
            p.CloseMainWindow();
            p.Kill();
        }
    }
}

}

答案 2 :(得分:8)

以下内容在Acrobat Reader 8.1.3和Acrobat Pro 11.0.06中进行了测试,并确认了以下功能:

  1. 在系统上找到默认的Acrobat可执行文件
  2. 将文件发送到本地打印机
  3. 关闭Acrobat,无论版本
  4. string applicationPath;
    
    var printApplicationRegistryPaths = new[]
    {
        @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\Acrobat.exe",
        @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRD32.exe"
    };
    
    foreach (var printApplicationRegistryPath in printApplicationRegistryPaths)
    {
        using (var regKeyAppRoot = Registry.LocalMachine.OpenSubKey(printApplicationRegistryPath))
        {
            if (regKeyAppRoot == null)
            {
                continue;
            }
    
            applicationPath = (string)regKeyAppRoot.GetValue(null); 
    
            if (!string.IsNullOrEmpty(applicationPath))
            {
                return applicationPath;
            }
        }
    }
    
    // Print to Acrobat
    const string flagNoSplashScreen = "/s";
    const string flagOpenMinimized = "/h";
    
    var flagPrintFileToPrinter = string.Format("/t \"{0}\" \"{1}\"", printFileName, printerName); 
    
    var args = string.Format("{0} {1} {2}", flagNoSplashScreen, flagOpenMinimized, flagPrintFileToPrinter);
    
    var startInfo = new ProcessStartInfo
    {
        FileName = printApplicationPath, 
        Arguments = args, 
        CreateNoWindow = true, 
        ErrorDialog = false, 
        UseShellExecute = false, 
        WindowStyle = ProcessWindowStyle.Hidden
    };
    
    var process = Process.Start(startInfo);
    
    // Close Acrobat regardless of version
    if (process != null)
    {
        process.WaitForInputIdle();
        process.CloseMainWindow();
    }
    

答案 3 :(得分:5)

我没有运气就试过Adobe Reader和Foxit。两者的当前版本都非常喜欢弹出窗口并让进程保持运行。使用Sumatra PDF结束,非常不引人注目。这是我使用的代码。在完成打印时,没有任何窗口和进程的痕迹很好地退出。

echo '<span class = "username">'.$row['username'].'</span>
          <form name = "matchcreator" class="amount" action="arena.php" method ="post">
          <input  name = "m-maker" type = "number" class="price"  min="5" max="100" value="5"/>
          <div class = "review">
          <p>REVIEW</p>
          </div>
          <button id ="send" type = "button" onclick="Confirm.render('."yes".','."no".')">Send Challenge</button>
          </form>';            
    echo "<br>";

答案 4 :(得分:4)

得到了另一个解决方案..它与stackOverflow的其他代码片段的组合。当我调用CloseMainWindow,然后调用Kill .. adobe关闭

    Dim info As New ProcessStartInfo()
    info.Verb = "print"
    info.FileName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("App Paths").OpenSubKey("AcroRd32.exe").GetValue(String.Empty).ToString()
    info.Arguments = String.Format("/p /h {0}", "c:\log\test.pdf")
    info.CreateNoWindow = True
    info.WindowStyle = ProcessWindowStyle.Hidden
    info.UseShellExecute = False

    Dim p As Process = Process.Start(info)
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden

    Dim counter As Integer = 0
    Do Until p.HasExited
        System.Threading.Thread.Sleep(1000)
        counter += 1
        If counter = 5 Then
            Exit Do
        End If
    Loop
    If p.HasExited = False Then
        p.CloseMainWindow()
        p.Kill()
    End If

答案 5 :(得分:3)

问题1

您可以在注册表中工作。在HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default)中,您应该找到一个CLSID,指向在两个位置之一中找到的值。相同密钥的CLSID文件夹,或(对于64位系统)在Wow6432Node\CLSID中向下一步,然后在 CLSID的密钥。

在该键中,您可以查找LocalServer32并找到指向当前exe路径的默认字符串值。

我不是100%的任何一个,但似乎有道理(尽管你将不得不在多个环境中进行验证,以确认实际上找到了你正在寻找的过程)。

(以下是registry keys involved关于PersistentHandlers

的文档

问题2

可能使用Process StartInfo的CreateNoWindow

Process p = new Process();
p.StartInfo.FileName = @"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe";
p.StartInfo.Arguments = "/t \"Label.pdf\" \"HP4000\" \"HP LaserJet 4100 Series PCL6\" \"out.pdf\"";
p.CreateNoWindow = true;
p.Start();
p.WaitForExit();

(但只是猜测,但我确定一点测试会证明它可以工作/不工作)

答案 6 :(得分:3)

如果您使用Acrobat reader 4.0,您可以执行以下操作: “C:\ Program Files \ Adob​​e \ Acrobat 4.0 \ Reader \ Acrord32.exe”/ t / s“U:\ PDF_MS \ SM003067K08.pdf”Planning_H2 但是,如果在较新版本的Acrobat中创建了PDF文件,则会打开一个不可见的窗口

答案 7 :(得分:0)

您已尝试过与Acrobat Reader不同的内容,因此我的建议是忘记GUI应用并使用第三方命令行工具,如RawFilePrinter.exe

private static void ExecuteRawFilePrinter() {
    Process process = new Process();
    process.StartInfo.FileName = "c:\\Program Files (x86)\\RawFilePrinter\\RawFilePrinter.exe";
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    process.StartInfo.Arguments = string.Format("-p \"c:\\Users\\Me\\Desktop\\mypdffile.pdf\" \"Canon Printer\"");

    process.Start();
    process.WaitForExit();
    if (process.ExitCode == 0) {
            //ok
    } else {
            //error
    }
}

下载最新版本:http://effisoft.pl/rawfileprinter

答案 8 :(得分:0)

对于问题2

使用 / h 参数将在最小化的窗口中打开Acrobat或Adobe Reader。

示例: C:\Program Files (x86)\Adobe\Reader 10.0\Reader>AcroRd32.exe **/h** /t "Label.pdf" "HP4000" "HP LaserJet 4100 Series PCL6" "out.pdf"

相关文档:https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24