web-dev-qa-db-fra.com

Impression d'un PDF Silencieusement avec Adobe Acrobat

Je rencontre deux problèmes lorsque j'essaie d'imprimer un fichier PDF en mode silencieux en C # avec Adobe Acrobat. J'imprime les fichiers PDF à l'aide de Process.Start (). 

Le premier problème est que je ne peux pas lancer Adobe Acrobat sans spécifier le chemin d'accès complet à l'exécutable. Je suppose que cela ne l'ajoute pas à votre chemin lorsque vous l'installez. Existe-t-il un moyen simple de lancer la dernière version d’Acrobat sur une machine sans spécifier de noms de chemins complets? Je suis inquiet que le client va faire une mise à jour et casser mon code qui lance ceci. Je suis également préoccupé par leur installation sur des machines avec différentes versions de Windows (les chemins d'installation sont différents dans un environnement 64 bits par rapport à 32 bits).

Mon deuxième problème est le fait que chaque fois que je lance Acrobat et que je l’imprime, la fenêtre Acrobat reste ouverte. Je pensais que les paramètres de ligne de commande que j'utilisais supprimeraient tout cela, mais apparemment pas.

J'essaie de lancer Adobe Acrobat à partir de la ligne de commande avec la syntaxe suivante:

C:\Fichiers de programme (x86)\Adobe\Reader 10.0\Reader> AcroRd32.exe/t "Label.pdf" "HP4000" "HP LaserJet série 4100" "out.pdf"

Il s’imprime bien mais laisse toujours la fenêtre acrobate en haut. Y a-t-il une autre solution à part sortir et tuer le processus par programme?

16
Cole W

J'ai fini par utiliser Adobe Acrobat et je suis allé avec FoxIt Reader (lecteur de pdf gratuit) pour imprimer des fichiers pdf. C'est le code que j'utilise pour imprimer via FoxIt en 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();

Le code ci-dessus s'imprime sur l'imprimante par défaut, mais vous pouvez utiliser des paramètres de ligne de commande pour spécifier le fichier et l'imprimante. Vous pouvez utiliser la syntaxe suivante:

Foxit Reader.exe -t "fichier pdf" "nom de l'imprimante"

Mettre à jour:

Apparemment, les versions antérieures d’Acrobat n’ont pas non plus le problème décrit ci-dessus. Si vous utilisez une version beaucoup plus ancienne (4.x ou similaire), le problème ne se pose pas.

Certaines imprimantes prennent également en charge l’impression PDF native. Il est donc possible d’envoyer les données PDF brutes à l’imprimante, qui peut éventuellement l’imprimer. Voir https://support.Microsoft.com/en-us/kb/322091 pour l'envoi de données brutes à l'imprimante.

Mise à jour 2

Dans les versions ultérieures de notre logiciel, nous avons fini par utiliser un produit payant:

http://www.pdfprinting.net/

25
Cole W

La réponse de Nick me paraissait bonne, alors je l'ai traduite en c #. Ça marche!

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

Les éléments suivants ont été testés dans Acrobat Reader 8.1.3 et Acrobat Pro 11.0.06, et les fonctionnalités suivantes ont été confirmées:

  1. Localise l'exécutable Acrobat par défaut sur le système 
  2. Envoie le fichier à l'imprimante locale 
  3. Ferme Acrobat, quelle que soit la version 

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
Chris Schiffhauer

J'ai essayé à la fois Adobe Reader et Foxit sans succès. Les versions actuelles des deux sont très friands d'afficher des fenêtres et de laisser les processus en cours d'exécution. Nous avons fini par utiliser Sumatra PDF qui est très discret. Voici le code que j'utilise. Aucune trace de fenêtre ni de processus ne se termine bien lorsque l'impression est terminée.

    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();
    }
5
Fredrik Hall

obtenu une autre solution .. sa combinaison d'autres extraits de stackOverflow. Lorsque j'appelle CloseMainWindow, puis Kill .., Adobe se ferme

    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

Problème 1

Vous pourrez peut-être contourner le registre. Dans HKEY_CLASSES_ROOT\.pdf\PersistentHandler\(Default), vous devriez trouver un CLSID qui pointe vers une valeur trouvée dans l'un des deux emplacements. Soit le dossier CLSID de la même clé, soit (pour les systèmes 64 bits) un pas en avant dans Wow6432Node\CLSID puis dans la clé that CLSID.

Dans cette clé, vous pouvez rechercher LocalServer32 et trouver la valeur de chaîne par défaut pointant vers le chemin exe actuel.

Je ne suis pas à 100% sur tout cela, mais semble plausible (bien que vous deviez vérifier sur plusieurs environnements pour confirmer qu'effectue localement le processus que vous recherchez).

(Voici la documentation sur clés de registre impliquées concernant PersistentHandlers )

Problème 2

Probablement en utilisant le CreateNoWindow du processus StartInfo.

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();

(seulement une supposition cependant, mais je suis sûr qu'un petit test prouvera que cela fonctionne/ne fonctionne pas)

3
Brad Christie

Si vous utilisez Acrobat Reader 4.0, vous pouvez procéder comme suit: "C:\Program Files\Adobe\Acrobat 4.0\Lecteur\Acrord32.exe"/t/s "U:\PDF_MS\SM003067K08.pdf" Planning_H2 MAIS si le fichier PDF a été créé dans une version plus récente d'Acrobat, une fenêtre invisible s'ouvre.

3
Andrew Michnik

Pour le problème 2

L'utilisation de / h param ouvrira Acrobat ou Adobe Reader dans une fenêtre réduite.

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

Documentation associée: https://www.Adobe.com/content/dam/acom/fr/devnet/acrobat/pdfs/Acrobat_SDK_developer_faq.pdf#page=24

0
Nikita Jain

Comme vous avez déjà essayé quelque chose de différent d'Acrobat Reader, mon conseil est d'oublier les applications à interface graphique et d'utiliser un outil de ligne de commande tiers tel que 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
    }
}

Dernière version à télécharger: http://effisoft.pl/rawfileprinter

0
zuko