Compare commits

..

No commits in common. "master" and "v1.0.2.6" have entirely different histories.

29 changed files with 934 additions and 1961 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
/.vs
/Utils/obj
/Utils/bin

View File

@ -1,92 +0,0 @@
# Contributing
When contributing to this repository, please first discuss the change you wish to make via issue,
email, or any other method with the owners of this repository before making a change.
Please note we have a code of conduct, please follow it in all your interactions with the project.
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
2. Update the README.md with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
3. Increase the version numbers in any examples files and the README.md to the new version that this
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
do not have permission to do that, you may request the second reviewer to merge it for you.
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at git ATTTT blubbfish.net. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,188 +0,0 @@
# Changelog
## 1.6.2 - 2022-01-30 - ProgrammLogger improved
### New Features
* ProgrammLogger can now have a path while init, so not need to move the file
* Make it possible that two instances can use the same logfile
* IniReader GetValue can now have a default that returns if no setting is found
### Bugfixes
### Changes
* Codingstyles
## 1.6.1 - 2022-01-20 - ProgrammLogger Fixed
### New Features
### Bugfixes
* Unhandled exception. System.IO.IOException: The file '/var/log/zwaybot/debug.log' already exists.
### Changes
## 1.6.0 - 2022-01-09 - HttpEndpoint added
### New Features
* Add HttpEndpoint
### Bugfixes
### Changes
* Change Readme that its link to the normal repo
* Codingstyles
* Fixing history
## 1.5.0 - 2021-04-10 - Add GetEvent so you can call events by string; Add OwnSingeton class
### New Features
* More allowed Chars for Chapters in inifile
* Add Contribution, Licence and readme
* Adding netcore
* Add changelog
* Filedhelper to helpter
* CmdArgs improvements
* Make netcore to default
* Add OwnSingleton
### Bugfixes
* WriteLine in Programmlogger sometimes make nonesense
* Writeline event are wrong
### Changes
* Remove the binary files
* Move all Classes to subfolder
* Codingstyles
## 1.4.0 - 2018-11-27 - Add Helper to Utils
### New Features
* Add Helper
### Bugfixes
### Changes
## 1.1.3 - 2018-10-02 - Improve CmdArgs
### New Features
* CmdArgs now throw extensions if there is something wrong
### Bugfixes
### Changes
## 1.1.2 - 2018-09-11 - Tiny Codingstyles
### New Features
### Bugfixes
### Changes
* Codingstyles
## 1.1.1 - 2018-05-29 - ProgrammLogger neets to cleanup
### New Features
* Delete the Mess behind
### Bugfixes
### Changes
## 1.1.0 - 2018-05-15 - ProgrammLogger
### New Features
* Add Programmlogger
### Bugfixes
### Changes
* Codingstyles
## 1.0.7.0 - 2018-05-08 - Yet another IniReader improvemnt round again
### New Features
### Bugfixes
### Changes
* Move searchpath to its own function
## 1.0.6.0 - 2017-12-22 - Yet another IniReader improvemnt round
### New Features
* Posibillity to add complete sections to an ini file
### Bugfixes
### Changes
## 1.0.5.2 - 2017-09-26 - And Improve IniReader again
### New Features
* IniReader returns the Sections with or without Brackets now
### Bugfixes
### Changes
## 1.0.5.1 - 2017-09-24 - Improve IniReader again
### New Features
### Bugfixes
* IniReader now supports umlaute
* IniReader matches with Brackets and without
### Changes
## 1.0.5.0 - 2017-08-09 - Improve IniReader
### New Features
* IniReader can now return a whole segemt
### Bugfixes
### Changes
## 1.0.4.1 - 2017-08-08 - Cleanup OwnView
### New Features
### Bugfixes
### Changes
* remove Init from OwnView
## 1.0.4.0 - 2017-04-30 - More Updater
### New Features
* continue Development of Updater
### Bugfixes
### Changes
## 1.0.3.2 - 2017-04-26 - Next Updater
### New Features
* continue Development of Updater
### Bugfixes
### Changes
## 1.0.3.1 - 2017-04-25 - EventArgsHelper
### New Features
* Add EventArgsHelper
### Bugfixes
### Changes
* Codingstyles
* Moves LogEventArgs to EventArgsHelper
* Moves UpdaterEventArgs to EventArgsHelper
## 1.0.2.6 - 2017-04-24 - Better Updater
### New Features
* Add Updater
* Add Disposable Interface
* Using LogEventArgs now for Logging
* Make UpdaterEventArgs as Child of EventArgs
* Updater now using Ownobject as Parent
* Add VersionsInfo to Updater
* Updater spawns a Background Task to Check for Updates
### Bugfixes
### Changes
## 1.0.2.5 - 2017-04-19 - Logging in OwnObject
### New Features
* Add Logging to OwnObject
### Bugfixes
* Avoid nullpointer exception in FileMutex
### Changes
* Codingstyles
## 1.0.2.3 - 2017-04-16 - OwnModel better
### New Features
* Add Remove observer on OwnModel
### Bugfixes
### Changes
* Codingstyles
## 1.0.2.2 - 2017-03-09 - Make it nice
### New Features
### Bugfixes
### Changes
* Codingstyles
## 1.0.2.1 - 2017-03-09 - Filemutex
### New Features
* Add Filemutex
### Bugfixes
* Filelogger backet on wrong pos
### Changes
## 1.0.0.1 - 2016-12-03 - Filelogger improvements
### New Features
* Check Directory and if not exist add it
* Now logs with timestamp
* Can select logdir
* Add Abstract dispose to OwnController
### Bugfixes
### Changes
## 1.0.0.0 - 2015-11-16 - Init
### New Features
* Add CmdArgs, FileLogger, IniReader, OwnController, OwnModel, OwnObject, OwnView,
### Bugfixes
### Changes

View File

@ -1,199 +1,185 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace BlubbFish.Utils
{
public class CmdArgs
{
public enum ArgLength
{
Single,
Touple
}
#region Classes
public struct VaildArguments
{
public VaildArguments(ArgLength length, Boolean required, String @default = "", String description = "")
{
this.Required = required;
this.Length = length;
this.Description = description;
this.@Default = @default;
}
public VaildArguments(ArgLength length, String @default = "", String description = "")
{
this.Required = false;
this.Length = length;
this.Description = description;
this.@Default = @default;
}
public ArgLength Length { get; private set; }
public Boolean Required { get; private set; }
public String Description { get; private set; }
public String Default { get; private set; }
}
private struct ArgTouple
{
public ArgTouple(String type, String data)
{
this.Type = type;
this.Data = data;
}
public ArgTouple(String type)
{
this.Type = type;
this.Data = null;
}
public String Type { get; private set; }
public String Data { get; private set; }
internal void SetData(String data)
{
if (data != "") {
this.Data = data;
}
}
}
#endregion
private String[] args;
private List<ArgTouple> argList;
private Dictionary<String, VaildArguments> argsPosible = new Dictionary<String, VaildArguments>();
private static CmdArgs instances = null;
private Boolean isSetArguments = false;
private CmdArgs()
{
}
/// <summary>
/// Gibt eine Instanz der Klasse zurück
/// </summary>
/// <returns>Klasse</returns>
public static CmdArgs Instance
{
get {
if (instances == null) {
instances = new CmdArgs();
}
return instances;
}
}
/// <summary>
/// Übernimmt die Argumente für die Klasse
/// </summary>
/// <param name="arguments">Mögliche Komandozeilenargumente</param>
/// <param name="args">Tatsächliche Komandozeilenargumente</param>
public void SetArguments(Dictionary<String, VaildArguments> arguments, String[] args)
{
this.args = args;
if (!this.isSetArguments) {
this.isSetArguments = true;
this.argsPosible = arguments;
this.Init();
}
}
private void Init()
{
this.argList = new List<ArgTouple>();
for (Int32 i = 0; i < this.args.Length; i++) {
if (this.argsPosible.Keys.Contains(this.args[i])) {
ArgTouple arg = new ArgTouple(this.args[i]);
if (this.argsPosible[this.args[i]].Length == ArgLength.Touple) {
if (this.args.Length > i + 1) {
arg.SetData(this.args[++i]);
} else {
Console.WriteLine(this.GetUsageList(""));
throw new ArgumentException("Argument: "+this.args[i]+" missing second argument.");
}
}
this.argList.Add(arg);
}
}
foreach(KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if(!this.HasArgumentType(item.Key) && item.Value.Length == ArgLength.Touple && item.Value.Default != "") {
this.argList.Add(new ArgTouple(item.Key, item.Value.Default));
using System;
using System.Collections.Generic;
using System.Linq;
namespace BlubbFish.Utils
{
public class CmdArgs
{
public enum ArgLength
{
Single,
Touple
}
#region Classes
public class VaildArguments
{
public VaildArguments(ArgLength length, Boolean required)
{
this.Required = required;
this.Length = length;
}
public VaildArguments(ArgLength length)
{
this.Required = false;
this.Length = length;
}
public ArgLength Length { get; private set; }
public Boolean Required { get; private set; }
}
private class ArgTouple
{
public ArgTouple(String type, String data)
{
this.Type = type;
this.Data = data;
}
public ArgTouple(String type)
{
this.Type = type;
}
public String Type { get; private set; }
public String Data { get; private set; }
internal void SetData(String data)
{
if (data != "") {
this.Data = data;
}
}
}
/// <summary>
/// Menge der angegebenen Komandozeilen-Argumente
/// </summary>
/// <returns>Menge</returns>
public Int32 GetArgsLength() => this.argList.Count;
/// <summary>
/// Gibt zurück ob ein Argument angegeben wurde
/// </summary>
/// <param name="name">Name des Arguments</param>
/// <returns>true wenn angegeben</returns>
public Boolean HasArgumentType(String name)
{
foreach (ArgTouple t in this.argList) {
if (t.Type == name) {
return true;
}
}
return false;
}
/// <summary>
/// Gibt den Inhalt des angegeben Arguments zurück, nur bei zweiteiligen Argumenten möglich
/// </summary>
/// <param name="name">Name des Arguments</param>
/// <returns>Inhalt des Arguments oder ArgumentNullException</returns>
public String GetArgumentData(String name)
{
foreach (ArgTouple t in this.argList) {
if (t.Type == name && t.Data != null) {
return t.Data;
}
}
throw new ArgumentNullException();
}
public Boolean HasAllRequiredArguments()
{
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (item.Value.Required && !this.HasArgumentType(item.Key)) {
return false;
}
}
return true;
}
public String GetUsageList(String name)
{
String ret = "Usage: " + name + " Parameter\nParameter:\n";
String req = "";
String opt = "";
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (item.Value.Required) {
req += item.Key + " " + ((item.Value.Length == ArgLength.Touple) ? (item.Value.Default != "" ? " " + item.Value.Default + "\n" : " [data]\n") : "\n");
if(item.Value.Description != "") {
req += "\t" + item.Value.Description + "\n";
}
}
}
if (req != "") {
ret += "Benötigte Parameter:\n" + req;
}
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (!item.Value.Required) {
opt += item.Key + " " + ((item.Value.Length == ArgLength.Touple) ? (item.Value.Default != "" ? " " + item.Value.Default + "\n" : " [data]\n") : "\n");
if (item.Value.Description != "") {
opt += "\t" + item.Value.Description + "\n";
}
}
}
if (opt != "") {
ret += "Optionale Parameter:\n" + opt;
}
return ret;
}
}
}
}
}
#endregion
private String[] args;
private List<ArgTouple> argList;
private Dictionary<String, VaildArguments> argsPosible = new Dictionary<String, VaildArguments>();
private static CmdArgs instances = null;
private Boolean isSetArguments = false;
private CmdArgs()
{
}
/// <summary>
/// Gibt eine Instanz der Klasse zurück
/// </summary>
/// <returns>Klasse</returns>
public static CmdArgs Instance
{
get {
if (instances == null) {
instances = new CmdArgs();
}
return instances;
}
}
/// <summary>
/// Übernimmt die Argumente für die Klasse
/// </summary>
/// <param name="arguments">Mögliche Komandozeilenargumente</param>
/// <param name="args">Tatsächliche Komandozeilenargumente</param>
public void SetArguments(Dictionary<String, VaildArguments> arguments, String[] args)
{
this.args = args;
if (!this.isSetArguments) {
this.isSetArguments = true;
this.argsPosible = arguments;
this.Init();
}
}
private void Init()
{
this.argList = new List<ArgTouple>();
for (Int32 i = 0; i < this.args.Length; i++) {
if (this.argsPosible.Keys.Contains(this.args[i])) {
ArgTouple arg = new ArgTouple(this.args[i]);
if (this.argsPosible[this.args[i]].Length == ArgLength.Touple) {
if (this.args.Length > i + 1) {
arg.SetData(this.args[++i]);
} else {
throw new ArgumentException();
}
}
this.argList.Add(arg);
}
}
}
/// <summary>
/// Menge der angegebenen Komandozeilen-Argumente
/// </summary>
/// <returns>Menge</returns>
public Int32 GetArgsLength()
{
return this.argList.Count;
}
/// <summary>
/// Gibt zurück ob ein Argument angegeben wurde
/// </summary>
/// <param name="name">Name des Arguments</param>
/// <returns>true wenn angegeben</returns>
public Boolean HasArgumentType(String name)
{
foreach (ArgTouple t in this.argList) {
if (t.Type == name) {
return true;
}
}
return false;
}
/// <summary>
/// Gibt den Inhalt des angegeben Arguments zurück, nur bei zweiteiligen Argumenten möglich
/// </summary>
/// <param name="name">Name des Arguments</param>
/// <returns>Inhalt des Arguments oder ArgumentNullException</returns>
public String GetArgumentData(String name)
{
foreach (ArgTouple t in this.argList) {
if (t.Type == name && t.Data != null) {
return t.Data;
} else {
throw new ArgumentNullException();
}
}
return null;
}
public Boolean HasAllRequiredArguments()
{
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (item.Value.Required && !this.HasArgumentType(item.Key)) {
return false;
}
}
return true;
}
public String GetUsageList(String name)
{
String ret = "Usage: " + name + " Parameter\nParameter:\n";
String req = "";
String opt = "";
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (item.Value.Required) {
req += item.Key + " " + ((item.Value.Length == ArgLength.Touple) ? " [data]\n" : "\n");
}
}
if (req != "") {
ret += "Benötigte Parameter:\n" + req;
}
foreach (KeyValuePair<String, VaildArguments> item in this.argsPosible) {
if (!item.Value.Required) {
opt += item.Key + " " + ((item.Value.Length == ArgLength.Touple) ? " [data]\n" : "\n");
}
}
if (opt != "") {
ret += "Optionale Parameter:\n" + opt;
}
return ret;
}
}
}

View File

@ -1,64 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace BlubbFish.Utils
{
public class FileLogger
{
private static readonly Dictionary<String, FileLogger> instances = new Dictionary<String, FileLogger>();
private static String logDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar;
private readonly StreamWriter file;
private FileLogger(String filename, Boolean append)
{
filename = logDir + filename;
if (!File.Exists(filename)) {
String folder = Path.GetDirectoryName(Path.GetFullPath(filename));
if (!Directory.Exists(folder)) {
_ = Directory.CreateDirectory(folder);
}
}
this.file = new StreamWriter(filename, append, Encoding.UTF8) {
AutoFlush = true
};
}
public static FileLogger GetInstance(String filename, Boolean append)
{
if (!instances.Keys.Contains(filename)) {
instances.Add(filename, new FileLogger(filename, append));
}
return instances[filename];
}
public static void SetLogDir(String v)
{
v = v.Replace("..", "");
v = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + v;
if (Directory.Exists(v)) {
logDir = v;
} else {
_ = Directory.CreateDirectory(v);
logDir = v;
}
if (logDir[^1..] != Path.DirectorySeparatorChar.ToString()) {
logDir += Path.DirectorySeparatorChar;
}
}
public void SetArray(String[] text)
{
this.file.Write(String.Join(this.file.NewLine, text) + this.file.NewLine);
this.file.Flush();
}
public void SetLine(String text)
{
this.file.WriteLine(text);
this.file.Flush();
}
public void SetLine(String text, DateTime d) => this.SetLine(d.ToString("[yyyy-MM-dd HH:mm:ss.ffff] ") + text);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace BlubbFish.Utils
{
public class FileLogger
{
private static Dictionary<String, FileLogger> instances = new Dictionary<String, FileLogger>();
private static String logDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar;
private StreamWriter file;
private FileLogger(String filename, Boolean append)
{
filename = logDir + filename;
if (!File.Exists(filename)) {
String folder = Path.GetDirectoryName(Path.GetFullPath(filename));
if (!Directory.Exists(folder)) {
Directory.CreateDirectory(folder);
}
}
this.file = new StreamWriter(filename, append, Encoding.UTF8) {
AutoFlush = true
};
}
public static FileLogger GetInstance(String filename, Boolean append)
{
if (!instances.Keys.Contains(filename)) {
instances.Add(filename, new FileLogger(filename, append));
}
return instances[filename];
}
public static void SetLogDir(String v)
{
v = v.Replace("..", "");
v = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + v;
if (Directory.Exists(v)) {
logDir = v;
} else {
Directory.CreateDirectory(v);
logDir = v;
}
if (logDir.Substring(logDir.Length - 1) != Path.DirectorySeparatorChar.ToString()) {
logDir = logDir + Path.DirectorySeparatorChar;
}
}
public void SetArray(String[] text)
{
this.file.Write(String.Join(this.file.NewLine, text) + this.file.NewLine);
this.file.Flush();
}
public void SetLine(String text)
{
this.file.WriteLine(text);
this.file.Flush();
}
public void SetLine(String text, DateTime d)
{
this.SetLine(d.ToString("[yyyy-MM-dd HH:mm:ss.ffff] ") + text);
}
}
}

View File

@ -1,73 +1,71 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace BlubbFish.Utils
{
public class FileMutex : IDisposable
{
private static FileMutex instance;
private String filename;
private StreamWriter file;
private FileMutex() { }
public static FileMutex Instance
{
get {
if (instance == null) {
instance = new FileMutex();
}
return instance;
}
}
public void SetName(String name)
{
String path = AppDomain.CurrentDomain.BaseDirectory;
SHA512Managed sha = new SHA512Managed();
this.filename = path + String.Join(String.Empty, Array.ConvertAll(sha.ComputeHash(Encoding.UTF8.GetBytes(name)), b => b.ToString("X2"))) + ".lock.txt";
sha.Dispose();
}
public Boolean Create()
{
if (File.Exists(this.filename)) {
return false;
}
this.file = new StreamWriter(this.filename);
this.InitFile();
return File.Exists(this.filename) && this.file != null;
}
private void InitFile()
{
this.file.Write("Created: " + DateTime.Now.ToUniversalTime() + "\n");
this.file.Flush();
}
public Boolean Delete()
{
if(this.file != null) {
this.file.Close();
}
File.Delete(this.filename);
return !File.Exists(this.filename);
}
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
if(this.file != null) {
this.file.Close();
}
}
}
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
}
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace BlubbFish.Utils
{
public class FileMutex : IDisposable
{
private static FileMutex instance;
private String filename;
private StreamWriter file;
private FileMutex() { }
public static FileMutex Instance
{
get {
if (instance == null) {
instance = new FileMutex();
}
return instance;
}
}
public void SetName(String name)
{
String path = AppDomain.CurrentDomain.BaseDirectory;
this.filename = path + String.Join(String.Empty, Array.ConvertAll(new SHA512Managed().ComputeHash(Encoding.UTF8.GetBytes(name)), b => b.ToString("X2"))) + ".lock.txt";
}
public Boolean Create()
{
if (File.Exists(this.filename)) {
return false;
}
this.file = new StreamWriter(this.filename);
InitFile();
return File.Exists(this.filename) && this.file != null;
}
private void InitFile()
{
this.file.Write("Created: " + DateTime.Now.ToUniversalTime() + "\n");
this.file.Flush();
}
public Boolean Delete()
{
if(this.file != null) {
this.file.Close();
}
File.Delete(this.filename);
return !File.Exists(this.filename);
}
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
if(this.file != null) {
this.file.Close();
}
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

185
InIReader.cs Normal file
View File

@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace BlubbFish.Utils
{
public class InIReader : IDisposable
{
private Dictionary<String, Dictionary<String, String>> cont;
private FileSystemWatcher k = new FileSystemWatcher(Directory.GetCurrentDirectory(), "*.ini");
private String filename;
private static Dictionary<String, InIReader> instances = new Dictionary<String, InIReader>();
private InIReader(String filename)
{
this.filename = filename;
this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
LoadFile();
}
public static InIReader GetInstance(String filename)
{
if (!instances.Keys.Contains(filename)) {
instances.Add(filename, new InIReader(filename));
}
return instances[filename];
}
private void ReadAgain(Object sender, EventArgs e)
{
this.LoadFile();
}
private void LoadFile()
{
this.cont = new Dictionary<String, Dictionary<String, String>>();
StreamReader file = new StreamReader(this.filename);
List<String> buf = new List<String>();
String fline = "";
while (fline != null) {
fline = file.ReadLine();
if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") {
buf.Add(fline);
}
}
file.Close();
Dictionary<String, String> sub = new Dictionary<String, String>();
String cap = "";
foreach (String line in buf) {
Match match = Regex.Match(line, @"^\[[a-zA-Z0-9\-_ ]+\]\w*$", RegexOptions.IgnoreCase);
if (match.Success) {
if (sub.Count != 0 && cap != "") {
this.cont.Add(cap, sub);
}
cap = line;
sub = new Dictionary<String, String>();
} else {
if (line != "" && cap != "") {
String key = line.Substring(0, line.IndexOf('='));
String value = line.Substring(line.IndexOf('=') + 1);
sub.Add(key, value);
}
}
}
if (sub.Count != 0 && cap != "") {
this.cont.Add(cap, sub);
}
}
public List<String> GetSections()
{
return this.cont.Keys.ToList<String>();
}
public String GetValue(String section, String key)
{
if (!section.StartsWith("[")) {
section = "[" + section + "]";
}
if (this.cont.Keys.Contains(section)) {
if (this.cont[section].Keys.Contains(key)) {
return this.cont[section][key];
}
}
return null;
}
public void SetValue(String section, String key, String value)
{
if (!section.StartsWith("[")) {
section = "[" + section + "]";
}
if (this.cont.Keys.Contains(section)) {
if (this.cont[section].Keys.Contains(key)) {
this.cont[section][key] = value;
} else {
this.cont[section].Add(key, value);
}
} else {
Dictionary<String, String> sub = new Dictionary<String, String> {
{ key, value }
};
this.cont.Add(section, sub);
}
this.Changed();
}
private void Changed()
{
this.k.Changed -= null;
SaveSettings();
LoadFile();
this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
}
private void SaveSettings()
{
StreamWriter file = new StreamWriter(this.filename);
file.BaseStream.SetLength(0);
file.BaseStream.Flush();
file.BaseStream.Seek(0, SeekOrigin.Begin);
foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.cont) {
file.WriteLine(cap.Key);
foreach (KeyValuePair<String, String> sub in cap.Value) {
file.WriteLine(sub.Key + "=" + sub.Value);
}
file.WriteLine();
}
file.Flush();
file.Close();
}
/// <summary>
/// Fügt eine neue Sektion in der Ini-Datei ein.
/// </summary>
/// <param name="name">Sektionsname</param>
/// <returns>true if added, false if error</returns>
public Boolean AddSection(String name)
{
if (!name.StartsWith("[")) {
name = "[" + name + "]";
}
if (this.cont.Keys.Contains(name)) {
return false;
}
this.cont.Add(name, new Dictionary<String, String>());
this.Changed();
return true;
}
/// <summary>
/// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei.
/// </summary>
/// <param name="name">Sektionsname</param>
/// <returns>true if removed, false if error</returns>
public Boolean RemoveSection(String name)
{
if (!name.StartsWith("[")) {
name = "[" + name + "]";
}
if (!this.cont.Keys.Contains(name)) {
return false;
}
this.cont.Remove(name);
this.Changed();
return false;
}
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
this.k.Dispose();
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

165
LICENSE
View File

@ -1,165 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

22
OwnController.cs Normal file
View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BlubbFish.Utils
{
public abstract class OwnController
{
/// <summary>
/// Führt den Controller aus.
/// </summary>
public void Execute()
{
this.Init();
}
abstract protected void Init();
abstract public void Dispose();
}
}

39
OwnModel.cs Normal file
View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlubbFish.Utils
{
public abstract class OwnModel<T> where T : class
{
private static readonly Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
private List<OwnView> observer = new List<OwnView>();
public static T Instance
{
get {
return _instance.Value;
}
}
private static T CreateInstanceOfT()
{
return Activator.CreateInstance(typeof(T), true) as T;
}
public void SetObserver(OwnView view)
{
this.observer.Add(view);
view.Update();
}
public void RemoveObserver(OwnView view) {
this.observer.Remove(view);
}
protected void Update()
{
this.observer.ForEach(delegate (OwnView view) { view.Update(); });
}
abstract protected void Init();
}
}

View File

@ -1,103 +1,126 @@
using System;
using System.Collections.Generic;
namespace BlubbFish.Utils
{
abstract public class OwnObject
{
public struct LogObject {
public LogObject(DateTime date, String location, String message, LogLevel level) {
this.Date = date;
this.Location = location;
this.Message = message;
this.Level = level;
}
public DateTime Date { get; set; }
public String Location { get; set; }
public String Message { get; set; }
public LogLevel Level { get; set; }
/// <summary>
/// Formates a LogMessage to a String
/// </summary>
/// <returns>Formated String</returns>
public override String ToString() => "[" + this.Date.ToString("R") + "]: " + this.Level.ToString() + " " + this.Location + ", " + this.Message;
/// <summary>
/// Formates a LogMessage to a String
/// </summary>
/// <param name="classNames">Enables the output of the location</param>
/// <param name="timeStamps">Enables the output of the date</param>
/// <returns>Formated String</returns>
public String ToString(Boolean classNames, Boolean timeStamps) => (timeStamps ? "[" + this.Date.ToString("R") + "]: " + this.Level.ToString() + " " : "") + (classNames ? this.Location + ", " : "") + this.Message;
}
private readonly List<LogObject> loglist = new List<LogObject>();
public delegate void LogEvent(Object sender, LogEventArgs e);
public enum LogLevel : Int32 {
Debug = 1,
Notice = 2,
Info = 4,
Warn = 8,
Error = 16
}
public event LogEvent EventDebug;
public event LogEvent EventNotice;
public event LogEvent EventInfo;
public event LogEvent EventWarn;
public event LogEvent EventError;
public event LogEvent EventLog;
/// <summary>
/// Get the Complete Log
/// </summary>
public List<String> GetLog(LogLevel level, Boolean classNames, Boolean timeStamps) {
List<String> ret = new List<String>();
foreach (LogObject t in this.loglist) {
if (t.Level >= level) {
ret.Add(t.ToString(classNames, timeStamps));
}
}
return ret;
}
/// <summary>
/// Put a message in the log
/// </summary>
/// <param name="location">Where the event arrives</param>
/// <param name="message">The logmessage itselfs</param>
/// <param name="level">Level of the message</param>
protected void AddLog(String location, String message, LogLevel level) => this.AddLog(location, message, level, DateTime.Now);
/// <summary>
/// Put a message in the log
/// </summary>
/// <param name="location">Where the event arrives</param>
/// <param name="message">The logmessage itselfs</param>
/// <param name="level">Level of the message</param>
/// <param name="date">Date of the message</param>
protected void AddLog(String location, String message, LogLevel level, DateTime date)
{
LogEventArgs e = new LogEventArgs(location, message, level, date);
if (level >= LogLevel.Debug) {
EventDebug?.Invoke(this, e);
}
if (level >= LogLevel.Notice) {
EventNotice?.Invoke(this, e);
}
if (level >= LogLevel.Info) {
EventInfo?.Invoke(this, e);
}
if (level >= LogLevel.Warn) {
EventWarn?.Invoke(this, e);
}
if (level >= LogLevel.Error) {
EventError?.Invoke(this, e);
}
EventLog?.Invoke(this, e);
this.loglist.Add(new LogObject(date, location, message, level));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BlubbFish.Utils
{
abstract public class OwnObject
{
public struct LogObject {
public LogObject(DateTime date, String location, String message, LogLevel level) {
this.Date = date;
this.Location = location;
this.Message = message;
this.Level = level;
}
public DateTime Date { get; set; }
public String Location { get; set; }
public String Message { get; set; }
public LogLevel Level { get; set; }
/// <summary>
/// Formates a LogMessage to a String
/// </summary>
/// <returns>Formated String</returns>
public override String ToString() {
return "[" + this.Date.ToString("R") + "]: " + this.Level.ToString() + " "+ this.Location + ", " + this.Message;
}
/// <summary>
/// Formates a LogMessage to a String
/// </summary>
/// <param name="classNames">Enables the output of the location</param>
/// <param name="timeStamps">Enables the output of the date</param>
/// <returns>Formated String</returns>
public String ToString(Boolean classNames, Boolean timeStamps) {
return (timeStamps ? "[" + this.Date.ToString("R") + "]: " + this.Level.ToString() + " " : "") + (classNames ? this.Location + ", " : "") + this.Message;
}
}
public class LogEventArgs : EventArgs {
public LogEventArgs(String location, String message, LogLevel level, DateTime date) {
this.Location = location;
this.Message = message;
this.Level = level;
this.Date = date;
}
public String Location { get; private set; }
public String Message { get; private set; }
public LogLevel Level { get; private set; }
public DateTime Date { get; private set; }
}
private List<LogObject> loglist = new List<LogObject>();
public delegate void LogEvent(Object sender, LogEventArgs e);
public enum LogLevel : Int32 {
Debug = 1,
Notice = 2,
Info = 4,
Warn = 8,
Error = 16
}
public event LogEvent EventDebug;
public event LogEvent EventNotice;
public event LogEvent EventInfo;
public event LogEvent EventWarn;
public event LogEvent EventError;
public event LogEvent EventLog;
/// <summary>
/// Get the Complete Log
/// </summary>
public List<String> GetLog(LogLevel level, Boolean classNames, Boolean timeStamps) {
List<String> ret = new List<String>();
foreach (LogObject t in this.loglist) {
if (t.Level >= level) {
ret.Add(t.ToString(classNames, timeStamps));
}
}
return ret;
}
/// <summary>
/// Put a message in the log
/// </summary>
/// <param name="location">Where the event arrives</param>
/// <param name="message">The logmessage itselfs</param>
/// <param name="level">Level of the message</param>
protected void AddLog(String location, String message, LogLevel level)
{
this.AddLog(location, message, level, DateTime.Now);
}
/// <summary>
/// Put a message in the log
/// </summary>
/// <param name="location">Where the event arrives</param>
/// <param name="message">The logmessage itselfs</param>
/// <param name="level">Level of the message</param>
/// <param name="date">Date of the message</param>
protected void AddLog(String location, String message, LogLevel level, DateTime date)
{
LogEventArgs e = new LogEventArgs(location, message, level, date);
if (EventDebug != null && level >= LogLevel.Debug) {
EventDebug(this, e);
}
if (EventNotice != null && level >= LogLevel.Notice) {
EventNotice(this, e);
}
if (EventInfo != null && level >= LogLevel.Info) {
EventInfo(this, e);
}
if (EventWarn != null && level >= LogLevel.Warn) {
EventWarn(this, e);
}
if (EventError != null && level >= LogLevel.Error) {
EventError(this, e);
}
EventLog?.Invoke(this, e);
this.loglist.Add(new LogObject(date, location, message, level));
}
}
}

View File

@ -1,18 +1,26 @@
namespace BlubbFish.Utils {
public abstract class OwnView {
protected OwnView() { }
/// <summary>
/// Called if the Oberver (Model) updates its View
/// </summary>
public abstract void Update();
/// <summary>
/// Called if view is viewed
/// </summary>
//protected abstract void Init();
/// <summary>
/// Called if Form is Disposed
/// </summary>
public abstract void Dispose();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BlubbFish.Utils {
public abstract class OwnView {
protected OwnView() {
this.Init();
}
/// <summary>
/// Called if the Oberver (Model) updates its View
/// </summary>
public abstract void Update();
/// <summary>
/// Called if view is viewed
/// </summary>
protected abstract void Init();
/// <summary>
/// Called if Form is Disposed
/// </summary>
public abstract void Dispose();
}
}

View File

@ -1,21 +1,18 @@
#if !NETCOREAPP
using System.Reflection;
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("Utils")]
[assembly: AssemblyDescription("Provides useful classes for other projects")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BlubbFish")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Utils")]
[assembly: AssemblyCopyright("Copyright © BlubbFish 2014 - 10.04.2021")]
[assembly: AssemblyTrademark("BlubbFish")]
[assembly: AssemblyCopyright("Copyright © 2014 - 24.04.2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("de-DE")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
@ -35,11 +32,5 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.5.0")]
[assembly: AssemblyFileVersion("1.5.0")]
#endif
/**
* 1.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class
* 1.4.0 Add Helper to Utils
*/
[assembly: AssemblyVersion("1.0.2.6")]
[assembly: AssemblyFileVersion("1.0.2.6")]

View File

@ -1,4 +0,0 @@
# BlubbFish.Utils (Utils)
Library containing helpfull utils
Maybe you find this Repo on Github. This is a mirror from [here](https://git.blubbfish.net/vs_utils/Utils).

145
Updater.cs Normal file
View File

@ -0,0 +1,145 @@

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Xml;
namespace BlubbFish.Utils {
public class Updater : OwnObject {
private static Updater instances;
private String url;
private VersionInfo[] versions;
public class UpdaterEventArgs : EventArgs {
public UpdaterEventArgs(Boolean hasUpdates, String message) {
this.HasUpdates = hasUpdates;
this.Message = message;
}
public String Message { get; private set; }
public Boolean HasUpdates { get; private set; }
}
public struct VersionInfo {
public VersionInfo(String name, String version, String filename, String guid) {
this.Name = name;
this.Version = version;
this.Filename = filename;
this.GUID = guid;
}
public VersionInfo(Type type) {
this.Name = type.Assembly.GetName().Name;
this.Version = type.Assembly.GetName().Version.ToString();
this.Filename = type.Assembly.ManifestModule.Name;
this.GUID = ((GuidAttribute)type.Assembly.GetCustomAttribute(typeof(GuidAttribute))).Value;
}
public String Name { get; private set; }
public String Version { get; private set; }
public String Filename { get; private set; }
public String GUID { get; private set; }
}
public delegate void UpdateStatus(Object sender, UpdaterEventArgs e);
public event UpdateStatus UpdateResult;
private Updater() { }
/// <summary>
/// Get Instance of Updater
/// </summary>
public static Updater Instance {
get {
if(instances == null) {
instances = new Updater();
}
return instances;
}
}
/// <summary>
/// Waits for the Result of the Updater thread.
/// </summary>
public void WaitForExit() {
throw new NotImplementedException();
}
/// <summary>
/// Set Path to check for Updates
/// </summary>
/// <param name="url">HTTP URI</param>
public void SetUpdateInfo(String url, VersionInfo[] versions) {
this.url = url;
this.versions = versions;
FileStream file = new FileStream("version.xml",FileMode.Create);
XmlTextWriter xml = new XmlTextWriter(file, Encoding.UTF8);
xml.WriteStartDocument();
xml.WriteWhitespace("\n");
xml.WriteStartElement("filelist");
xml.WriteWhitespace("\n");
foreach (VersionInfo version in versions) {
xml.WriteWhitespace("\t");
xml.WriteStartElement("file");
xml.WriteAttributeString("Version", version.Version);
xml.WriteAttributeString("Filename", version.Filename);
xml.WriteAttributeString("GUID", version.GUID);
xml.WriteString(version.Name);
xml.WriteEndElement();
xml.WriteWhitespace("\n");
}
xml.WriteEndElement();
xml.Flush();
file.Flush();
file.Close();
}
/// <summary>
/// Check for Updates
/// </summary>
/// <exception cref="ArgumentException"></exception>
public void Check() {
if(this.url == "") {
throw new ArgumentException("You must set url first.");
}
if(this.versions.Length == 0) {
throw new ArgumentException("You must set a Version number first.");
}
if(this.UpdateResult == null) {
throw new ArgumentNullException("You must attach an event first.");
}
Thread t = new Thread(this.Runner);
t.Start();
}
private void Runner() {
Thread.Sleep(1000);
WebRequest request = WebRequest.Create(this.url + "version.xml");
WebResponse response = null;
try {
response = request.GetResponse();
} catch(WebException e) {
this.UpdateResult(this, new UpdaterEventArgs(false, e.Message));
return;
}
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
String content = reader.ReadToEnd();
}
/// <summary>
/// Update the file
/// </summary>
/// <param name="filename">The filename of the targetfile</param>
/// <param name="url">The url of the sourcefile</param>
/// <param name="afterExit">Updates the Programm after it has been closed</param>
/// <returns></returns>
public Boolean Update(Boolean afterExit = true) {
return true;
}
}
}

View File

@ -1,22 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils-4.7.1.csproj", "{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,72 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BlubbFish.Utils</RootNamespace>
<AssemblyName>Utils</AssemblyName>
<TargetFrameworkVersion>v4.7.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CmdArgs.cs" />
<Compile Include="EventArgsHelper.cs" />
<Compile Include="FileLogger.cs" />
<Compile Include="FileMutex.cs" />
<Compile Include="Helper.cs" />
<Compile Include="InIReader.cs" />
<Compile Include="OwnController.cs" />
<Compile Include="OwnModel.cs" />
<Compile Include="OwnObject.cs" />
<Compile Include="OwnView.cs" />
<Compile Include="ProgramLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updater.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="..\CHANGELOG.md" />
<Content Include="..\CONTRIBUTING.md" />
<Content Include="..\LICENSE" />
<Content Include="..\README.md" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{FAC8CE64-BF13-4ECE-8097-AEB5DD060098}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BlubbFish.Utils</RootNamespace>
<AssemblyName>Utils</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CmdArgs.cs" />
<Compile Include="FileLogger.cs" />
<Compile Include="FileMutex.cs" />
<Compile Include="InIReader.cs" />
<Compile Include="OwnController.cs" />
<Compile Include="OwnModel.cs" />
<Compile Include="OwnObject.cs" />
<Compile Include="OwnView.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Updater.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils.csproj", "{A289C67C-BC49-46A0-8657-B444C605079E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A289C67C-BC49-46A0-8657-B444C605079E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A289C67C-BC49-46A0-8657-B444C605079E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A289C67C-BC49-46A0-8657-B444C605079E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A289C67C-BC49-46A0-8657-B444C605079E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A7224DC4-69F1-4273-BE78-3D9DC80A28C5}
EndGlobalSection
EndGlobal

View File

@ -1,32 +0,0 @@
using System;
namespace BlubbFish.Utils {
public class UpdaterEventArgs : EventArgs {
public UpdaterEventArgs(Boolean hasUpdates, String message) {
this.HasUpdates = hasUpdates;
this.Message = message;
}
public String Message { get; private set; }
public Boolean HasUpdates { get; private set; }
}
public class UpdaterFailEventArgs : EventArgs {
public UpdaterFailEventArgs(Exception e) => this.Except = e;
public Exception Except { get; private set; }
}
public class LogEventArgs : EventArgs {
public LogEventArgs(String location, String message, OwnObject.LogLevel level, DateTime date) {
this.Location = location;
this.Message = message;
this.Level = level;
this.Date = date;
}
public String Location { get; private set; }
public String Message { get; private set; }
public OwnObject.LogLevel Level { get; private set; }
public DateTime Date { get; private set; }
}
}

View File

@ -1,93 +0,0 @@
using System;
using System.ComponentModel;
using System.Reflection;
namespace BlubbFish.Utils {
public static class Helper {
#region PropertyHelper
public static Boolean HasProperty(this Object o, String type) {
Type t = o.GetType();
foreach (PropertyInfo item in t.GetProperties()) {
if (item.Name == type) {
return true;
}
}
return false;
}
public static Object GetProperty(this Object o, String name) {
PropertyInfo prop = o.GetType().GetProperty(name);
return prop.CanRead ? prop.GetValue(o) : null;
}
public static void SetProperty(this Object o, String name, String value) {
PropertyInfo prop = o.GetType().GetProperty(name);
if (prop.CanWrite) {
if (prop.PropertyType == typeof(Boolean) && Boolean.TryParse(value, out Boolean vb)) {
prop.SetValue(o, vb);
} else if (prop.PropertyType == typeof(Byte) && Byte.TryParse(value, out Byte v8)) {
prop.SetValue(o, v8);
} else if (prop.PropertyType == typeof(Int32) && Int32.TryParse(value, out Int32 v32)) {
prop.SetValue(o, v32);
} else if (prop.PropertyType == typeof(Single) && Single.TryParse(value, out Single vs)) {
prop.SetValue(o, vs);
} else if (prop.PropertyType == typeof(Double) && Double.TryParse(value, out Double vd)) {
prop.SetValue(o, vd);
} else if (prop.PropertyType == typeof(Int64) && Int64.TryParse(value, out Int64 v64)) {
prop.SetValue(o, v64);
} else if (prop.PropertyType.BaseType == typeof(Enum)) {
try {
prop.SetValue(o, Enum.Parse(prop.PropertyType, value));
} catch (Exception) { }
}
}
}
#endregion
#region FieldHelper
public static Object GetField(this Object o, String name) {
FieldInfo field = o.GetType().GetField(name);
return field.IsPublic ? field.GetValue(o) : null;
}
public static Object GetField(this Type o, String name) {
FieldInfo field = o.GetField(name);
return field.IsPublic ? field.GetValue(o) : null;
}
public static T GetEvent<T>(this Object o, String name) {
FieldInfo field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
return (T)field?.GetValue(o);
}
#endregion
#region InterfaceHelper
public static Boolean HasInterface(this Type o, Type interf) {
foreach (Type item in o.GetInterfaces()) {
if (item == interf) {
return true;
}
}
return false;
}
public static Boolean HasAbstract(this Type o, Type type) => o.BaseType == type;
#endregion
#region StringHelper
public static String GetEnumDescription(Enum value) {
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes != null && attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public static String ToUpperLower(this String s) => s.Length == 0 ? "" : s.Length == 1 ? s.ToUpper() : s[0].ToString().ToUpper() + s[1..].ToLower();
public static void WriteError(String text) {
Console.ForegroundColor = ConsoleColor.Red;
Console.Error.WriteLine("ERROR: " + text);
Console.ResetColor();
}
#endregion
}
}

View File

@ -1,59 +0,0 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace BlubbFish.Utils {
public class HttpEndpoint {
private readonly HttpClient client = new HttpClient();
private readonly String server = "";
public enum RequestMethod {
GET,
POST,
PUT
}
public HttpEndpoint(String server, String auth = null) {
this.server = server;
if(auth != null) {
this.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(auth);
}
}
public HttpEndpoint(String server, (String scheme, String parameter) auth) {
this.server = server;
this.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(auth.scheme, auth.parameter);
}
public async Task<String> RequestString(String address, String json = "", Boolean withoutput = true, RequestMethod method = RequestMethod.GET) {
String ret = null;
try {
HttpResponseMessage response = null;
if(method == RequestMethod.POST || method == RequestMethod.PUT) {
HttpContent content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//content.Headers.Add("Content-Type", "application/json");
if(method == RequestMethod.POST) {
response = await this.client.PostAsync(this.server + address, content);
} else if(method == RequestMethod.PUT) {
response = await this.client.PutAsync(this.server + address, content);
}
content.Dispose();
} else if(method == RequestMethod.GET) {
response = await this.client.GetAsync(this.server + address);
}
if(!response.IsSuccessStatusCode) {
throw new Exception(response.StatusCode + ": " + response.ReasonPhrase);
}
if(withoutput && response != null) {
ret = await response.Content.ReadAsStringAsync();
}
} catch(Exception e) {
throw new WebException(String.Format("Error while opening resource: \"{0}\" Method {1} Data {2} Fehler {3}", this.server + address, method, json, e.Message));
}
return ret;
}
}
}

View File

@ -1,257 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace BlubbFish.Utils {
public class InIReader : IDisposable
{
private Dictionary<String, Dictionary<String, String>> inifile;
private readonly FileSystemWatcher k;
private readonly String filename;
private static readonly List<String> search_path = new List<String>() {
Directory.GetCurrentDirectory()
};
private static readonly Dictionary<String, InIReader> instances = new Dictionary<String, InIReader>();
public static void SetSearchPath(List<String> directorys) => search_path.AddRange(directorys);
public static Boolean ConfigExist(String filename) {
foreach (String path in search_path) {
if (File.Exists(path + Path.DirectorySeparatorChar + filename)) {
return true;
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) {
return true;
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) {
return true;
}
}
return false;
}
private InIReader(String filename) {
foreach (String path in search_path) {
if (File.Exists(path + Path.DirectorySeparatorChar + filename)) {
this.filename = path + Path.DirectorySeparatorChar + filename;
this.k = new FileSystemWatcher(path, filename);
break;
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) {
this.filename = path + Path.DirectorySeparatorChar + filename + ".ini";
this.k = new FileSystemWatcher(path, filename + ".ini");
break;
} else if(File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) {
this.filename = path + Path.DirectorySeparatorChar + filename + ".conf";
this.k = new FileSystemWatcher(path, filename + ".conf");
break;
}
}
if(this.filename == null) {
throw new ArgumentException(filename + " not found!");
}
this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
this.LoadFile();
}
/// <summary>
/// Gibt eine InIReader-Instanz zu einer Datei zurück
/// </summary>
/// <param name="filename">Dateiname</param>
/// <returns></returns>
public static InIReader GetInstance(String filename) {
if (!instances.Keys.Contains(filename)) {
instances.Add(filename, new InIReader(filename));
}
return instances[filename];
}
private void ReadAgain(Object sender, EventArgs e) => this.LoadFile();
private void LoadFile() {
this.inifile = new Dictionary<String, Dictionary<String, String>>();
StreamReader file = new StreamReader(this.filename);
List<String> buf = new List<String>();
String fline = "";
while (fline != null) {
fline = file.ReadLine();
if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") {
buf.Add(fline);
}
}
file.Close();
Dictionary<String, String> sub = new Dictionary<String, String>();
String cap = "";
foreach (String line in buf) {
Match match = Regex.Match(line, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase);
if (match.Success) {
if (sub.Count != 0 && cap != "") {
this.inifile.Add(cap, sub);
}
cap = line;
sub = new Dictionary<String, String>();
} else {
if (line != "" && cap != "") {
String key = line.Substring(0, line.IndexOf('='));
String value = line[(line.IndexOf('=') + 1)..];
sub.Add(key, value);
}
}
}
if (sub.Count != 0 && cap != "") {
this.inifile.Add(cap, sub);
}
}
/// <summary>
/// Gibt eine Liste an Sektionen zurück
/// </summary>
/// <param name="withBrackets">Default = true; false, wenn die Liste ohne Klammern sein soll.</param>
/// <returns></returns>
public List<String> GetSections(Boolean withBrackets = true)
{
if(withBrackets) {
return this.inifile.Keys.ToList();
} else {
List<String> ret = new List<String>();
foreach (String item in this.inifile.Keys) {
ret.Add(item[1..^1]);
}
return ret;
}
}
/// <summary>
/// Überschreibt eine InI-Datei mit der Kompletten neuen Configuration
/// </summary>
/// <param name="config">Neue Konfiguration</param>
public void SetSections(Dictionary<String, Dictionary<String, String>> config) {
this.inifile.Clear();
foreach (KeyValuePair<String, Dictionary<String, String>> item in config) {
String key = item.Key;
if(!key.StartsWith("[")) {
key = "[" + key + "]";
}
if (Regex.Match(key, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase).Success) {
this.inifile.Add(key, item.Value);
}
}
this.Changed();
}
public Dictionary<String, String> GetSection(String section) => this.inifile.Keys.Contains(section) ?
this.inifile[section] : this.inifile.Keys.Contains("[" + section + "]") ?
this.inifile["[" + section + "]"] : new Dictionary<String, String>();
/// <summary>
/// Gibt einen einzelnen Wert zurück
/// </summary>
/// <param name="section">Name der Sektion</param>
/// <param name="key">Name des Wertes</param>
/// <returns></returns>
public String GetValue(String section, String key, String @default = null) {
if (!section.StartsWith("[")) {
section = "[" + section + "]";
}
return this.inifile.Keys.Contains(section) && this.inifile[section].Keys.Contains(key) ? this.inifile[section][key] : @default;
}
/// <summary>
/// Setzt einen Wert in einer Sektion
/// </summary>
/// <param name="section">Name der Sektion</param>
/// <param name="key">Name des Wertes</param>
/// <param name="value">Wert</param>
public void SetValue(String section, String key, String value)
{
if (!section.StartsWith("[")) {
section = "[" + section + "]";
}
if (this.inifile.Keys.Contains(section)) {
if (this.inifile[section].Keys.Contains(key)) {
this.inifile[section][key] = value;
} else {
this.inifile[section].Add(key, value);
}
} else {
Dictionary<String, String> sub = new Dictionary<String, String> {
{ key, value }
};
this.inifile.Add(section, sub);
}
this.Changed();
}
private void Changed()
{
this.k.Changed -= null;
this.SaveSettings();
this.LoadFile();
this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
}
private void SaveSettings()
{
StreamWriter file = new StreamWriter(this.filename);
file.BaseStream.SetLength(0);
file.BaseStream.Flush();
_ = file.BaseStream.Seek(0, SeekOrigin.Begin);
foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.inifile) {
file.WriteLine(cap.Key);
foreach (KeyValuePair<String, String> sub in cap.Value) {
file.WriteLine(sub.Key + "=" + sub.Value);
}
file.WriteLine();
}
file.Flush();
file.Close();
}
/// <summary>
/// Fügt eine neue Sektion in der Ini-Datei ein.
/// </summary>
/// <param name="name">Sektionsname</param>
/// <returns>true if added, false if error</returns>
public Boolean AddSection(String name)
{
if (!name.StartsWith("[")) {
name = "[" + name + "]";
}
if (this.inifile.Keys.Contains(name)) {
return false;
}
this.inifile.Add(name, new Dictionary<String, String>());
this.Changed();
return true;
}
/// <summary>
/// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei.
/// </summary>
/// <param name="name">Sektionsname</param>
/// <returns>true if removed, false if error</returns>
public Boolean RemoveSection(String name)
{
if (!name.StartsWith("[")) {
name = "[" + name + "]";
}
if (!this.inifile.Keys.Contains(name)) {
return false;
}
_ = this.inifile.Remove(name);
this.Changed();
return false;
}
protected virtual void Dispose(Boolean disposing) {
if (disposing) {
this.k.Dispose();
}
}
public void Dispose() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
}
}

View File

@ -1,11 +0,0 @@
namespace BlubbFish.Utils {
public abstract class OwnController
{
/// <summary>
/// Führt den Controller aus.
/// </summary>
public void Execute() => this.Init();
abstract protected void Init();
abstract public void Dispose();
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
namespace BlubbFish.Utils {
public abstract class OwnModel<T> where T : class
{
private static readonly Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
private readonly List<OwnView> observer = new List<OwnView>();
public static T Instance => _instance.Value;
private static T CreateInstanceOfT() => Activator.CreateInstance(typeof(T), true) as T;
public void SetObserver(OwnView view)
{
this.observer.Add(view);
view.Update();
}
public void RemoveObserver(OwnView view) => _ = this.observer.Remove(view);
protected void Update() => this.observer.ForEach(delegate (OwnView view) {
view.Update();
});
abstract protected void Init();
abstract public void Dispose();
}
}

View File

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BlubbFish.Utils {
public abstract class OwnSingeton<T> where T : class {
private static readonly Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
public static T Instance => _instance.Value;
private static T CreateInstanceOfT() => Activator.CreateInstance(typeof(T), true) as T;
}
}

View File

@ -1,175 +0,0 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace BlubbFish.Utils {
public class ProgramLogger {
private FileWriter fw;
private ConsoleWriter stdout;
private ConsoleWriter errout;
private String loggerfile;
public ProgramLogger(String path = null) {
this.loggerfile = path ?? Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "output.log";
this.Init(this.loggerfile);
this.AttachToFw();
this.SetOutputs();
}
private void SetOutputs() {
Console.SetOut(this.stdout);
Console.SetError(this.errout);
}
private void Init(String file) {
if(!this.IsWritable(file)) {
Console.Error.WriteLine("Cannot write to " + file);
throw new ArgumentException("Cannot write to " + file);
}
this.fw = new FileWriter(FileWriter.GetFileSteam(file, false));
this.stdout = new ConsoleWriter(Console.Out, ConsoleWriterEventArgs.ConsoleType.Info);
this.errout = new ConsoleWriter(Console.Error, ConsoleWriterEventArgs.ConsoleType.Error);
}
private Boolean IsWritable(String filename) {
try {
using FileStream fstream = new FileStream(filename, FileMode.Append);
using TextWriter writer = new StreamWriter(fstream);
writer.Write("");
} catch (UnauthorizedAccessException) {
return false;
}
return true;
}
public void SetPath(String file) {
if(file == null) {
return;
}
if (!this.IsWritable(file)) {
Console.Error.WriteLine("Cannot write to " + file);
throw new ArgumentException("Cannot write to " + file);
}
this.DisattachToFw();
this.fw.Close();
if(new FileInfo(this.loggerfile).Length > 0) {
if(File.Exists(file)) {
this.FileCopy(this.loggerfile, file);
File.Delete(this.loggerfile);
} else {
File.Move(this.loggerfile, file);
}
} else {
File.Delete(this.loggerfile);
}
this.loggerfile = file;
this.fw = new FileWriter(FileWriter.GetFileSteam(this.loggerfile, true));
this.AttachToFw();
}
public void Dispose() {
this.DisattachToFw();
this.fw.Dispose();
}
private void FileCopy(String source, String target) {
using FileStream fread = new FileStream(source, FileMode.Open);
using FileStream fwrite = new FileStream(target, FileMode.Create);
using TextReader reader = new StreamReader(fread);
using TextWriter writer = new StreamWriter(fwrite);
writer.Write(reader.ReadToEnd());
writer.Flush();
writer.Close();
reader.Close();
}
private void DisattachToFw() {
this.stdout.WriteEvent -= this.fw.Write;
this.stdout.WriteLineEvent -= this.fw.WriteLine;
this.errout.WriteEvent -= this.fw.Write;
this.errout.WriteLineEvent -= this.fw.WriteLine;
}
private void AttachToFw() {
this.stdout.WriteEvent += this.fw.Write;
this.stdout.WriteLineEvent += this.fw.WriteLine;
this.errout.WriteEvent += this.fw.Write;
this.errout.WriteLineEvent += this.fw.WriteLine;
}
}
internal class FileWriter : StreamWriter {
private Boolean newline = true;
public FileWriter(FileStream fs) : base(fs) {
}
public static FileStream GetFileSteam(String path, Boolean append) => File.Open(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? FileShare.Write : FileShare.ReadWrite);
public override Encoding Encoding => Encoding.UTF8;
public override Boolean AutoFlush { get => true; set => base.AutoFlush = value; }
private void Write(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) {
String text;
if (this.newline) {
text = "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value;
this.newline = false;
} else {
text = value;
}
origstream.Write(text);
base.Write(text);
base.Flush();
}
private void WriteLine(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) {
String text = this.newline ? "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value : value;
this.newline = true;
origstream.WriteLine(text);
base.WriteLine(text);
base.Flush();
}
internal void Write(Object sender, ConsoleWriterEventArgs e) => this.Write(e.Value, e.Writer, e.StreamType);
internal void WriteLine(Object sender, ConsoleWriterEventArgs e) => this.WriteLine(e.Value, e.Writer, e.StreamType);
}
internal class ConsoleWriterEventArgs : EventArgs {
public String Value { get; private set; }
public TextWriter Writer { get; private set; }
public ConsoleType StreamType { get; private set; }
public enum ConsoleType {
Info,
Error
}
public ConsoleWriterEventArgs(String value, TextWriter writer, ConsoleType type) {
this.Value = value;
this.Writer = writer;
this.StreamType = type;
}
}
internal class ConsoleWriter : TextWriter {
private readonly TextWriter stream;
private readonly ConsoleWriterEventArgs.ConsoleType streamtype;
public ConsoleWriter(TextWriter writer, ConsoleWriterEventArgs.ConsoleType type) {
this.stream = writer;
this.streamtype = type;
}
public override Encoding Encoding => Encoding.UTF8;
public override void Write(String value) => this.WriteEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype));
//base.Write(value);
public override void WriteLine(String value) => this.WriteLineEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype));
//base.WriteLine(value);
public event EventHandler<ConsoleWriterEventArgs> WriteEvent;
public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent;
}
}

View File

@ -1,195 +0,0 @@

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Xml;
namespace BlubbFish.Utils {
public class Updater : OwnObject {
private static Updater instances;
private String url;
private VersionInfo[] versions;
private Thread t;
public struct VersionInfo {
public VersionInfo(Type type) {
this.Name = type.Assembly.GetName().Name;
this.Version = type.Assembly.GetName().Version.ToString();
this.Filename = type.Assembly.ManifestModule.Name;
this.GUID = ((GuidAttribute)type.Assembly.GetCustomAttribute(typeof(GuidAttribute))).Value;
this.HasUpdate = false;
}
public String Name { get; private set; }
public String Version { get; private set; }
public String Filename { get; private set; }
public String GUID { get; private set; }
public Boolean HasUpdate { get; set; }
}
public delegate void UpdateStatus(Object sender, UpdaterEventArgs e);
public delegate void UpdateFail(Object sender, UpdaterFailEventArgs e);
public event UpdateStatus UpdateResult;
public event UpdateFail ErrorRaised;
private Updater() { }
/// <summary>
/// Get Instance of Updater
/// </summary>
public static Updater Instance {
get {
if(instances == null) {
instances = new Updater();
}
return instances;
}
}
/// <summary>
/// Waits for the Result of the Updater thread.
/// </summary>
public void WaitForExit(Boolean exceuteUpdate = true) {
while (this.t.ThreadState == ThreadState.Running) { }
if(exceuteUpdate) {
if(File.Exists("update.bat")) {
_ = System.Diagnostics.Process.Start("update.bat");
}
}
}
/// <summary>
/// Set Path to check for Updates
/// </summary>
/// <param name="url">HTTP URI</param>
public void SetUpdateInfo(String url, VersionInfo[] versions) {
this.url = url;
this.versions = versions;
FileStream file = new FileStream("version.xml",FileMode.Create);
XmlTextWriter xml = new XmlTextWriter(file, Encoding.UTF8);
xml.WriteStartDocument();
xml.WriteWhitespace("\n");
xml.WriteStartElement("filelist");
xml.WriteWhitespace("\n");
foreach (VersionInfo version in versions) {
xml.WriteWhitespace("\t");
xml.WriteStartElement("file");
xml.WriteAttributeString("Version", version.Version);
xml.WriteAttributeString("Filename", version.Filename);
xml.WriteAttributeString("GUID", version.GUID);
xml.WriteString(version.Name);
xml.WriteEndElement();
xml.WriteWhitespace("\n");
}
xml.WriteEndElement();
xml.Flush();
file.Flush();
file.Close();
xml.Close();
}
/// <summary>
/// Check for Updates
/// </summary>
/// <exception cref="ArgumentException"></exception>
public void Check() {
if(this.url == "") {
throw new ArgumentException("Zuerst eine URL setzen!");
}
if(this.versions.Length == 0) {
throw new ArgumentException("Zuerst Dateien registrieren!");
}
if(this.UpdateResult == null) {
throw new ArgumentNullException("Zuerst das Update Event anhängen.");
}
this.t = new Thread(this.Runner);
this.t.Start();
}
private void Runner() {
Thread.Sleep(1000);
try {
Stream stream = WebRequest.Create(this.url + "version.xml").GetResponse().GetResponseStream();
StreamReader sr = new StreamReader(stream);
String content = sr.ReadToEnd();
sr.Close();
Boolean update = false;
XmlDocument doc = new XmlDocument();
doc.LoadXml(content);
foreach (XmlNode node in doc.DocumentElement.ChildNodes) {
String guid = node.Attributes["GUID"].Value;
String version = node.Attributes["Version"].Value;
for(Int32 i=0;i<this.versions.Length;i++) {
if (this.versions[i].GUID == guid && this.versions[i].Version != version) {
this.versions[i].HasUpdate = true;
update = true;
}
}
}
if (update) {
this.UpdateResult(this, new UpdaterEventArgs(true, "Update verfügbar"));
return;
}
} catch (Exception e) {
this.ErrorRaised?.Invoke(this, new UpdaterFailEventArgs(e));
return;
}
this.UpdateResult(this, new UpdaterEventArgs(false, "Kein Update verfügbar"));
}
/// <summary>
/// Update the file
/// </summary>
/// <param name="afterExit">Updates the Programm after it has been closed</param>
/// <returns></returns>
public Boolean Update(Boolean afterExit = true) {
try {
if (afterExit) {
this.UpdateAfter();
} else {
this.UpdateNow();
}
} catch (Exception e) {
this.ErrorRaised?.Invoke(this, new UpdaterFailEventArgs(e));
return false;
}
return true;
}
private void UpdateAfter() {
this.UpdateNow(true);
StreamWriter update = new StreamWriter("update.bat", false);
update.WriteLine("echo off");
update.WriteLine("echo \"Warte 10s\"");
update.WriteLine("ping 127.0.0.1 -n 10");
update.WriteLine("echo \"Kopiere Dateien....\"");
foreach (VersionInfo file in this.versions) {
if (file.HasUpdate) {
update.WriteLine("echo \"Kopiere " + file.Filename + "\"");
update.WriteLine("del " + file.Filename);
update.WriteLine("move " + file.Filename + "_ " + file.Filename);
}
}
update.WriteLine("start cmd /C ping 127.0.0.1 -n 10 & del update.bat");
update.Flush();
update.Close();
}
private void UpdateNow(Boolean forAfter = false) {
foreach (VersionInfo file in this.versions) {
if (file.HasUpdate) {
Stream stream = WebRequest.Create(this.url + file.Filename).GetResponse().GetResponseStream();
FileStream target = new FileStream(file.Filename + (forAfter ? "_" : ""), FileMode.Create);
stream.CopyTo(target);
target.Flush();
target.Close();
}
}
}
}
}

View File

@ -1,60 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>Utils</AssemblyName>
<RootNamespace>BlubbFish.Utils</RootNamespace>
<Description>Provides useful classes for other projects</Description>
<Company>BlubbFish</Company>
<Authors>BlubbFish</Authors>
<PackageId>Utils.BlubbFish</PackageId>
<Copyright>Copyright © BlubbFish 2014 - 30.01.2022</Copyright>
<Version>1.6.2</Version>
<NeutralLanguage>de-DE</NeutralLanguage>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageProjectUrl>http://git.blubbfish.net/vs_utils/Utils</PackageProjectUrl>
<RepositoryUrl>http://git.blubbfish.net/vs_utils/Utils.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>
1.6.2 - 2022-01-30 - ProgrammLogger improved
1.6.1 - 2022-01-20 - ProgrammLogger Fixed
1.6.0 - 2022-01-09 - HttpEndpoint added
1.5.0 - 2021-04-10 - Add GetEvent so you can call events by string; Add OwnSingeton class
1.4.0 - 2018-11-27 - Add Helper to Utils
1.1.3 - 2018-10-02 - Improve CmdArgs
1.1.2 - 2018-09-11 - Tiny Codingstyles
1.1.1 - 2018-05-29 - ProgrammLogger neets to cleanup
1.1.0 - 2018-05-15 - ProgrammLogger
1.0.7.0 - 2018-05-08 - Yet another IniReader improvemnt round again
1.0.6.0 - 2017-12-22 - Yet another IniReader improvemnt round
1.0.5.2 - 2017-09-26 - And Improve IniReader again
1.0.5.1 - 2017-09-24 - Improve IniReader again
1.0.5.0 - 2017-08-09 - Improve IniReader
1.0.4.1 - 2017-08-08 - Cleanup OwnView
1.0.4.0 - 2017-04-30 - More Updater
1.0.3.2 - 2017-04-26 - Next Updater
1.0.3.1 - 2017-04-25 - EventArgsHelper
1.0.2.6 - 2017-04-24 - Better Updater
1.0.2.5 - 2017-04-19 - Logging in OwnObject
1.0.2.3 - 2017-04-16 - OwnModel better
1.0.2.2 - 2017-03-09 - Make it nice
1.0.2.1 - 2017-03-09 - Filemutex
1.0.0.1 - 2016-12-03 - Filelogger improvements
1.0.0.0 - 2015-11-16 - Init
</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<Content Include="../CHANGELOG.md" />
<Content Include="../CONTRIBUTING.md" />
<Content Include="../LICENSE" />
<Content Include="../README.md" />
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>

BIN
bin/Release/Utils.dll Normal file

Binary file not shown.