Bonjour à tous,
Mon application (sur framework 4.0) a pour but de donner accès à une imprimante via une page web à des utilisateurs sur un autre réseau que celui de l’imprimante. Pour ce faire un formulaire d’upload permet de copié le fichier qui doit être imprimé dans un folder côté server. Une fois l’upload terminé, une méthode print (côté serveur) est appelée prenant le nom du fichier comme paramètre. Cette méthode est contenue dans un assembly appelé DistantPrintingFacilities. Voici la partie concernée du code :
Dans le code behind on a quelque chose comme :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Security; using System.Security.Permissions; using Microsoft.Win32; namespace DistantPrintingFacilities { public class DistantPrinting { #region Fields // Array of allowed file extension private static string[] _extension = { ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pps", ".ppsx", ".pdf", ".txt" }; private static List<String> _allowedExtension = new List<string>(_extension); private enum shellCommandType { Read, Open, Edit, Preview, Play }; #endregion #region Public Methods [SecuritySafeCritical] public void Print(string fileName) { new PermissionSet(PermissionState.Unrestricted).Assert(); lock (this) { try { Process myProcess = new Process(); myProcess.StartInfo = CreateStartInfo(fileName); myProcess.Start(); int i = 0; while (!myProcess.HasExited && i <= 45) { System.Threading.Thread.Sleep(1000); i += 1; } if (myProcess.HasExited) { myProcess.Dispose(); } else { while (!myProcess.Responding && i <= 45) { System.Threading.Thread.Sleep(1000); i += 1; } myProcess.Kill(); } } catch (Exception ex) { throw ex; } } } #endregion #region Private Methods private ProcessStartInfo CreateStartInfo(String fileLocation) { ProcessStartInfo starter = new ProcessStartInfo(); starter.UseShellExecute = true; String fileType = Path.GetExtension(fileLocation); switch (fileType) { case ".pdf": string pathToExecutable = GetFullName("AcroRD32.exe", shellCommandType.Read ); //GetFullName finds the path of the executable (here Acrobat Reader) starter.FileName = pathToExecutable; starter.Arguments = "/t " + fileLocation; break; default: if (_allowedExtension.Find(ex => ex.Equals(fileType)) != null) { starter.FileName = fileLocation; starter.LoadUserProfile = true; starter.Verb = "Print"; starter.WindowStyle = ProcessWindowStyle.Hidden; starter.CreateNoWindow = true; } else throw new NotSupportedException("Not allowed extension"); break; } return starter; }
Tout ceci fonctionne très bien quand je debug dans Visual Studio (2010). Le problème est que lorsque le site web est déployé sur IIS rien ne se passe. C-à-d que le fichier est bien uploader, un process est bien crée - comme winword.exe ou AcroRd32.exe (visible dans le gestionnaire de tâches - mais avec une mémoire utilisée bien inférieure à ce qui devrait être) pourtant rien ne s’imprime jamais.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 //Code pour uploader try { DistantPrinting dop = new DistantPrinting(); dop.Print(_path + filename); } catch (Exception ex) { LabelStatusOK.Text = ""; LabelStatusError.Text = "An error occurred when trying to print" + ex.Message; } //dautres lignes de code pour remplir un peu plus la page :)
Plusieurs choses sont également à noter :
L’identité que j’ai donné au pool d’application a des droit d’admin sur ma machine (juste pour tester les problèmes de droits) - qui fonctionne sous Windows 7. Dans ce cas de figure je peux imprimer des pdf, rien d’autres. En faisant la même chose sur le server (Windows Server 2008) je ne peux même pas imprimer des pdf. Je soupçon que le problème soit du a une histoire de CAS (qui semble avoir subit de forte modif pour la version 4.0), puisqu’il semblerait qu’un assembly qui tourne sous ASP.net est sandboxé (mais bon c'est peut-être tout autre chose). J’ai fait différent test (comme essayer de faire un assert dans ma fonction print), mais ça n’a rien donné. Je dois avouer que le principe me passe un peu au dessus de la tête.
J’ai également essayé l’appli en installant l’assembly dans le GAC, sans que ça change quelque chose.
Est-ce que quelqu’un a une idée, ou a déjà rencontré le problème?
Merci.
A++
Partager