18 votes

Comment puis-je envoyer un fax pour un pdf à partir d'un service Windows en utilisant FAXCOMEXLib ?

J'ai vu cette question posée auparavant, mais je n'ai pas vu de réponses définitives, et certainement pas de réponses qui résolvent mon problème. J'ai créé un service Windows pour envoyer des fax (de manière semi-automatique) en utilisant la bibliothèque FAXCOMEXLib. Jusqu'à présent, mon service a réussi à envoyer des fichiers texte (.txt). Mais lorsque j'essaie d'envoyer des fichiers pdf, jpg ou tif, j'obtiens l'erreur "Operation failed". Dans SO, j'ai vu beaucoup de discussions sur les permissions de l'utilisateur sous lequel le service est exécuté. J'ai essayé un grand nombre d'options différentes (Service local, Utilisateur local, utilisateur personnalisé avec des privilèges d'administrateur, autoriser le service à interagir avec le bureau). Mais rien ne semble faire de différence. Il semble que le service n'ait pas les autorisations nécessaires pour ouvrir l'application appropriée pour "imprimer" le fichier pdf, jpg ou tif. Mais je ne fais que spéculer. Quelqu'un a-t-il réussi à envoyer un fax via FAXCOMEXLib dans un service Windows ? Voici mon code qui envoie le fax :

fileName = @"D:\temp\FaxTest.txt"; //THIS WORKS
//fileName = @"D:\temp\FaxTest.pdf"; //Operation failed
//fileName = @"D:\temp\FaxTest.tif"; //Operation failed
faxDoc.Sender.Name = faxRec.From;
faxDoc.Sender.Company = faxRec.From;
faxDoc.Body = fileName;
faxDoc.Subject = faxRec.ReferenceId;
faxDoc.DocumentName = faxRec.ReferenceId;
var to = "xxxxxxxxxx";
faxDoc.Recipients.Add(to, "Some Name");
var serverName = Environment.MachineName;
string[] returnVal = faxDoc.Submit(serverName);

Au cas où vous vous poseriez la question, oui, ces fichiers existent bien sur le serveur avec ces noms, et ce sont des fichiers valides (je peux les ouvrir dans Adobe Reader et Picture Viewer). Et cela fonctionne également très bien si je l'exécute localement sur ma machine de développement. Et bien sûr, la visionneuse appropriée s'affiche avant l'envoi (sur ma machine locale). Je pense que, pour une raison quelconque, le service ne peut pas ouvrir la visionneuse. Quelqu'un a-t-il réussi à envoyer un PDF de cette manière dans un service Windows ?

3voto

Hans Passant Points 475940

Il est assez bien documenté dans l'article de MSDN . La chose non triviale qui doit se produire est que un peu de Le logiciel doit convertir le contenu du fichier en texte imprimable qui peut être faxé. Citation :

Les exemples de documents que vous pouvez envoyer comme corps de fax sont un fichier texte (.txt), un document Microsoft Word (.doc), ou une feuille de calcul Microsoft Excel (.xls). Lorsque vous envoyez une télécopie à partir d'un ordinateur client, le corps de la télécopie doit être associé à une application installée sur cet ordinateur, et l'application doit prendre en charge le verbe PrintTo ; sinon, la télécopie échouera.

Un test simple que vous pouvez effectuer consiste à cliquer avec le bouton droit de la souris sur le fichier dans l'Explorateur et à rechercher la commande "Imprimer". Ensuite, faites glisser le fichier vers une imprimante pour exercer le verbe "PrintTo". Si ces tests échouent, cela ne fonctionnera pas et vous devrez installer une application qui sait comment imprimer le fichier.

Le fait d'effectuer cette opération à partir d'un service impose des exigences supplémentaires à l'application qui effectue l'impression. Il y en a beaucoup qui ne se comportent pas particulièrement bien dans un service. En particulier lorsque vous essayez d'imprimer, Microsoft recommande fortement de ne jamais le faire dans un service. Ce n'est pas le cas des applications Office depuis peu, ce qui rend le conseil de MSDN déjà peu convaincant.

Sur mon ordinateur, l'extension .tif est associée à une application UWP, qui ne fonctionnera pas non plus dans un service. Il est difficile de donner de bons conseils étant donné le grand nombre d'applications qui gèrent ces extensions populaires. Le mieux est d'aller sur superuser.com et de nommer l'extension spécifique, la version de Windows et l'application que vous préférez utiliser. Faire cela à partir d'une session utilisateur est certainement la solution la plus simple.

3voto

Matt Spinks Points 3941

Je veux donner une réponse complète à cette question. Les réponses précédemment postées contenaient une partie de la solution, mais elles ne donnaient pas une image complète de tout ce que nous devions faire pour envoyer avec succès un fichier pdf via une ligne de fax, en utilisant FAXCOMEXLib dans notre service Windows personnalisé.

Je voudrais commencer par dire que FAXCOMEXLib est conçu pour une application console Windows, pas pour un service Windows. Vous pouvez même le lire dans la documentation. Et je pense que c'est la raison pour laquelle nous avons eu tant de mal à la faire fonctionner.

Cependant, nous avons réussi à le faire fonctionner (enfin) après de nombreux essais et erreurs. La plupart des problèmes que nous avons rencontrés étaient liés aux paramètres et aux autorisations d'Adobe Reader. Ce que nous avons découvert, c'est qu'Adobe Reader essayait de faire beaucoup de choses en coulisse lors du traitement d'un fichier PDf. Et ces "choses" qu'il essayait de faire nécessitaient une interaction avec l'utilisateur (cliquer sur des boîtes d'alerte, etc.). Lorsque ce processus est exécuté sous un service Windows, il n'y a pas d'interaction de l'utilisateur avec ce service, ce qui fait que notre processus se bloque indéfiniment et finit par échouer. Mais nous avons découvert qu'il existe un moyen de contourner tout cela. Voici comment nous avons procédé :

Voici le bout de code que nous utilisons et qui fonctionne :

fileName = @"D:\temp\FaxTest.pdf";
faxDoc.Sender.Name = faxRec.From;
faxDoc.Sender.Company = faxRec.From;
faxDoc.Body = fileName;
faxDoc.Subject = faxRec.ReferenceId;
faxDoc.DocumentName = faxRec.ReferenceId;
var to = "xxxxxxxxxx";
faxDoc.Recipients.Add(to, "Some Name");
var serverName = Environment.MachineName;
var myProcesses = Process.GetProcessesByName("AcroRd32");
foreach (var myProcess in myProcesses)
{
    if (DateTime.Now.Ticks - myProcess.StartTime.Ticks > TimeSpan.FromSeconds(30).Ticks) {
        myProcess.Kill();
    }
}
string[] returnVal = faxDoc.Submit(serverName);

Il y a plus de code que cela dans notre service, bien sûr. L'autre code fait des choses comme gérer les gestionnaires d'événements de rappel pour suivre le statut des fax envoyés/achevés/échecs, etc. Mais ceci est le "cœur" du code qui initie réellement l'envoi.

Et voici une liste des changements de configuration que nous avons apportés au serveur pour que notre service Windows personnalisé décode, rende et envoie correctement les fichiers PDF sous forme de fax. Certaines de ces modifications sont mentionnées dans certaines réponses, mais d'autres ne le sont pas, et je voulais que cette réponse soit complète.

  1. Connectez-vous en tant qu'administrateur au serveur et installez le rôle Fax Server sur le serveur.
  2. Assurez-vous que le périphérique/carte modem fax est correctement installé sur le serveur et que la ligne de fax est active. Vous pouvez essayer d'envoyer quelques télécopies de test avec des fichiers texte directement à partir de l'utilitaire Windows Fax. (Dans notre cas, nous avons rencontré des problèmes car nous devions composer le "9" et un code secret pour obtenir une ligne extérieure longue distance).
  3. Installez Adobe Reader sur le serveur.
  4. Créez un utilisateur sur le serveur pour que votre service Windows s'exécute "en tant que". Nous avons appelé notre utilisateur "FaxServiceUser".
  5. Connectez-vous au serveur en tant que cet utilisateur FaxServiceUser au moins une fois. Une fois connecté, définissez le périphérique "Adobe PDF" comme imprimante par défaut.
  6. En outre, lorsque vous êtes connecté en tant qu'utilisateur, ouvrez un fichier PDF en utilisant Adobe et cliquez sur les CLUF.
  7. Lorsque vous êtes connecté en tant qu'utilisateur et qu'Adobe Reader est ouvert, modifiez ces paramètres :
    • Si la case est cochée, décochez l'option "Afficher les messages lorsque je lance Reader" (sous "Général").
    • Décochez la case "Activer le mode protégé" au démarrage (Cette option ne s'applique peut-être qu'à Acrobat 10. Dans Acrobat 11, cette option a été déplacée dans Sécurité (améliorée) et s'intitule Activer le mode protégé au démarrage. Veillez à décocher cette option)
    • Décochez la case "Activer la sécurité renforcée" (sous "Sécurité (renforcée)" - ceci ne s'applique peut-être qu'à Acrobat 11 et aux versions ultérieures).
    • Sélectionnez l'option Updater et désactivez le téléchargement et l'installation automatiques des mises à jour.
    • Décochez "Créer des liens à partir d'URLs" (sous "Général")
    • Décochez "Faire en sorte que l'outil manuel lise les articles" (Sous "Général")
    • Décochez "Afficher les messages lorsque je lance Reader" (sous "Général").
    • Décochez "Calculer automatiquement les valeurs des champs" (Sous "Formulaires")
    • Décochez "Afficher les rectangles de mise au point" (Sous "Formulaires")
    • Décochez l'option "Afficher l'indicateur de débordement des champs de texte" (sous "Formulaires").
    • Décochez "Activer Acrobat JavaScript" (sous "Javascript")
    • Décochez "Afficher le dialogue de bienvenue" (sous "Révision").
    • Décochez "Afficher la boîte de dialogue d'avertissement de connexion au serveur lors de l'ouverture du fichier" (Sous "Révision")
  8. Si nécessaire, consultez ce lien pour obtenir de l'aide sur les paramètres d'Adobe Reader : http://kb.faxback.com/How+Pour+configurer+Adobe+XI+pour+l'utiliser+avec+NET+SatisFAXtion
  9. Après avoir construit, déployé et installé votre service Windows, modifiez les propriétés de votre service pour qu'il soit exécuté "en tant que" l'utilisateur que vous avez créé précédemment ("FaxServiceUser" dans notre cas).
  10. Ajoutez des autorisations pour ce FaxServiceUser à n'importe quel dossier dans lequel il doit lire/écrire/supprimer.
  11. Étant donné qu'Adobe est censé être exécuté en tant qu'application de bureau, ajoutez du code dans votre service pour libérer la mémoire utilisée par Adobe Reader (vous pouvez voir comment nous avons procédé dans le fichier myProcess.Kill() dans l'exemple de code).

Et ça devrait le faire. C'est un peu lourd, mais j'espère que cela donne un exemple complet de la façon de configurer Adobe Reader en conjonction avec votre service Windows personnalisé pour envoyer des fax à partir de fichiers PDF sur un serveur Windows. Nous le faisons depuis quelques mois maintenant sans aucun problème. Notre client a un faible volume de télécopies, je ne peux donc pas parler de la façon dont cela fonctionne avec un volume élevé de télécopies. Donc, si vous cherchez un moyen "gratuit" d'envoyer des fax, sans payer pour quelque chose comme Interfax, cela pourrait être une option viable, au moins pour un faible volume.

0voto

Nawfel Points 39

Le problème semble être lié au processus nommé "AcroRd32", qui ouvre le fax dans Acrobat Reader et le convertit en fichier TIFF avant de l'envoyer. Ce processus ne libère pas de mémoire.

Essayez d'arrêter le processus comme suit

Dim myProcesses() As Process Dim myProcess As Process
' How to retrieve the program associat with pdf, when i only know the file extension ?
myProcesses = Process.GetProcessesByName("AcroRd32") For Each myProcess In myProcesses
If Date.Now.Ticks - myProcess.StartTime.Ticks > TimeSpan.FromSeconds(30).Ticks Then
myProcess.Kill()
End If
Next

J'espère que cela vous sera utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X