none
Windows Dienst, Crystal Reports, Fehler 5 RRS feed

  • Frage

  • Hallo,

     

    erstmal hoffe ich, dass ich im richtigen Forum poste ;)

    Nun zu meinem Problem: Kurzgesagt, habe einen Windows Dienst geschrieben. Der überprüft nen Ordner und sieht nach welche Crystal Reports sich darin befinden, liest auch welche die letzte pdf Version des Reports ist und exportiert den Bericht mit den aktuellen Daten.

    Meine dev Maschine ist Win7 Prof x64, VS 2010. Ich installiere den Dienst mit installutil, setze den Beutzer des Dienstes mit einem User des Active Diretorys, damit ich DB Zugriff habe, und starte den Dienst. Funzt einwandfrei.

    Meine Ziel Maschine ist Win XP SP3. .NET 4.5 und Crystal Reports Runtime Engine sind installiert. Ich logge mich mit dem lokalen Admin ein, installiere den Dienst mit RunAsSvc und sage dem Dienst als welcher Benutzer er starten soll (wie oben, wegen AD). Leider bekomm ich dann beim starten des Dienstes einen

    "Fehler 5: Zugriff verweigert"

    sowohl als lokaler Admin, als auch als AD User als der der Dienst ausgeführt wird.

    Weis da vllt jemand Abhilfe? Wäre über jeden Rat/Hinweis dankbar ;)

     

    Danke, mfg

     

    PS: Hier der Code des Dienstes.

     

     

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.IO;
    using CrystalDecisions.CrystalReports.Engine;
    using CrystalDecisions.Shared;
    using System.Timers;
    using Microsoft.Win32;
    
    
    namespace semperit_autoexport_svc
    {
     public partial class CystalReportsAutoexport : ServiceBase
     {
     string _path;
     List<string> _reports;
     Timer _timer;
     public CystalReportsAutoexport()
     {
     InitializeComponent();
     
     //Timer zum Start auf 10 Sekunden gestetzt, um Dienst zu starten, warten, und dann erst Arbeit ausführen.
     //Wenn SVC beim Start mit Arbeit beginnt, startet er nicht
     _timer = new Timer(10000);
     _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
     _timer.Start();
     }
    
     protected override void OnStart(string[] args)
     {
     this.EventLog.WriteEntry("CR Autoexport Dienst gestartet");
     }
    
     protected override void OnStop()
     {
     this.EventLog.WriteEntry("CR Autoexport Dienst gestoppt");
     }
    
     void timer_Elapsed(object sender, ElapsedEventArgs e)
     {
     _timer.Stop();
     startWork();
     //Timer auf 12 Stunden gesetzt
     _timer.Interval = 43200000;
     _timer.Start();
     }
    
     private void startWork()
     {
     _path = @"C:\Temp\";
    
     if (prepareWork() == true)
     {
     for (int i = 0; i < _reports.Count; i++)
     {
      //this.EventLog.WriteEntry("Aufruf dowork: " + _path + _reports[i].Replace(".rpt", "").ToString() + "\\" + i.ToString());
      doWork(_path + _reports[i].Replace(".rpt", "") + "\\", i);
     }
     }
     }
    
     private bool prepareWork()
     {
     try
     {
     _reports = (from x in new DirectoryInfo(_path).GetFiles("*.rpt")
      orderby x.Name ascending
      select x.Name).ToList();
     //this.EventLog.WriteEntry("_reports Anzahl: " + _reports.Count.ToString());
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("Error: Hole *.rpt Files \r\n" + ex.Message);
     return false;
     }
    
     try
     {
     foreach (var item in _reports)
     { if (!Directory.Exists(_path + item.Replace(".rpt", ""))) Directory.CreateDirectory(_path + item.Replace(".rpt", "")); }
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("Error: Erstelle Root Ordner \r\n" + ex.Message);
     return false;
     }
    
     return true;
     }
    
     private void doWork(string path, int index)
     {
     DirectoryInfo di = new DirectoryInfo(path);
    
     try
     {
     FileInfo[] files = di.GetFiles("*", SearchOption.AllDirectories);
     if (files.Count() > 0)
     {
      var lastFile = (from x in di.GetFiles("*", SearchOption.AllDirectories)
       orderby x.CreationTime ascending
       select x.Name).Last();
      var lastDate = lastFile.Split('-')[1];
      var lastTime = lastFile.Split('-')[2];
      lastTime = lastTime.Split('.')[0];
    
      //this.EventLog.WriteEntry("lastfile: " + lastFile + " " + lastDate + " " + lastTime);
    
      try
      {
      DateTime date = new DateTime(Convert.ToInt32(lastDate.Split('.')[2]), Convert.ToInt32(lastDate.Split('.')[1]), Convert.ToInt32(lastDate.Split('.')[0]));
      if (date.Date.AddDays(1) >= DateTime.Now.Date && lastTime == "1200 bis 2359") return;
      //this.EventLog.WriteEntry("Aufruf exportPDF: " + lastTime + date + path + index.ToString());
      exportPDF(lastTime, date, path, index);
      }
      catch (Exception ex)
      { this.EventLog.WriteEntry("Error: " + ex.Message); }
     }
     else
     {
      //DateTime date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).AddDays(-2);
      try
      {
      DateTime date = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).AddDays(-2);
      //this.EventLog.WriteEntry("Aufruf exportPDF: " + "1200 bis 2359" + date.ToShortDateString() + path + index.ToString());
      exportPDF("1200 bis 2359", date, path, index);
      }
      catch (Exception ex)
      { this.EventLog.WriteEntry("Error: " + ex.Message); }
      //exportPDF("1200 bis 2359", date, path, index);
     }
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("CR Autoexport Dienst Fehler: Hole Infos letzte Datei Subordner " + index + " " + "\r\n" + ex.Message + "\r\n" + ex.InnerException + "\r\n" + ex.HelpLink);
     }
     }
    
     private bool exportPDF(string timespan, DateTime date, string path, int index)
     {
     ReportDocument rd = new ReportDocument();
     try
     {
     rd.Load(_path + _reports[index]);
     rd.SetDatabaseLogon("USER", "PW", @"DB", "");
     rd.Refresh();
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("Error: Datenbankzugriff \r\n" + ex.Message);
     return false;
     }
    
     ParameterFields paramFields = new ParameterFields();
     ParameterField paramField = new ParameterField();
     ParameterDiscreteValue Zeitraum = new ParameterDiscreteValue();
     ParameterDiscreteValue Datum = new ParameterDiscreteValue();
    
     if (timespan == "1200 bis 2359")
     {
     Zeitraum.Value = "00:00 bis 11:59";
     date = date.AddDays(1);
     }
     else Zeitraum.Value = "12:00 bis 23:59";
     rd.ParameterFields[0].CurrentValues.Add(Zeitraum);
     Datum.Value = date.Date.ToShortDateString();
     rd.ParameterFields[1].CurrentValues.Add(Datum);
     string dirpath = path + date.Year + "\\" + date.ToString("MMMM yyyy");
     string filepath = path + date.Year + "\\" + date.ToString("MMMM yyyy") + "\\" + _reports[index].Replace(".rpt", "") + "-" + Datum.Value.ToString() + "-" + Zeitraum.Value.ToString().Replace(":", "") + ".pdf";
    
     try
     {
     if (!Directory.Exists(dirpath)) Directory.CreateDirectory(dirpath);
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("Error: Erstelle Subordner:\r\n" + dirpath + "\r\n" + ex.Message);
     return false;
     }
     try
     {
     rd.ExportToDisk(ExportFormatType.PortableDocFormat, filepath);
     this.EventLog.WriteEntry("Export Erfolgreich:\r\n" + filepath);
     }
     catch (Exception ex)
     {
     this.EventLog.WriteEntry("Export Error: " + filepath + "\r\n" + ex.Message);
     return false;
     }
    
     rd.Dispose();
     GC.Collect();
    
     if (Zeitraum.Value.ToString() == "12:00 bis 23:59")
     {
     if (date.AddDays(1) < DateTime.Now.Date)
     {
      //this.EventLog.WriteEntry("Export Erfolgreich \r\n" + filepath);
      exportPDF(Zeitraum.Value.ToString().Replace(":", ""), date, path, index);
     }
     }
     else
     {
     //this.EventLog.WriteEntry("Export Erfolgreich \r\n" + filepath);
     exportPDF(Zeitraum.Value.ToString().Replace(":", ""), date, path, index);
     }
     //this.EventLog.WriteEntry("Export Erfolgreich \r\n" + filepath);
     return true;
     }
     }
    }
    
    


     




    Mittwoch, 17. August 2011 06:29

Antworten

Alle Antworten

  • niemand ne idee woran das liegen könnte?

     

    danke, mfg

    Donnerstag, 18. August 2011 06:13
  • Hi,

    "Fehler 5: Zugriff verweigert"

    sowohl als lokaler Admin, als auch als AD User als der der Dienst ausgeführt wird.

    Weis da vllt jemand Abhilfe? Wäre über jeden Rat/Hinweis dankbar ;)

    und wo tritt der Fehler auf? Ggfs. sollte man den Dienst mal als Debug kompilieren und dann ein paar mehr Fehlerdetails, insbesondere die Codestelle, an der der Fehler auftritt, posten.

    Denn so kann das alles mögliche sein.

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
    Donnerstag, 18. August 2011 07:01
    Moderator
  • Meine Ziel Maschine ist Win XP SP3. .NET 4.5 und Crystal Reports Runtime Engine sind installiert. Ich logge mich mit dem lokalen Admin ein, installiere den Dienst mit RunAsSvc und sage dem Dienst als welcher Benutzer er starten soll (wie oben, wegen AD). Leider bekomm ich dann beim starten des Dienstes einen

    "Fehler 5: Zugriff verweigert"

    sowohl als lokaler Admin, als auch als AD User als der der Dienst ausgeführt wird.

    Der Fehler tritt auf wenn ich den Dienst starten will als ein User des AD.

    Wenn ich den Dienst unter "Lokalem Systemkonto" laufen lasse startet er, aber bricht sofort wieder ab. Er hat da natürlich auch nicht die Rechte sich mit der DB zu verbinden.

    Sobald ich den Dienst eben als AD User laufen lasse, startet er eben gar nicht mehr, sondern gibt mir den genannten Fehler 5 aus.

     

    BTW, ich installiere den Dienst mit RunAsSvc (http://www.pirmasoft.de/runassvc.php), die Dienst *.exe ist die *.exe aus dem Debug Ordner. Der gesamte Ordner befindet sich aber lokal auf dem Zielsystem. Ist das vllt ein Problem?

    Wenn ich die *.exe aus dem Debug Ordner jedoch auf meinem Dev System installiere, funktioniert das ganze aber ohne Probleme.

     

    Danke für die Hilfe.

    mfg

    Donnerstag, 18. August 2011 07:32
  • Hallo,

    Crystal Reports ist zu großen Teilen unmanaged und greift auf eine Vielzahl von Komponenten zurück.
    Da gibt es viel Raum für fehlende Zugriffsrechte.

    Wenn die Ausnahmen nichts hergeben, kann der Process Monitor helfen.
    Dort sollte man fehlenden Zugriffsrechte erkennen können.

    Gruß Elmar

    Donnerstag, 18. August 2011 07:32
    Beantworter
  • Danke für die Antworten.

    Vorsichtshalber hab ich den Dienst laut MS http://support.microsoft.com/kb/137890 installiert und versucht zu starten als AD User. Siehe da, es klappte!

    Leider jedoch nicht wie gewollt. Ich bekam die Fehlermeldung im Log:

    Der Dienst kann nicht gestartet werden. Der Dienstprozess konnte keine Verbindung mit dem Dienstcontroller herstellen.

    Etwas googeln, und ich fand diesen Thread: (siehe letzter Post)

    http://www.vbarchiv.net/forum/read.php?id=22&t=23367&i=23367&v=f

    Der Timer war schuld?

    Habs probiert, dass ich den Timer zum Start rausnehme, und direkt startWork() ausführe, auch auf die Gefahr hin, dass mir der Dienst abschmiert und nicht startet. ABER: Es funktionierte!! Hatte den Timer zum Beginn nur eingebaut da mir unter Win 7 der Dienst nicht startete wenn ich direkt startWork() ausführe. Unter XP SP2 jedoch funktioniert es genau umgekehrt: Er startet und macht einfach die Arbeit NACH dem Start anstatt während des Starts.

    Danke für eure Hilfe, soweit funktioniert jetzt alles. Sollte sich noch was ergeben werd ich euch wieder nerven *gggg*

    mfg

    //edit: anscheinend bekomme ich die Fehlermedlung nachdem die "Arbeiit ausgeführt wurde" trotzdem. HMMMMMMM. Dazu iwer ne Idee warum?

    mfg

    Donnerstag, 18. August 2011 08:54
  • Hallo,

    entschuldige die späte Antwort, ich war die letzten Tage offline.

    Ich muss zugegeben, dass ich mich bei der ersten Antwort auf den Fehler 5 (Access denied) konzentriert hatte.

    Nach genauerer Durchsicht, solltest Du den Entwurf überarbeiten.
    Beachte, dass Dienste pausiert, gestoppt (beim Shutdown zwangsweise) und deaktiviert werden können -
    siehe Lebensdauer von Diensten in der Einführung in Windows-Dienstanwendungen

    Einen Timer im Konstruktur zu erzeugen und loslaufen zu lassen ist zu früh.
    Das sollte erst im OnStart passieren und es empfiehlt sich den Timer auf kürzere Intervalle einzustellen.
    Beim OnStop/Shutdown solltest Du den Dienst korrekt beenden, dass heisst hier auch das Exportieren stoppen.
    Anstatt des Timers.Timer wäre ein Threading.Timer angemessener, eine Interaktion mit einer Benutzeroberfläche
    fällt eh flach, siehe http://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer

    Zum Installieren solltest Du wie auch oben beschrieben einen Installer verwenden, siehe
    Gewusst wie: Hinzufügen von Installern zur Dienstanwendung
    Eine alternative Abwandlung beschreibt: Windows Services Can Install Themselves

    Gruß Elmar

     

     

    Dienstag, 23. August 2011 07:41
    Beantworter