myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Code-Reviews » [Review] Programm zum sicheren Starten und Loggen des Startvorgangs von Programmen
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

[Review] Programm zum sicheren Starten und Loggen des Startvorgangs von Programmen

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
R3turnz R3turnz ist männlich
myCSharp.de-Mitglied

Dabei seit: 03.01.2016
Beiträge: 125
Entwicklungsumgebung: Visual Studio 2015
Herkunft: Süddeutschland


R3turnz ist offline

[Review] Programm zum sicheren Starten und Loggen des Startvorgangs von Programmen

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,
erstmal möchte ich den Sinn meines Programmes erläutern:
Einfach gesagt: Es startet ein Program.
Jedoch werden Fehlermeldungen in eine log-Datei geschrieben und Einstellungen werden aus einer ini-Datei geladen. Außerdem bietet es eine Unterstüzung zum verbinden von Netzlaufwerken und ermöglicht so das zentralen Speichern der log-Datein.
Zugegeben, das Einsazgebiet ist sehr klein, und aktuell ist es sehr viel Code um nichts, wenn man aber z.B. das Starten eines Programmes zur bestimmten Uhrzeit per Gui geplant werden könnte etc. wäre es effektiver, ich werde es deswegen später auch wahrscheinlich weiter entwickeln. (Gerade fehlt mir vorallem das Wissen in WPF).
An einigen Stellen bin ich mir mit den Variablen-Namen nicht schlüssig geworden, habe aber versucht es so gut wie möglich hinzubekommen.

Program.cs:

C#-Code:
using System;
namespace Starter
{

    class Program
    {

        public static void Main()
        {
            Console.Title = "Starte...";
            string[] log = new string[2];
            ConfigLoader config = new ConfigLoader("config.ini");

                log[0] = config.Load() + "\n";
            if (config.LoadedStarter != null) log[1] = config.LoadedStarter.Start() + "\n";
                config.LoadedLogWriter.Write(log);
        }
    }
}

Config-Loader.cs:

C#-Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Reflection;
namespace Starter
{
    class ConfigLoader
    {
        public string ConfigPath { get; private set; }
        public ConfigLoader(string configpath)
        {
            ConfigPath = configpath;
            LoadedStarter = null;
            LoadedLogWriter = null;
        }
        public Starter LoadedStarter { get; private set; }
        public LogWriter LoadedLogWriter { get; private set; }
        private string programpath = null;
        string args = null;
        string[] splittedArgs = null;
        string logpath = null;
        string nas = null;
        string nasuser = null;
        string naspasswd = null;
        string naspath = null;
        public string Load()
        {

            if (File.Exists(ConfigPath))
            {
                IniFile config = new IniFile("config.ini");
                if (config.KeyExists("Programpfad", "Starter")) programpath = config.Read("Programpfad", "Starter").Trim();
                if (config.KeyExists("Aufzeichnungspfad", "Starter")) logpath = config.Read("Aufzeichnungspfad", "Starter").Trim();
                if (config.KeyExists("Argumente", "Starter")) args = config.Read("Argumente","Starter");
                if (config.KeyExists("Netzwerkpfad", "NAS") && config.KeyExists("Aufzeichnungspfad","NAS"))
                {
                    nas = config.Read("Netzwerkpfad", "NAS").Trim();
                    naspath = config.Read("Aufzeichnungspfad","NAS").Trim();
                    if (config.KeyExists("Benutzer") && config.KeyExists("Nas-Passwort") && logpath == null)
                    {
                        nasuser = config.Read("Benutzer", "NAS").Trim();
                        naspasswd = config.Read("Passwort", "NAS").Trim();
                    }
                }
            }
            return Create();
        }
        private string Create()
        {
            StringBuilder parambuilder = new StringBuilder("Folgende Paramter wurden geladen:\n");
            if (!string.IsNullOrEmpty(logpath))
            {
                LoadedLogWriter = new LogWriter(logpath);
                parambuilder.AppendFormat("Der Pfad für die Aufzeichnung wurde auf:{0} gesetzt.",logpath);
            }
             else
            {
                LoadedLogWriter = new LogWriter();
                parambuilder.AppendFormat("Es konnte kein Pfad für die Aufzeichnung gefunden werden! Standartwert:{0}.",LoadedLogWriter.DefaultDestination);
            }
            parambuilder.AppendLine();
            if(!string.IsNullOrEmpty(programpath) && splittedArgs != null && splittedArgs.Length > 0)
            {
                SplitArgs(args,new char[] { ',' });
                parambuilder.AppendFormat("Der Programpfad wurde auf:{0} gesetzt. Außerdem wurden folgender Argumente erkannt:{1}.",LoadedStarter.ExecutionPath,args);
            }
            else if(!string.IsNullOrEmpty(programpath))
            {
                LoadedStarter = new Starter(programpath);
                parambuilder.AppendFormat("Der Programpfad wurde auf:{0} gesetzt.",LoadedStarter.ExecutionPath);
            }
            else
            {
                parambuilder.AppendFormat("Es konnte kein Pfad zum Ausführen gefunden werden!");
            }
            if(!string.IsNullOrEmpty(nas) && !string.IsNullOrEmpty(naspath))
            {
                parambuilder.AppendLine();
                parambuilder.Append("NAS-Konfiguration:");
                if (!string.IsNullOrEmpty(nasuser) && !string.IsNullOrEmpty(naspasswd))
                {
                   parambuilder.Append(LoadedLogWriter.Connect(nas,naspath,nasuser,naspasswd));
                }
                else
                {
                    parambuilder.Append(LoadedLogWriter.Connect(nas,naspath));
                }
            }

            return parambuilder.ToString();
        }

        private void SplitArgs(string args,char[] pattern)
        {
            splittedArgs = args.Trim().Split(pattern);
        }
    }

}

LogWriter.cs:

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Windows;
using System.Security;
using System.Text;

namespace Starter
{
    class LogWriter
    {
        public string Destination { get; set; }
        public string DefaultDestination
        {
            get
            {
                string appDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Starter");
                return Path.Combine(appDir, "log.txt");
            }
        }
        public LogWriter(string destination = null)
        {
            Destination = destination ?? DefaultDestination;
        }

        public void Write(string[] value)
        {
            string appDir = Path.GetDirectoryName(Destination);
            if (!Directory.Exists(appDir)) Directory.CreateDirectory(appDir);
            try
            {
                using (var fs = new FileStream(Destination, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    fs.Seek(0,SeekOrigin.End);
                    using (var sw = new StreamWriter(fs,Encoding.UTF8))
                    {
                        sw.WriteLine("Starter v0.1 "+Environment.MachineName + " (" + DateTime.Now.ToString() + ")");
                        foreach(var towrite in value)
                        {
                            if(towrite != null)
                            sw.WriteLine(towrite);
                        }

                    }
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(string.Format("Es ist ein Fehler wärend des Log-Schreibens nach:{0} aufgetreten:{1}",Destination,ex.Message),"CCleaner-Starter-Fehler",MessageBoxButton.OK,MessageBoxImage.Error);
            }

        }
        public string Connect(string root,string path, string user = null, string password = null)
        {
            var name = getNextDriveName();
            if (name == ' ') return "Kein weiteren Laufwerk-Bezeichner gefunden!";
            try
            {
                using (var powershell = PowerShell.Create())
                {
                    powershell.AddCommand("New-PSDrive");
                    powershell.AddParameter("Name", name);
                    powershell.AddParameter("PSProvider", "FileSystem");
                    powershell.AddParameter("Root", root);
                    if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password))
                    {
                        var secure = new SecureString();
                        foreach (char c in password)
                        {
                            secure.AppendChar(c);

                        }
                        PSCredential credential = new PSCredential(user, secure);
                        powershell.AddParameter("Credential",credential);
                    }
                    Collection<PSObject> powershellobjects =  powershell.Invoke();
                    if(powershell.HadErrors)
                    {
                        StringBuilder errorbuilder = new StringBuilder("Während des Verbindens mit dem Netzlaufwerk ist ein/mehrere Fehler aufgetreten:");
                        for(int i = 0; i < powershell.Streams.Error.Count; i++)
                        {
                            if (i < powershell.Streams.Error.Count - 1)
                            {
                                errorbuilder.Append(powershell.Streams.Error[i].ToString() + ",");
                            }
                         else
                            {
                                errorbuilder.Append(powershell.Streams.Error[i].ToString());
                            }
                        }
                        return errorbuilder.ToString();
                    }
                    else if(powershellobjects.Any())
                    {
                        PSDriveInfo psinfo = (PSDriveInfo)powershellobjects[0].BaseObject;
                        Destination = Path.Combine(psinfo.Root,path);
                       return string.Format("Netzlaufwerk erfolgreich geladen, log wird nun nach: {0} geschrieben!", Destination);
                    }
                    else
                    {
                      return "Ein unbekannter Fehler ist aufgetreten!";
                    }

                }
            }
            catch(Exception ex)
            {
                return "Während des Verbindens mit dem Netzlaufwerk ist ein Fehler aufgetreten:"+ex.Message;
            }


        }



        private char getNextDriveName()
        {
            List<char> alphabet = new List<char>(26);
            for (char c = 'A'; c < 'Z'; c++)
            {
                alphabet.Add(c);
            }
            DriveInfo[] drives = DriveInfo.GetDrives();
            foreach(var drive in drives)
            {
                alphabet.Remove(char.Parse(drive.Name.Substring(0,1)) );
            }

            return alphabet.Any() ? alphabet[0] : ' ';

        }
    }
}

Starter.cs:

C#-Code:
using System.IO;
using System.Diagnostics;
using System;
using System.Text;

namespace Starter
{
    class Starter
    {
        public string ExecutionPath { get; private set; }
        public string Arguments { get; set; }
        public string Start()
        {
            Process ccleaner = new Process();
            ccleaner.StartInfo.FileName = ExecutionPath;

            if(!string.IsNullOrEmpty(Arguments))  ccleaner.StartInfo.Arguments = Arguments;
                ccleaner.StartInfo.CreateNoWindow = true;

            try
            {
                ccleaner.Start();
            }
            catch (Exception ex)
            {
                return string.Format("Es ist ein Fehler während des Startens von: {0} aufgetreten:{1}.", ExecutionPath, ex.Message);
            }
            return string.Format("Erfolgreich:{0} gestartet!",ExecutionPath);
        }
        public Starter(string executionpath,string args = null)
        {
            ExecutionPath = executionpath;
            Arguments = args;
        }
    }

}

Die InI-File Klasse kommt von:  http://stackoverflow.com/questions/21790...ing-an-ini-file


LG

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von R3turnz am 06.03.2016 09:49.

05.03.2016 20:40 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.575
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Von Ini Dateien solltest - wenn irgendwie möglich - Du allgemein die Finger weglassen, denn das ist wirklich aus der Mottenkiste.
Verwende XML oder Json. Lassen sich viel einfacher und sicherer lesen.

Ansonsten bin ich ein Freund von Code Dokumentation.
Muss nicht wirklich jede Zeile sein, aber der Leser sollte wissen, was an der Stelle passiert (und manchmal auch wieso).
06.03.2016 11:31 Beiträge des Benutzers | zu Buddylist hinzufügen
Papst Papst ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.09.2014
Beiträge: 253
Entwicklungsumgebung: VS2017
Herkunft: Kassel


Papst ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich habe jetzt nicht alles durchgelesen, aber du übergibst der Klase ConfigLoader im Konstruktor die zu ladende Datei, lädst dann aber in ConfigLoader.Load() die "config.ini" egal, was vorher übergeben wurde.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Papst am 06.03.2016 16:07.

06.03.2016 16:05 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
MarsStein MarsStein ist männlich
myCSharp.de-Poweruser/ Experte

avatar-3191.gif


Dabei seit: 27.06.2006
Beiträge: 3.140
Entwicklungsumgebung: VS 2013, MonoDevelop
Herkunft: Trier -> München


MarsStein ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

was mir daran gar nicht gefällt, ist, dass überall in den Methoden die Status/Logmedungen als Strings zurückgegeben werden.

Das mag in diesem speziellen Fall ja OK sein und das tun was Du willst.
Als Konzept finde ich es aber grauselig, und sollte man sich nicht angewöhnen/abschauen.

Gruß, MarsStein
07.03.2016 13:38 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
R3turnz R3turnz ist männlich
myCSharp.de-Mitglied

Dabei seit: 03.01.2016
Beiträge: 125
Entwicklungsumgebung: Visual Studio 2015
Herkunft: Süddeutschland

Themenstarter Thema begonnen von R3turnz

R3turnz ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,
@Abt InI-Datein haben für mich den Vorteil, jeder könnte sie selber editieren (Brauche nicht wie z.B. bei XML ein Tool dafür zu entwerfen), und sie haben mir nihctmal 10 Minuten Einarbeitung gekostet smile .
Aber keine Angst, mein aktueller "Schlachtplan" sieht so aus: LinQ, XML, WPF geschockt . Bis ich da durchbin wird es zwar noch dauern, aber werde es schon packen.
@Papst Danke, ist behoben Augenzwinkern
@MarsStein Okay, nur bringt es mir leider wenig ohne Verbesserungsvorschlag. verwundert

Nochmal danke an alle, fürs durchsehen.

LG
08.03.2016 14:42 Beiträge des Benutzers | zu Buddylist hinzufügen
Coffeebean Coffeebean ist männlich
myCSharp.de-Team

avatar-3295.gif


Dabei seit: 25.08.2011
Beiträge: 2.196
Entwicklungsumgebung: VS 2005-2017, VS Code
Herkunft: Deutschland/Schweiz


Coffeebean ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo R3turnz,

Zitat von R3turnz:
@Abt InI-Datein haben für mich den Vorteil, jeder könnte sie selber editieren (Brauche nicht wie z.B. bei XML ein Tool dafür zu entwerfen), und sie haben mir nihctmal 10 Minuten Einarbeitung gekostet :)

XML und JSON lassen sich ebenfalls in jedem Texteditor editieren.

Gruss

Coffeebean
08.03.2016 14:54 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.575
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ini-Dateien haben über XML eigentlich genau: keinen Vorteil.
Auch XML Dateien basieren auf einfachem Text - da braucht man kein Tool dazu.

XML und Json unterstützen im Gegensatz zu Ini aber weit mehr als nur Key-Value.
Und sind dabei auch noch viel sicherer und einfacher zu lesen.
08.03.2016 14:55 Beiträge des Benutzers | zu Buddylist hinzufügen
R3turnz R3turnz ist männlich
myCSharp.de-Mitglied

Dabei seit: 03.01.2016
Beiträge: 125
Entwicklungsumgebung: Visual Studio 2015
Herkunft: Süddeutschland

Themenstarter Thema begonnen von R3turnz

R3turnz ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,
ich wollte ini-File's nicht gut reden. Mir sind die stärken von XMl/Json durchaus bewusst ;)
Ich weiß auch das man sie normal in einem Editor öffnen kann, ein XML File, ist jedoch meiner Meinung nach ein wenig komplexer als ein ini-File.
Wenn ich jedoch darüber nachdenke wäre es aber auch gar nicht so schlimm.
Ich muss mier jedoch XML jedoch nochmal anschauen, blicke vorallem in XSD noch gar nicht durch.

LG
08.03.2016 17:24 Beiträge des Benutzers | zu Buddylist hinzufügen
Coder007
myCSharp.de-Mitglied

Dabei seit: 05.08.2006
Beiträge: 1.207


Coder007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich will diese Diskussion eigentlich nicht vertiefen. Ich bevorzuge auch XML oder Json, wo das möglich ist. Aber ich auch erwähnen, dass die meisten unserer Kunden und Consultants im Maschinenbaubereich ini Dateien absolut den Vorrang geben. Kaum führen wir mal irgendwo eine Config im XML Format ein, mit der auch "Benutzer" direkt in Berührung kommen, dann kommen garantiert zig Anfragen rein, bitte auf ini umstellen.
08.03.2016 20:44 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.575
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich komm ursprüngliche aus der Maschinenbaubranche und neue Systeme verwenden durchaus XML - selbst als Market Leader.
Bei Legacy-Systemen ist das durchaus so, was historisch aufgrund der Abwärtskompatibilität bedingt ist. Nicht unüblich bei einem Fertigungslaser, der 20 Jahre Laufzeit hat.
Nur pauschal zu sagen die Maschinenbauer verwenden ini ist inkorrekt.
08.03.2016 21:44 Beiträge des Benutzers | zu Buddylist hinzufügen
Coder007
myCSharp.de-Mitglied

Dabei seit: 05.08.2006
Beiträge: 1.207


Coder007 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nein, ich wollte das natürlich nicht pauschalisieren. Ich habe auch nicht Maschinenbauer allgemein gemeint, und auch nicht die Software, die sie möglicherweise benutzen, sondern ganz konkret auf unsere Software bezogen. Aber da das eine Branchenlösung für Maschinenbauer ist, wollte ich das eben eingrenzen. Unsere Software ist auch schon seit über 20 Jahren auf dem Markt und natürlich dementsprechend sehr stark historisch gewachsen. Die Konfiguration ist auch teilweise sehr umfangreich und komplex, und wenn sich Kunden und Consultants da schon auskennen, wollen sie weder neue noch gemischte Konfigurationsformate.
09.03.2016 20:17 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Jahre.
Der letzte Beitrag ist älter als 4 Jahre.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 01.04.2020 03:48