Question

Ce n’est probablement pas facile, mais voici la situation:

J'ai écrit une application en ligne de commande C # qui:

  • crée un PDF en utilisant ITextSharp
  • écrit sur le disque
  • utilise Acrord32.exe (il s’agit d’Acrobat Reader) via System.Diagnostics.Process afin d’imprimer en silence le fichier PDF généré

Si je construis ma solution et double-clique sur le pdfGen.exe , cela fonctionne comme prévu. Le PDF est créé et imprimé.

Maintenant, mon application doit être déployée sur un serveur interne sous Windows Vista exécutant IIS 7. Ce serveur exécute une application Web PHP. Et il sera appelé via PHP en utilisant shell_exec () pour que le PDF résultant soit imprimé sur l'imprimante connectée au serveur.

Donc, ma page PHP ressemble à ceci:

shell_exec('/path/to/pdfGen.exe');

Mais ici, les choses tournent mal. Qu'est-ce qui se passe est selon le gestionnaire de tâches, etc.:

  • pdfGen.exe démarre
  • le PDF est créé
  • Acrord32.exe démarre
  • pdfGen.exe est bloqué pour toujours (de même que le script PHP) et rien n'est imprimé

Je suis presque sûr qu'il s'agit d'un problème lié aux autorisations . J'ai déjà donné à IIS_IUSRS l'accès à l'imprimante par défaut et au répertoire où se trouve Acrord32.exe . Mais toujours pas d'impression. Cependant, si je lance manuellement pdfGen.exe, cela fonctionne.

Avez-vous une idée de ce qui me manque?

EDIT:

Je ne suis pas tenu d'utiliser Acrobat Reader pour imprimer le fichier PDF. S'il existe un autre moyen pour imprimer en silence le serveur PDF créé, cela ne me dérange pas du tout.

Était-ce utile?

La solution 5

Merci à tous pour vos commentaires. Malheureusement, ceci "php start printjob" Ce projet faisait partie d’un projet plus vaste qui a été annulé aujourd’hui pour des raisons bien… Je ne sais pas… pour des raisons politiques. Je suppose que le projet est à peu près mort.

Quoi qu’il en soit, je me suis essayé plusieurs fois au cours des derniers jours et j’ai été incapable de le faire fonctionner avec IIS. Ma solution que j'ai déjà implémentée et testée: supprimez IIS, installez un paquet XAMPP ou WAMPP avec un apache local et PHP qui s'exécute avec des droits d'accès administrateur .

Cela a fait le tour. J'ai utilisé pclose (popen ('... command ...', 'r')); en PHP afin de démarrer le .exe et que PHP le fasse n'attendez pas que le PDF soit fini. Tout a bien fonctionné.

Voici mon code C # qui démarre le travail d'impression avec Acrobat Reader

public void Print(string pathname, string acrobatDirectory)
{
    var proc = new Process
    {
        StartInfo =
        {
            Arguments               = String.Format("/t \"{0}\"", pathname),
            FileName                = acrobatDirectory,
            UseShellExecute         = false,
            CreateNoWindow          = true,
            RedirectStandardOutput  = false,
            RedirectStandardError   = false,
        }
    };

    proc.Start();  
}  

Le premier argument est le chemin du fichier PDF à imprimer, le second paramètre est le chemin absolu du AcroRd32.exe .

Le seul problème qui restait était que AcroRd32.exe avait été démarré, imprimé et jamais refermé. Ainsi, chaque printjob a lancé une nouvelle instance de AcroRd32.exe (j'utilise Acrobat Reader 9.0). Donc, si vous avez imprimé 10 fois, 10 instances d’Acrobat Reader ont été créées.

Ce que j'ai fait a été de lancer le travail d'impression, puis d'attendre X secondes, en espérant que l'imprimante était terminée, puis en tuant toutes les instances de AcroRd32.exe :

public void Print(string pathname, string acrobatDirectory)
{
    Debug.WriteLine("Printing...");

    Printer.Print(pathname, acrobatDirectory);

    Thread.Sleep(30000);

    try
    {
        Debug.WriteLine("Trying to kill runnung AcroRd32.exe's ");

        FindAndKillProcess("AcroRd32");
    }
    catch (Exception)
    {
        Debug.WriteLine("AcroRd32.exe could not be killed...");
    }
}

private bool FindAndKillProcess(string name)
{
    foreach (Process clsProcess in Process.GetProcesses())
    {
        if (clsProcess.ProcessName.StartsWith(name))
        {
            clsProcess.Kill();
            return true;
        }
    }

    return false;
}

Cela a très bien fonctionné.

Notez que ce qui précède (tuer tout le AcroRd32.exe et exécuter PHP avec des privilèges administrateur) n’était réalisable que pour les raisons suivantes: Tout cela n’est utilisé que par un utilisateur à la fois. domaine d'utilisation très limité .

Il doit être utilisé sur une application à écran tactile déployée sur le point de vente du client. Un vendeur utiliserait l'application PHP pour configurer un produit, puis PHP appellerait mon fichier .exe qui créerait et imprimerait un fichier PDF en arrière-plan. Le document imprimé est ensuite remis au client. La sécurité, etc., n'était donc pas vraiment une préoccupation dans ce cas.

Si quelqu'un a une solution pour l'utiliser avec IIS, je suis toujours prêt à l'accepter comme une réponse.

Autres conseils

Pour vérifier ce qui se passe, essayez de lancer le moniteur de processus de Sysinternals et filtre les événements dans le processus adobe acrobat . Vous verrez les appels système d’Acrobat et cela vous permettra de savoir plus ou moins ce qui ne va pas.

Je connais une petite amélioration à votre solution: SumatraPDF possède une belle interface de ligne de commande qui peut être utilisée pour fermer automatiquement Sumatra après l'impression.

J'ai utilisé PHP " system " ou " exec " fonctions permettant d'exécuter un fichier de commandes pour ouvrir SumatraPDF:

sumatrapdf.exe -print-to-default -exit-on-print <path_to_PDF_file>

(vous pouvez également spécifier le nom de l'imprimante sur laquelle imprimer)

c'est un programme intéressant.

IIS_IUSRS  semble ne pas avoir le droit d'imprimer, essayez d'ajouter IIS_IUSRS à l'opérateur d'opérateurs d'impression / accorder l'autorisation d'impression à l'utilisateur.

Shell_exec () est presque destiné aux commandes shell (ls / dir, cp, etc.) Avez-vous essayé d'utiliser exec () au lieu de shell_exec ()?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top