1

我有一个批处理脚本,它循环一个文件夹并使用 GhostScript (9.07) 将其中的 PDF 展平。我想将其转换为 PowerShell 脚本,因为它似乎喜欢偶尔崩溃,而且我只是厌倦了调试批处理文件。

无论如何,我有一个似乎可以工作的 PS 脚本,基于它在控制台中的输出,但我实际上并没有得到任何文件。PS中的手动输入似乎更有效......我做错了什么?

批处理脚本

@ECHO OFF
::
:: Process all PDFs and flatten them to PDF/A format
:: =====================================================================================
FOR %%F IN ("J:\Finals\*.pdf") DO (
    IF /I %%F NEQ "*Floor Plan*.pdf" (
::      Convert the original PDF to a flattened PDF PDF/A
::      ========================================================================
        "%ProgramFiles%\gs\gs9.07\bin\gswin64.exe" -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="J:\Finals\%%~nF (Final).pdf" "%%F"
::
::      Delete the original PDF file
::      ========================================================================
        DEL "%%F" /F /Q
::
::      Rename the flattened PDF PDF/A to the original PDF's name
::      ========================================================================
        MOVE "J:\Finals\%%~nF (Final).pdf" "%%F"
    )
)
::
:: Move files form the Readdle drive to the Digital Documents drive
:: =====================================================================================
ROBOCOPY J:\Finals\ K:\ *.* /MOV /R:0 /W:0 /MT

PowerShell 脚本(到目前为止)

$GhostScript = "$env:ProgramFiles\gs\gs9.07\bin\gswin64c.exe"

Get-ChildItem "C:\Test In\*.pdf" | Where {
    $_.BaseName -NotMatch "Floor Plan"
} | ForEach-Object {
    $InputFile = $_.FullName
    $OutputFile = "C:\Test Out\{0} (Final).pdf" -F $_.BaseName

    & "$GhostScript" -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="$OutputFile" "$InputFile"
}

PowerShell 脚本的输出

GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Substituting font Times-Italic for TimesNewRomanPS-ItalicMT.
Loading NimbusRomNo9L-ReguItal font from %rom%Resource/Font/NimbusRomNo9L-ReguItal... 4198200 2870566 3665244 2332637 3 done.
Substituting font Courier for CourierNewPSMT.
Loading NimbusMonL-Regu font from %rom%Resource/Font/NimbusMonL-Regu... 3755680 2306439 4089108 2566088 3 done.
Loading NimbusRomNo9L-Regu font from %rom%Resource/Font/NimbusRomNo9L-Regu... 3796376 2391131 4078352 2484871 3 done.
Loading Dingbats font from %rom%Resource/Font/Dingbats... 3917480 2509851 4280192 2689988 3 done.

任何关心这个的人都在 Windows Server 2008 R2 虚拟机上进行测试。它有 4GB 的 RAM 和 4 个 vCPU。我还检查了我使用的测试文件夹是否存在权限问题,但事实并非如此。

更新

我已经更新了我的帖子以显示当前脚本的样子。将$OutputFile变量括在引号中不会做任何事情。无论是否引用引号,我总是得到输出(我在上面添加),表明 GhostScript 正在做它应该做的事情,但最终我没有创建任何文件......

4

5 回答 5

1

对我来说,使用 PDFtk 生成的 PDF 比原始 PDF 更大,所以这不是很有帮助。我也想使用 powershell,因为这只是这些天要走的路,但是在 powershell 中执行 ghostscript 也遇到了麻烦。由于它在使用批处理文件时运行良好,因此我选择使用带有两个参数的批处理文件运行 ghostscript,我在我的 powershell 脚本中调用了两个参数。

精简版(没有循环和清理)如下所示:

$script = "C:\path\to\script.cmd"
$InputFile = "C:\path\to\input.pdf"
$OutputFile = "C:\path\to\output.pdf"
& $script $InputFile $OutputFile

批处理脚本如下所示:

echo off
set arg1=%1
set arg2=%2

"C:\Program Files\gs\gs9.19\bin\gswin64c.exe" -sDEVICE=pdfwrite -dPDFSETTINGS=/screen -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH -sOutputFile=%arg2% %arg1%
于 2016-09-20T13:16:28.473 回答
0

您的$OutFile变量会生成一个包含空格的路径,您需要用引号将其括起来:

& $GhostScript -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="$OutputFile" $InputFile
于 2013-03-19T01:30:21.150 回答
0

嗯,我想出了一个解决办法。它涉及选择不使用 GhostScript for PDFtk。说真的,我不知道 GhostScript 的交易是什么,但它只是拒绝 100% 工作。它工作了 95%,但我真正关心的最后 5%(输出的文件)从未发生过。无论如何,我改为使用 PDFtk,它可以正常工作,而且对于完全相同的任务,它的工作速度也比 GhostScript 快很多倍。我不明白...

这是我最终的 PowerShell 脚本的样子:

$PDFtk = "C:\Program Files (x86)\PDF Labs\PDFtk Server\bin\pdftk.exe"

If (Test-Path $PDFtk) {
    Get-ChildItem "J:\Finals\" | Where-Object {
        $_.Extension -Match "pdf"
    } | ForEach-Object {
        $InputFile = $_.FullName
        $OutputFile = "J:\Finals\{0} (Flattened).pdf" -F $_.BaseName
        $DigitalDocumentsFile = "K:\{0}" -F $_.Name

        & $PDFtk $InputFile OUTPUT $OutputFile FLATTEN

        If (Test-Path $OutputFile) {
            Remove-Item $InputFile
            Move-Item $OutputFile $DigitalDocumentsFile
        }
    }
}
于 2013-03-20T00:36:18.723 回答
0

我知道这个问题已经很老了——但这是我对这种情况的看法。

批处理脚本是否自行尝试以查看是否生成了任何输出文件 - 如果没有,可能是批处理脚本中的删除文件命令在 GhostScript 可执行文件完成执行之前运行。

要解决此问题,可以尝试以下两种方法之一

  1. 通过 timeout 命令在 ghostscript 调用和删除命令之间添加延迟

    timeout /t 3 /nobreak > nul

将增加 3 秒延迟。调整它以满足您的要求。

  1. 在 ghostscript 调用的开头添加“start”命令

    start /wait /min "" "%ProgramFiles%\gs\gs9.07\bin\gswin64.exe" ...

/wait 开关将导致 del 命令仅在启动目标完成后执行。/min 开关将抑制控制台窗口的闪烁。/min 开关后的空字符串 "" 是必要的,以避免 start 命令将 ghostscript 可执行文件的路径视为控制台标题。

此外,将 ghostscript 参数替换为

-q -dNOPAUSE -dBATCH -dSAFER -dSimulateOverprint=true -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -dEmbedAllFonts=true -dSubsetFonts=true -dAutoRotatePages=/None -dColorImageDownsampleType=/Bicubic -dColorImageResolution=150 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=150 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=150 

可能会导致生成的 pdf 比原始帖子中使用的最小设置小得多。

于 2021-11-29T06:52:21.417 回答
0

这实际上很奇怪。我用进程监视器查看了这个。当没有被双引号括起来时,Ghostscript 实际上按字面意思输出到 '$Outputfile'。

 & $GhostScript -dPDFA -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile="$OutputFile" $InputFile

这对我来说已经足够了,即使在 $ghostscript 和 $inputfile 变量中有空格。看起来powershell通常不会解释看起来像-parameter的变量,除非冒号在它前面,或者它是双引号,即使在PS 6中也是如此。

更简单的演示:

$a = 'hi'

echo -InputObject$a

-InputObject$a

echo -InputObject"$a"

-InputOjbecthi

echo -InputObject:$a

hi
于 2019-07-07T16:04:18.500 回答