mesaou
Goto Top

VBSkript mit Hilfe eines Dienstes starten (geschrieben in C-Sharp)

Hi,

Folgende Situation
Ich habe ein VBSkript, das über einen Dienst gestartet werden soll. Soblad der Dienst gestoppt wird, wird auch das Skript wieder angehalten. Die Endbedingung für das Skript zu generieren funktioniert genauso wie das Zurücksetzen selbiger (ist über einen Eintrag in einer SQL-Tabelle gelöst). Die Zugangsdaten für die SQL-Verbindung sind korrekt angelegt. Die Library Class ist nur zum beschreiben einer Logdatei erstellt und funktioniert auch nach Start des Dienstes (sprich die Logdatei wird erstellt und befüllt).

Das Problem liegt nun darin, dass ich das VBSkript nicht aus dem Dienst heraus gestartet kriege. In Zeile 51 soll das Skript gestartet werden, der Dateipfad stimmt. Wenn ich das Skript manuell starte funktioniert es, genauso wenn ich es über ein kleines VB-Programm mit der selben Mechanik wie hier im Dienst probiere. Ich vermute das mein Aufruf aus C# fehlerhaft ist habe aber im Netz noch nichts gefunden, wie ich den Aufruf berichtigen kann.

Grüße,
Mesaou

Hier noch der Code:

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.Threading.Tasks;
using System.Timers;
using System.Data.SqlClient;

namespace ServiceName
{
    public partial class Service1 : ServiceBase
    {
        private Timer timer1 = null;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string args)
        {
            timer1 = new Timer();
            this.timer1.Interval = 30000;
            this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Tick);
            timer1.Enabled = true;
            
            string connetionString = null;
            SqlConnection cnn;
            SqlDataReader reader;
            connetionString = "Data Source=****;Initial Catalog=****;User ID=****;Password=****";  
            cnn = new SqlConnection(connetionString);
            try
            {
                cnn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = "Update omopt Set DienstAktiv=1 where ID=1";  
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cnn;

                reader = cmd.ExecuteReader();
                cnn.Close();
            }
            catch (Exception ex)
            {
                Library.WriteErrorLog(DateTime.Now.ToString() + ": SQLFEHLER " + ex.Source.ToString().Trim() + ": " + ex.Message.ToString().Trim());  
            }
            Process.Start("C:\\Winchenbach\\KundenAktualisieren.vbs");  
            Library.WriteErrorLog("ServiceName started");  
        }

        private void timer1_Tick(object sender, ElapsedEventArgs e)
        {
            Library.WriteErrorLog("Tick and Job done");  
        }

        protected override void OnStop()
        {
            timer1.Enabled = false;
            string connetionString = null;
            SqlConnection cnn;
            SqlDataReader reader;
            connetionString = "Data Source=****;Initial Catalog=****;User ID=****;Password=****";  
            cnn = new SqlConnection(connetionString);
            try
            {
                cnn.Open();
                SqlCommand cmd = new SqlCommand();
                cmd.CommandText = "Update omopt Set DienstAktiv=0 where ID=1";  
                cmd.CommandType = CommandType.Text;
                cmd.Connection = cnn;

                reader = cmd.ExecuteReader();
                cnn.Close();
            }
            catch (Exception ex)
            {
                Library.WriteErrorLog(DateTime.Now.ToString() + ": SQLFEHLER " + ex.Source.ToString().Trim() + ": " + ex.Message.ToString().Trim());  
            }
            Library.WriteErrorLog("ServiceName stopped");  
        }
    }
}

Content-ID: 249336

Url: https://administrator.de/contentid/249336

Ausgedruckt am: 24.11.2024 um 08:11 Uhr

colinardo
Lösung colinardo 16.09.2014, aktualisiert am 30.09.2014 um 10:37:52 Uhr
Goto Top
Hallo Mesaou,
was macht das VB-Script bzw. was nutzt es für Funktionen? Du solltest wissen das das Script natürlich im Userkontext des Dienstes läuft und es keinen Zugriff auf die UI hat, d.h. jeglicher Versuch etwas anzuzeigen, und sei es nur eine MsgBox, werden fehlschlagen, wenn man den Dienst nicht als Interaktiven Dienst konfiguriert, der mit dem Desktop interagieren kann.
Mehr zum Security-Modell von Diensten kannst du hier nachlesen:
http://stackoverflow.com/questions/4516200/how-can-a-windows-service-st ...

Zum starten von VBS-Scripten würde ich zudem cscript.exe benutzen und den Pfad zum Script als Argument übergeben.
Process pr = new Process();
pr.StartInfo.FileName = "cscript.exe";  
pr.StartInfo.Arguments = @"c:\pfad\script.vbs";  
pr.Start();
Grüße Uwe
Mesaou
Mesaou 17.09.2014 um 10:33:39 Uhr
Goto Top
Das Skript wird jetzt gestartet, danke schonmal.

Das Skript baut mehrere Datenbankverbindunge auf und prüft in regelmäßigen Abständen ob die Endbedingung eingetreten ist (bestimmter Wert in der Datenbank gesetzt). Sofern der Wert nicht gesetzt ist, werden alle Änderungen die in der dafür erstellten Tabelle eingetragen wurden im Elo durchgeführt.
Genutzt werden

- db.Execute zum Ausführen der SQL-Befehle
- drei selbst geschriebene Subs, die
- einen vorhandenen Eintrag im Elo ändern ("Alter")
- einen neuen Eintrag im Elo anlegen ("Add")
- im Elo einen Ordner anlegt und dessen Werte setzt (wird in den beiden anderen Subs benutuzt)
- verscheinden Elo-Befehle zum Bearbeiten des angelegten Ordners (Das Elo-Objekt ist erstellt und ELo ist gestartet)
(Elo.GetEntryId, Elo.SetObjAttrib, Elo.ObjShort, Elo.PrepareObjEx, Elo.ObjFlags, Elo.ObjIndex, Elo.ObjMemo, Elo.UpdateObject, Elo.Sleep, Elo.Status,
Elo.DoInvisibleSearch, Elo.InsertRef, Elo.LookUpIndex)

Es hat den Anschein als läge das Problem in den Subs "Add" und "Alter", da die Datenbankaktionen korrekt durchgeführt werden (Anpassung an Kunden und KundenOpt sowie das Löschen in der DatenbankuebergriffTest). Ich habe bereits versucht die Wartezeit zu erhöhen, leider ohne Erfolg.

MAIN
Set rs2 = db2.Execute ("Select * from DatenbankuebergriffTest")  

	Do Until rs2.EOF
		ID = rs2(0)
		KundNr = rs2(1)
		KundName = rs2(2)
		KundPLZ = rs2(3)
		KundOrt = rs2(4)
		KundEMail = rs2(5)
		Change=rs2(6)

		if Change = 2 then
			db1.Execute ("Insert Kunden (*Spaltennamen*) Values (*Werte für Spalten*)")  
			db1.Execute ("Insert KundenOpt (*Spaltennamen*) Values (*Werte für Spalten*)")  
			Add 1, KundNr, KundName
		elseif Change = 1 then
			db1.Execute ("Update Kunden Set Spaltename = 'Wert', ...")  
			db1.Execute ("Update KundenOpt Set Spaltename = 'Wert', ...")  
			Alter 1, KundNr, KundName
		end if
		db3.Execute ("Delete from DatenbankuebergriffTest Where TbID = "  & ID )  
		rs2.movenext
	Loop
colinardo
colinardo 17.09.2014 aktualisiert um 10:44:19 Uhr
Goto Top
Frage: Warum setzt du das VB-Script nicht direkt im Dienst mit C# um ?
Mesaou
Mesaou 17.09.2014 aktualisiert um 13:42:06 Uhr
Goto Top
Ich dachte, dass es einfacher "zu Steuern" sei wenn ich das Script über den Dienst starte, dann in Dauerschleife laufen lasse und bei Beenden des Diesntes wieder beende. Ist allerdings möglicherweise sinnvoller den Code in den Dienst direkt zu übernehmen ... muss mich dann mal etwas mit den Besonderheiten in der Syntax von C# auseinandersetzen.

Edit:
hmm ... Elo lässt sich aus C# nicht direkt ansprechen ... dann muss ich wohl doch beim Skript bleiben.

Edit2:
Was mich wundert ist, dass das Skript die Sub "main" bearbeitet, die darin benutzen Subs ("Add" und "Alter") allerdings nicht. Die danach ausgeführte SQL-Anweisung (Löschen der Änderungseinträge) wird wiederum ausgeführt.

Edit3:
Dieses Verhalten tritt nur auf, wenn das Skript durch den Dienst gestartet wird ...bei manuellem Start funktioniert es einwandfrei. Der Dienst setht standardmäßig auf "Local System" ich habs mal auf Administrator geändert. Leider hat das nichts geändert.
colinardo
colinardo 17.09.2014 aktualisiert um 14:17:13 Uhr
Goto Top
Edit: hmm ... Elo lässt sich aus C# nicht direkt ansprechen ... dann muss ich wohl doch beim Skript bleiben.
Was du mit VBS machst kannst lässt sich auch mit C# umsetzen 100%

Edit2:
Edit3
ohne Code ist das hier schwierig zu beurteilen.

lass dir doch mal aus der VBS Logs in eine Datei schreiben dann weißt du an welcher Stelle das Script genau abbricht.
Mesaou
Mesaou 23.09.2014 um 14:49:41 Uhr
Goto Top
Danke für die Idee. Ich werde es vorläufig über ein kleines Programm lösen, das über ne Aufgabe beim Anmelden vom Administrator, gestartet wird und dann mein Skript in Dauerschleife laufen lässt.