2009-01-06 9 views
6

J'utilise un service Windows et je veux imprimer une page .html lorsque le service démarre. J'utilise ce code et ça s'imprime bien. Mais une boîte de dialogue d'impression vient, comment puis-je imprimer sans la boîte de dialogue d'impression?document html Imprimer du service Windows en C#, sans dialogue d'impression

public void printdoc(string document) 
{ 
    Process printjob = new Process(); 
    printjob.StartInfo.FileName = document; 
    printjob.StartInfo.UseShellExecute = true; 
    printjob.StartInfo.Verb = "print"; 
    printjob.StartInfo.CreateNoWindow = true; 
    printjob.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

    printjob.Start(); 
} 

Existe-t-il un autre moyen d'imprimer ceci sans afficher la boîte de dialogue d'impression.

Merci à l'avance, Anup Pal

+0

UseShellExecute et CreateNoWindow se contredisent dans ce cas. Vous ne pouvez en définir qu'un seul. Pour imprimer des documents plutôt que de démarrer des programmes, UseShellExecute doit être vrai. –

Répondre

-1

En service Windows le contrôle du navigateur Web de Microsoft ne fonctionne pas. J'ai utilisé ce code, il fonctionne très bien dans l'application Windows, mais quand je l'utilise dans un service Windows, le programme se coincer dans cette ligne

axWebBrowser1.Navigate (@ "C: \ mydoc.html", ref vide, ref vide, ref vide, ref vide);

merci pour la réponse, Anup Pal

13

Voici le Saint-Graal.

Profitant de StaTaskScheduler (prise de parallèle Extras Extension (release on Code Gallery)).

Caractéristiques: attend la fin de l'impression, ne montre pas les paramètres d'impression, nous l'espérons fiable.

Limites: nécessite C# 4.0, utilise l'imprimante par défaut, ne permet pas de changer modèle d'impression

TaskScheduler Sta = new StaTaskScheduler(1); 
    public void PrintHtml(string htmlPath) 
    { 
     Task.Factory.StartNew(() => PrintOnStaThread(htmlPath), CancellationToken.None, TaskCreationOptions.None, Sta).Wait(); 
    } 

    void PrintOnStaThread(string htmlPath) 
    { 
     const short PRINT_WAITFORCOMPLETION = 2; 
     const int OLECMDID_PRINT = 6; 
     const int OLECMDEXECOPT_DONTPROMPTUSER = 2; 
     using(var browser = new WebBrowser()) 
     { 
      browser.Navigate(htmlPath); 
      while(browser.ReadyState != WebBrowserReadyState.Complete) 
       Application.DoEvents(); 

      dynamic ie = browser.ActiveXInstance; 
      ie.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, PRINT_WAITFORCOMPLETION); 
     } 
    } 

//-------------------------------------------------------------------------- 
// 
// Copyright (c) Microsoft Corporation. All rights reserved. 
// 
// File: StaTaskScheduler.cs 
// 
//-------------------------------------------------------------------------- 

using System.Collections.Concurrent; 
using System.Collections.Generic; 
using System.Linq; 

namespace System.Threading.Tasks.Schedulers 
{ 
    /// <summary>Provides a scheduler that uses STA threads.</summary> 
    public sealed class StaTaskScheduler : TaskScheduler, IDisposable 
    { 
     /// <summary>Stores the queued tasks to be executed by our pool of STA threads.</summary> 
     private BlockingCollection<Task> _tasks; 
     /// <summary>The STA threads used by the scheduler.</summary> 
     private readonly List<Thread> _threads; 

     /// <summary>Initializes a new instance of the StaTaskScheduler class with the specified concurrency level.</summary> 
     /// <param name="numberOfThreads">The number of threads that should be created and used by this scheduler.</param> 
     public StaTaskScheduler(int numberOfThreads) 
     { 
      // Validate arguments 
      if (numberOfThreads < 1) throw new ArgumentOutOfRangeException("concurrencyLevel"); 

      // Initialize the tasks collection 
      _tasks = new BlockingCollection<Task>(); 

      // Create the threads to be used by this scheduler 
      _threads = Enumerable.Range(0, numberOfThreads).Select(i => 
      { 
       var thread = new Thread(() => 
       { 
        // Continually get the next task and try to execute it. 
        // This will continue until the scheduler is disposed and no more tasks remain. 
        foreach (var t in _tasks.GetConsumingEnumerable()) 
        { 
         TryExecuteTask(t); 
        } 
       }); 
       thread.IsBackground = true; 
       thread.SetApartmentState(ApartmentState.STA); 
       return thread; 
      }).ToList(); 

      // Start all of the threads 
      _threads.ForEach(t => t.Start()); 
     } 

     /// <summary>Queues a Task to be executed by this scheduler.</summary> 
     /// <param name="task">The task to be executed.</param> 
     protected override void QueueTask(Task task) 
     { 
      // Push it into the blocking collection of tasks 
      _tasks.Add(task); 
     } 

     /// <summary>Provides a list of the scheduled tasks for the debugger to consume.</summary> 
     /// <returns>An enumerable of all tasks currently scheduled.</returns> 
     protected override IEnumerable<Task> GetScheduledTasks() 
     { 
      // Serialize the contents of the blocking collection of tasks for the debugger 
      return _tasks.ToArray(); 
     } 

     /// <summary>Determines whether a Task may be inlined.</summary> 
     /// <param name="task">The task to be executed.</param> 
     /// <param name="taskWasPreviouslyQueued">Whether the task was previously queued.</param> 
     /// <returns>true if the task was successfully inlined; otherwise, false.</returns> 
     protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) 
     { 
      // Try to inline if the current thread is STA 
      return 
       Thread.CurrentThread.GetApartmentState() == ApartmentState.STA && 
       TryExecuteTask(task); 
     } 

     /// <summary>Gets the maximum concurrency level supported by this scheduler.</summary> 
     public override int MaximumConcurrencyLevel 
     { 
      get { return _threads.Count; } 
     } 

     /// <summary> 
     /// Cleans up the scheduler by indicating that no more tasks will be queued. 
     /// This method blocks until all threads successfully shutdown. 
     /// </summary> 
     public void Dispose() 
     { 
      if (_tasks != null) 
      { 
       // Indicate that no new tasks will be coming in 
       _tasks.CompleteAdding(); 

       // Wait for all threads to finish processing tasks 
       foreach (var thread in _threads) thread.Join(); 

       // Cleanup 
       _tasks.Dispose(); 
       _tasks = null; 
      } 
     } 
    } 
} 
+0

Comment cela n'a-t-il pas encore été mis à jour? Cela a fonctionné très bien pour moi! – JasonRShaver

+0

D'où vient "Task"? –

+0

https://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx –

1

Pour ajouter à la limitation de Vadim vous pouvez définir l'imprimante par défaut avant l'impression en utilisant:

static void SetAsDefaultPrinter(string printerDevice) 
    { 
     foreach (var printer in PrinterSettings.InstalledPrinters) 
     { 
      //verify that the printer exists here 
     } 
     var path = "win32_printer.DeviceId='" + printerDevice + "'"; 
     using (var printer = new ManagementObject(path)) 
     { 
      printer.InvokeMethod("SetDefaultPrinter", 
           null, null); 
     } 

     return; 
    } 

Et changeing légèrement la méthode PrintHtml avec:

public void PrintHtml(string htmlPath, string printerDevice) 
    { 
     if (!string.IsNullOrEmpty(printerDevice)) 
      SetAsDefaultPrinter(printerDevice); 


     Task.Factory.StartNew(() => PrintOnStaThread(htmlPath), CancellationToken.None, TaskCreationOptions.None, _sta).Wait(); 
    } 

maintenant, je ne sais pas h Ce qui sera juste dans un environnement d'impression lourd, étant donné qu'il pourrait y avoir des problèmes de concurrence avec la modification de l'imprimante par défaut beaucoup. Mais jusqu'à présent, c'est le meilleur que j'ai trouvé pour corriger cette limitation.