2017-09-25 13 views
-2

Webアプリケーションをサイレントに印刷するコンソールアプリケーションがあります。 Ref:Print WebBrowser without previewing i.e. single click printC#Windowsサービス - Webブラウザーコントロールがリリースモードで動作しない

Windowsサービスに変換しようとしています。コードはデバッグモードで正常に動作しますが、リリースモード(サービスをインストールした後)で失敗します。 (私は例として、google.comを印刷しました)これは、完全なコードです

Faulting application name: TestWindowsService.exe, version: 1.0.0.0, time stamp: 0x59c94fa7 
Faulting module name: MSHTML.dll, version: 11.0.9600.18792, time stamp: 0x59908408 

:イベントビューアには、としてエラーが発生しました

using System; 
using System.ServiceProcess; 
using System.Timers; 
using System.Threading.Tasks; 
using System.IO; 
using System.Threading; 
using System.Windows.Forms; 

namespace TestWindowsService 
{ 
    public partial class Scheduler : ServiceBase 
    { 
     private System.Timers.Timer timer1 = null; 
     public Scheduler() 
     { 
      InitializeComponent(); 
     } 

     public void onDebug() 
     { 
      OnStart(null); 
     } 

     protected override void OnStart(string[] args) 
     { 

      timer1 = new System.Timers.Timer(); 
      this.timer1.Interval = 3000; //every 3 seconds 
      this.timer1.Elapsed += new ElapsedEventHandler(this.timer1_Tick); 
      timer1.AutoReset = false; 
      timer1.Enabled = true; 
     } 

     private void timer1_Tick(object sender, ElapsedEventArgs e) 
     { 
      try 
      { 

       var task = MessageLoopWorker.Run(DoWorkAsync, "http://www.google.com"); 
       task.Wait(); 
       Console.WriteLine("DoWorkAsync completed."); 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("DoWorkAsync failed: " + ex.Message); 
      } 
      finally 
      { 
       if (null != timer1) 
       { 
        timer1.Start(); 
       } 
      } 
     } 

     public static class MessageLoopWorker 
     { 
      public static async Task<object> Run(Func<object[], Task<object>> worker, params object[] args) 
      { 
       var tcs = new TaskCompletionSource<object>(); 

       var thread = new Thread(() => 
       { 
        EventHandler idleHandler = null; 

        idleHandler = async (s, e) => 
        { 
         // handle Application.Idle just once 
         Application.Idle -= idleHandler; 

         // return to the message loop 
         await Task.Yield(); 

         // and continue asynchronously 
         // propogate the result or exception 
         try 
         { 
          var result = await worker(args); 
          tcs.SetResult(result); 
         } 
         catch (Exception ex) 
         { 
          tcs.SetException(ex); 
         } 

         // signal to exit the message loop 
         // Application.Run will exit at this point 
         Application.ExitThread(); 
        }; 

        // handle Application.Idle just once 
        // to make sure we're inside the message loop 
        // and SynchronizationContext has been correctly installed 
        Application.Idle += idleHandler; 
        Application.Run(); 
       }); 

       // set STA model for the new thread 
       thread.SetApartmentState(ApartmentState.STA); 

       // start the thread and await for the task 
       thread.Start(); 
       try 
       { 
        return await tcs.Task; 
       } 
       finally 
       { 
        thread.Join(); 
       } 
      } 
     } 

     // navigate WebBrowser to the list of urls in a loop 
     static async Task<object> DoWorkAsync(object[] args) 
     { 
      //logger.Info("Start working."); 
      var wb = new WebBrowser(); 
      wb.ScriptErrorsSuppressed = true; 

      if (wb.Document == null && wb.ActiveXInstance == null) 
      { 
       //logger.Info($"Unable to initialize the underlying WebBrowserActiveX"); 
       throw new ApplicationException("Unable to initialize the underlying WebBrowserActiveX"); 
      } 
      // get the underlying WebBrowser ActiveX object; 
      var wbax = (SHDocVw.WebBrowser)wb.ActiveXInstance; 
      TaskCompletionSource<bool> loadedTcs = null; 
      WebBrowserDocumentCompletedEventHandler documentCompletedHandler = (s, e) => 
       loadedTcs.TrySetResult(true); // turn event into awaitable task 

      TaskCompletionSource<bool> printedTcs = null; 
      SHDocVw.DWebBrowserEvents2_PrintTemplateTeardownEventHandler printTemplateTeardownHandler = (p) => 
       printedTcs.TrySetResult(true); // turn event into awaitable task 

      // navigate to each URL in the list 
      foreach (var url in args) 
      { 
       loadedTcs = new TaskCompletionSource<bool>(); 
       wb.DocumentCompleted += documentCompletedHandler; 
       try 
       { 
        wb.Navigate(url.ToString()); 
        // await for DocumentCompleted 
        await loadedTcs.Task; 
       } 
       finally 
       { 
        wb.DocumentCompleted -= documentCompletedHandler; 
       } 

       // the DOM is ready, 
       //Console.WriteLine(url.ToString()); 
       //Console.WriteLine(wb.Document.Body.OuterHtml); 

       // print the document 
       printedTcs = new TaskCompletionSource<bool>(); 
       wbax.PrintTemplateTeardown += printTemplateTeardownHandler; 
       try 
       { 
        wb.Print(); 
        // await for PrintTemplateTeardown - the end of printing 
        await printedTcs.Task; 
       } 
       finally 
       { 
        wbax.PrintTemplateTeardown -= printTemplateTeardownHandler; 
       } 
       //logger.Info($"{url.ToString()} is Complete "); 
       //Console.WriteLine(url.ToString() + " printed."); 
      } 

      wb.Dispose(); 
      return null; 
     } 

     protected override void OnStop() 
     { 
     } 
    } 
} 

これはProgram.csの

using System; 
using System.ServiceProcess; 
using System.Text; 
using System.Threading; 

namespace TestWindowsService 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     static void Main() 
     { 

#if DEBUG 
      Scheduler myservice = new Scheduler(); 
      myservice.onDebug(); 
      Thread.Sleep(Timeout.Infinite); 

#else 
      ServiceBase[] ServicesToRun; 
      ServicesToRun = new ServiceBase[] 
      { 
       new Scheduler() 
      }; 
      ServiceBase.Run(ServicesToRun); 
#endif 
     } 
    } 
} 

何ですか私は間違っている?すべてのポインタ?

+0

を、それがデバッグで作業し、リリースに失敗する理由を私は知りません。 – ProgSky

答えて

1

多分あなたがする必要があります: "ローカルシステムアカウント" として

  1. セットサービスログオンを。

  2. 「サービスとデスクトップの対話を許可する」を選択します。

enter image description here

+0

あなたのお返事ありがとうございますyaniv。私はこのオプションを試しましたが、うまくいきません。このオプションはVISTA以降無効になっているようです。この議論を見てください。 https://stackoverflow.com/questions/4237225/allow-service-to-interact-with-desktop-in-windows – ProgSky

関連する問題