【问题标题】:Printing PDFs from Windows Command Line从 Windows 命令行打印 PDF
【发布时间】:2013-10-08 02:55:29
【问题描述】:

我正在尝试打印当前目录中的所有 pdf。 当我在 cmd (singlepdf.sh) 中调用这个 bash 脚本时: '"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe"' /t Gemeinde_348_BioID_842_alt.pdf 一切正常。

使用此内容调用multiplepdfs.sh 时:

declare -a pdfs=(*.pdf)

for pdf in ${pdfs[@]}; do
  echo -e "\nprinting **$pdf** with AcroRd32.exe...\n"
  '"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe"' /t $pdf
  sleep 3
done

回显显示文件在循环中被正确寻址 - 但随后我收到错误"C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe": No such file or directory

有人可以帮忙解决这个问题吗?

编辑: 顺便说一句,我已经安装了 msys mingw

【问题讨论】:

    标签: windows pdf printing cmd sh


    【解决方案1】:

    我知道这是个老问题,但我最近遇到了同样的问题,没有一个答案对我有用:

    • 找不到旧版福昕阅读器
    • 正如@pilkch 所说,2Printer 添加了一个报告页面
    • Adobe Reader 打开一个 gui

    再搜索了一下,我发现了这个:http://www.columbia.edu/~em36/pdftoprinter.html。

    这是一个简单的 exe,您可以使用文件名调用它并打印到默认打印机(或您指定的打印机)。 来自网站:

    PDFtoPrinter 是一个从 Windows 命令行打印 PDF 文件的程序。该程序通常是为 Windows 命令行设计的,也可以与 vDos DOS 模拟器一起使用。

    要将 PDF 文件打印到默认的 Windows 打印机,请使用以下命令:

    PDFtoPrinter.exe filename.pdf
    

    要打印到特定打印机,请将打印机名称添加到引号中:

    PDFtoPrinter.exe filename.pdf "Name of Printer"
    

    如果要打印到网络打印机,请使用出现在 Windows 打印对话框中的名称,如下所示(并注意名称开头的两个反斜杠和服务器名称后的单个反斜杠):

    PDFtoPrinter.exe filename.pdf "\\SERVER\PrinterName"
    

    【讨论】:

    • 我尝试使用 PDFtoPrinter.exe,但它被我尝试过的多个病毒扫描程序标记为特洛伊木马。
    • 我是 PDFtoPrinter.exe 的作者。它是用 AutoIt 编写的,一些病毒扫描程序将任何 AutoIt 可执行文件标记为特洛伊木马,因为脚本小子使用 AutoIt。尝试将其提交到 VirusTotal.com 或 viruscan.jotti.org 以获得更新的报告。
    • @emendelson 是否有一些关于命令行参考的额外文档,访问源代码以了解我自己的工作方式?我想寻找一种方法让PDFtoPrinter.exe 自身同步,以便shell 上的调用者需要等待一切完成。
    • @ThorstenSchöning - 是的,PDFtoPrinter 使用 AutoIt 的“RunWait”来运行嵌入式 PDF-Xchange 查看器。欢迎您通过页面底部的地址与我联系,了解该计划;我宁愿在公开之前清理 AutoIt 代码的荒谬混乱,但如果您愿意私下查看,请与我们联系。同时,我发布了一个名为 PDFtoPrinterCLI.exe(同一站点)的命令行界面版本,您可以尝试一下。我不知道它是否会有所帮助;请告诉我。
    • @ThorstenSchöning - 还可以查看我网页上的调试选项。如果你使用它,它显示了如何运行打印命令,你可能根本不需要我的程序。
    【解决方案2】:

    我在使用 Acrobat Reader 完成这项任务时遇到了两个问题。

    1. 命令行 API 不受官方支持,因此可能会在没有警告的情况下更改或删除。
    2. 向 Reader 发送打印命令会加载 GUI,但似乎无法阻止它。我需要让流程对用户透明。

    我偶然发现了这个blog,它建议使用Foxit Reader。 Foxit Reader 是免费的,API 几乎与 Acrobat Reader 相同,但关键是有文档记录,不会加载用于打印作业的 GUI。

    提醒一句,不要不注意就点击安装过程,它也会尝试安装不相关的软件。为什么软件供应商还在这样做???

    【讨论】:

    • 我无法让 Foxit Reader (v7.0.6) 在后台静默打印。它会打开一个最小化的 GUI 版本,并且在手动关闭它之前不会返回控制 :( 所以我最终使用了 SumatraPDF,它具有命令行开关 -print-to-default(或 -print-to myprinter)和 -silent 允许完全无声的后台打印!如果返回代码为 0它成功,如果失败则为 1。参考:http://github.com/sumatrapdfreader/sumatrapdf/wiki/Command-line-arguments
    • 除了上述 7.06 及以下版本中概述的问题外,开关也发生了变化。以前静默打印只有/t,打印机名是可选的。如果省略了打印机名称,Foxit 会将文件发送到默认打印机。现在/p 已指定发送到默认打印机,而/t 要求有一个名为的打印机。
    • 如果您想在横向媒体上打印横向 PDF,SumatraPDF 就是垃圾!相反,它决定自动旋转您的 PDF。
    • v7 的问题已被确认为错误forums.foxitsoftware.com/forum/…
    • 根据您的操作,Adobe Reader License 不允许将其用于无头打印或从服务器打印或打印。如果您要批量进行大量打印并且需要速度,那么 SumatraPDF 会很慢。来自 SumatraPDF 论坛:“总的来说,Sumatra 不擅长打印,所以我不建议在 [大量场景] 中使用它。目前我们通过为每一页生成位图并将这些位图发送到打印机来打印。Adobe 更聪明。”
    【解决方案3】:

    您似乎缺少打印机名称、驱动程序和端口 - 按此顺序排列。您的最终命令应类似于:

    AcroRd32.exe /t <file.pdf> <printer_name> <printer_driver> <printer_port>
    

    例如:

    "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" /t "C:\Folder\File.pdf" "Brother MFC-7820N USB Printer" "Brother MFC-7820N USB Printer" "IP_192.168.10.110"
    

    注意:要查找打印机信息,请右键单击您的打印机并选择属性。在我上面显示的情况下,打印机名称和驱动程序名称匹配 - 但您的信息可能不同。

    【讨论】:

      【解决方案4】:

      错误信息告诉你。

      试试吧

      "C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe" /t "$pdf"
      

      当您将字符串括在单引号中时,这会使所有内容都包含在有效字符串中,包括" 字符。通过删除单引号,shell 会将 dbl 引号作为字符串“包装器”处理。

      我还将文件名变量包装在 dbl-quotes 中,以便您可以轻松处理名称中带有空格的文件,即

      "C:\Program Files (x86)\Adobe\Reader 10.0\Reader\AcroRd32.exe" /t "$pdf"
      

      IHTH

      【讨论】:

      • 我尝试了 qoutes 的每一种类型和变体,而 op 中的一个是唯一一个在循环之外工作的.. 使用单引号 adobe 打开文件但奇怪地给出了“打开时出错”的消息文件..”并且不将文件发送到打印机..
      • 感谢您的编辑,我只是​​发帖询问如何在 Windows 上运行 bash。我可以推荐的最好的方法是在脚本顶部附近添加set -vx,这样您就可以看到正在执行的内容,以及变量的值是如何使用的。此外,您可以尝试使用 ANSI 字符串,使用 $"c:\program ...." 或 $'c:\.....' 而不仅仅是普通的 dbl 或单引号。还将bash --version 的输出添加到您的帖子中。祝你好运。
      • 或尝试让您的 multipdf 脚本调用 singlepdf 并使用 file 参数?祝你好运。
      【解决方案5】:

      我在连续打印多个 PDF 文件时遇到了类似的问题,我发现只有使用 2Printer 软件才能解决问题。 打印 PDF 文件的命令行示例:

      2Printer.exe -s "C:\In\*.PDF" -prn "HP LasetJet 1100"
      

      http://doc2prn.com/http://doc2prn.com/可免费用于非商业用途

      【讨论】:

      • 免费版在每个页面上添加了一个报告页面,所以对我来说有点没用,因为 50% 的打印都是浪费。
      • 只要有效,我们就可以购买。但是请确保购买后它可以工作。您能否确认其可靠和标准。我们必须在企业中使用它。
      【解决方案6】:

      第一反应 - 最终想回馈一个有用的社区...

      希望将此添加到仍在寻找简单解决方案的人们的回复中。我正在使用 Foxit Software 的免费产品 - FoxItReader。
      这是与静默打印一起使用的版本的链接 - 较新版本的静默打印功能仍然无法正常工作。 FoxitReader623.815_Setup

      FOR %%f IN (*.pdf) DO ("C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe" /t %%f "SPST-SMPICK" %%f & del %%f) 
      

      我只是创建了一个命令来循环遍历目录并为每个 pdf 文件 (FOR %%f IN *.pdf) 静默打开阅读器 (/t) 获取下一个 PDF (%%f) 并将其发送到打印队列(SPST-SMPICK),然后在我将每个 PDF 发送到打印队列(del%%f)后删除它。 Shashank 展示了一个将文件移动到另一个目录的示例,如果您需要这样做

      FOR %%X in ("%dir1%*.pdf") DO (move "%%~dpnX.pdf" p/)
      

      【讨论】:

        【解决方案7】:

        使用 Acrobat 阅读器不是一个好的解决方案,尤其是命令行属性没有记录。此外,Acrobat 阅读器的窗口在打印过程后保持打开状态。 PDF 文件为打印机驱动程序所熟知,因此您可能会找到更好的工具,例如 2Printer.exe 或 RawFilePrinter.exe。在我看来,RawFilePrinter 有更好的支持和清晰的许可流程(您只需支付一次捐款,就可以在您喜欢的许多项目中重新分发 RawFilePrinter - 即使新版本也可以使用以前购买的许可)

        RawFilePrinter.exe -p "c:\Users\Me\Desktop\mypdffile.pdf" "Canon Printer" 
        IF %ERRORLEVEL% 1(
            echo "Error!"
        )
        

        要下载的最新版本:http://bigdotsoftware.pl/index.php/rawfileprinter

        【讨论】:

          【解决方案8】:

          这是另一个解决方案:

          1) 下载 SumatraPDF(便携版)-https://www.sumatrapdfreader.org/download-free-pdf-viewer.html

          2) 创建一个类库项目,将SumatraPDF.exe解压到项目目录根目录下并解封。

          3) 在项目属性中,转到资源选项卡并将 exe 添加为文件。

          4) 将以下类添加到您的库中:

          public class SumatraWrapper : IDisposable
          {
              private readonly FileInfo _tempFileForExe = null;
              private readonly FileInfo _exe = null;
          
              public SumatraWrapper()
              {
                  _exe = ExtractExe();
              }
          
              public SumatraWrapper(FileInfo tempFileForExe)
                  : this()
              {
                  _tempFileForExe = tempFileForExe ?? throw new ArgumentNullException(nameof(tempFileForExe));
              }
          
              private FileInfo ExtractExe()
              {
                  string tempfile = 
                      _tempFileForExe != null ? 
                      _tempFileForExe.FullName : 
                      Path.GetTempFileName() + ".exe";
          
                  FileInfo exe = new FileInfo(tempfile);
                  byte[] bytes = Properties.Resources.SumatraPDF;
          
                  using (FileStream fs = exe.OpenWrite())
                  {
                      fs.Write(bytes, 0, bytes.Length);
                  }
          
                  return exe;
              }
          
              public bool Print(FileInfo file, string printerName)
              {
                  string arguments = $"-print-to \"{printerName}\" \"{file.FullName}\"";
                  ProcessStartInfo processStartInfo = new ProcessStartInfo(_exe.FullName, arguments)
                  {
                      CreateNoWindow = true
                  };
                  using (Process process = Process.Start(processStartInfo))
                  {
                      process.WaitForExit();
                      return process.ExitCode == 0;
                  }
              }
          
              #region IDisposable Support
              private bool disposedValue = false; // To detect redundant calls
          
              protected virtual void Dispose(bool disposing)
              {
                  if (!disposedValue)
                  {
                      if (disposing)
                      {
                          // TODO: dispose managed state (managed objects).
                      }
          
                      // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
                      // TODO: set large fields to null.
                      try
                      {
                          File.Delete(_exe.FullName);
                      }
                      catch
                      {
          
                      }
          
                      disposedValue = true;
                  }
              }
          
              // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
              // ~PdfToPrinterWrapper() {
              //   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
              //   Dispose(false);
              // }
          
              // This code added to correctly implement the disposable pattern.
              public void Dispose()
              {
                  // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
                  Dispose(true);
                  // TODO: uncomment the following line if the finalizer is overridden above.
                  // GC.SuppressFinalize(this);
              }
              #endregion
          }
          

          5) 享受从您的代码中打印 pdf 文件的乐趣。

          这样使用:

          FileInfo file = new FileInfo(@"c:\Sandbox\dummy file.pdf");
          SumatraWrapper pdfToPrinter =
              new SumatraWrapper();
          pdfToPrinter.Print(file, "My Printer");
          

          【讨论】:

            【解决方案9】:

            以下批处理脚本应该可以实现您想要的。虽然它会在完成后让 Acrobat Reader 实例继续运行,但这不会在下次运行此脚本时造成任何问题。

            @echo off
            for %%f in (*.pdf) do (
              echo Printing %cd%\%%f with Adobe Acrobat Reader...
              start /b "Printing %%f" "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" /p /h "%cd%\%%f"
            )
            

            虽然之后您可以单独终止 Acrobat Reader 进程,但这可能会关闭您不想关闭的其他打开的 PDF 文档。

            【讨论】:

              【解决方案10】:
              @ECHO off set "dir1=C:\TicketDownload" 
              FOR %%X in ("%dir1%*.pdf") DO ( "C:\Program Files (x86)\Adobe\Reader 9.0\Reader\AcroRd32.exe" /t "%%~dpnX.pdf" "Microsoft XPS Document Writer" ) 
              FOR %%X in ("%dir1%*.pdf") DO (move "%%~dpnX.pdf" p/)
              

              试试这个..可能你有其他版本的阅读器所以这就是问题..

              【讨论】:

                【解决方案11】:

                今天我一直在寻找这个解决方案,我尝试了 PDFtoPrinter,但我遇到了问题(我尝试打印的 PDF 表明他们使用了不正确的纸张尺寸,导致打印作业挂起,在解决之前没有打印任何其他内容)。在我努力寻找替代方案的过程中,我想起了 GhostScript 和与之相关的实用程序。我发现 GSView 及其相关程序 GSPrint(参考 https://www.ghostscript.com/)。这两个都需要 GhostScript (https://www.ghostscript.com/),但是当所有组件都安装好后,GSPrint 可以完美运行,我能够创建一个计划任务,可以在一夜之间自动打印 PDF。

                【讨论】:

                  【解决方案12】:

                  另一种“开箱即用”的解决方案

                  FOR %X in ("*.pdf") DO (C:\Windows\System32\print.exe /d:"\\printername" "%X.pdf")

                  编辑: 正如“huysentruitw”所提到的,这仅适用于 txt 文件! 对不起!

                  当我仔细检查时,我意识到我正在使用 GhostScript,正如“Multiverse IT”所建议的那样。 看起来是这样的:

                  "C:\Program Files (x86)\gs\gs\bin\gswin32c.exe" -dPrinted -dBATCH -dNOPAUSE -dNOSAFER -q -dNumCopies=1 -sDEVICE=mswinpr2 -sOutputFile="%printer%My-Printer-Name" "c:\My-Pdf-File.pdf"
                  

                  【讨论】:

                  • print.exe 只打印纯文本,因此在打印这样的 PDF 文件时,您只会得到几页带有奇怪字符的页面。
                  猜你喜欢
                  • 2017-11-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-08-14
                  • 2011-09-24
                  • 1970-01-01
                  • 2011-09-11
                  • 2019-12-06
                  • 2011-12-04
                  相关资源
                  最近更新 更多