web-dev-qa-db-ja.com

PDF Adob​​e Acrobatで静かに印刷する

Adobe acrobatを使用してC#でPDFをサイレント印刷しようとすると、2つの問題が発生します。 Process.Start()を使用してPDFを印刷しています。

最初の問題は、実行可能ファイルへのフルパスを指定しないとAdobe Acrobatを起動できないことです。インストールしたときにパスに追加されないと思います。 フルパス名を指定せずにマシンで最新バージョンのacrobatを起動する簡単な方法はありますか?クライアントが更新を実行してこれを起動するコードを壊すのではないかと心配しています。また、Windowsのバージョンが異なるマシンにこれをインストールすることにも関心があります(64ビット環境と32ビット環境ではインストールパスが異なります)。

私の2番目の問題は、アクロバットを起動して印刷すると、アクロバットウィンドウが開いたままになるという事実です。私が使用していたコマンドラインパラメーターはこれをすべて抑制できると思いましたが、明らかに抑制されていません。

コマンドラインから次の構文で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のウィンドウは開いたままです。 プログラムを使用してプロセスを強制終了する以外に他の解決策はありますか?

17
Cole W

私はここでAdobe Acrobatを使用して、PDF印刷を行うために FoxIt Reader (無料のPDFリーダー)を使用しました。これは、C#でFoxItを介して印刷するために使用しているコードです。

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ファイル名" "プリンター名"

更新:

どうやら以前のバージョンのacrobatにも、上記の問題はありません。はるかに古いバージョン(4.xまたは類似のもの)を使用している場合、この問題は発生しません。

一部のプリンターはネイティブpdf印刷もサポートしているため、未加工のpdfデータをプリンターに送信して印刷できる場合があります。生データをプリンターに送信する方法については、 https://support.Microsoft.com/en-us/kb/322091 を参照してください。

アップデート2

それ以降のバージョンのソフトウェアでは、有料の製品を使用することになりました。

http://www.pdfprinting.net/

26
Cole W

ニックの答えは良さそうだったので、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();
        }
    }
}

}

9
Phil in Seattle

以下は、Acrobat Reader 8.1.3とAcrobat Pro 11.0.06の両方でテストされ、以下の機能が確認されています。

  1. システム上でデフォルトのAcrobat実行可能ファイルを見つけます
  2. ファイルをローカルプリンターに送信します
  3. バージョンに関係なくAcrobatを閉じます
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();
}
8

私は運が悪いのにAdobe ReaderとFoxitの両方を試しました。両方の現在のバージョンは、ウィンドウをポップアップしてプロセスを実行したままにすることを非常に好みます。最終的に Sumatra PDF を使用しましたが、非常に目立たなくなります。これが私が使用するコードです。印刷が完了すると、ウィンドウとプロセスのトレースはうまく終了しません。

    public static void SumatraPrint(string pdfFile, string printer)
    {
        var exePath = Registry.LocalMachine.OpenSubKey(
            @"SOFTWARE\Microsoft\Windows\CurrentVersion" +
            @"\App Paths\SumatraPDF.exe").GetValue("").ToString();

        var args = $"-print-to \"{printer}\" {pdfFile}";

        var process = Process.Start(exePath, args);
        process.WaitForExit();
    }
7
Fredrik Hall

別のソリューションを得た..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
4
Nick

問題1

レジストリを回避できる場合があります。 HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default)では、2つの場所のいずれかにある値を指すCLSIDを見つける必要があります。同じキーのCLSIDフォルダー、または(64ビットシステムの場合)Wow6432Node\CLSIDを1ステップ下にしてからthatCLSIDのキーを入力します。

そのキー内でLocalServer32を探し、現在のexeパスを指すデフォルトの文字列値を見つけることができます。

私はこれについて100%ではありませんが、もっともらしいようです(あなたが探しているプロセスが実際にあることを確認するために、複数の環境で確認する必要があります)。

(これは 関連するレジストリキー に関するドキュメントです PersistentHandlers に関する)

問題2

おそらくプロセス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();

(しかし、推測だけですが、少しのテストでそれが機能する/機能しないことを証明すると確信しています)

3
Brad Christie

Acrobat Reader 4.0を使用している場合、次のようなことができます。 "C:\ Program Files\Adob​​e\Acrobat 4.0\Reader\Acrord32.exe"/t/s "U:\ PDF_MS\SM003067K08.pdf" Planning_H2 BUT = PDF新しいバージョンのAcrobatでファイルが作成され、非表示のウィンドウが開きます

3
Andrew Michnik

問題2の場合

/ hparamを使用すると、最小化されたウィンドウで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

0
Nikita Jain

あなたはすでに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

0
zuko