using DatenDB;
using Deckungsbeitrag.AA_Forms;
using Deckungsbeitrag.AA_Klassen;
using Deckungsbeitrag.Properties;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Management;
using System.Net;
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Web.Configuration;
using System.Web.SessionState;
using System.Windows.Forms;
namespace Deckungsbeitrag
{
public enum Priority
{
None = 0,
First = 1,
Second = 2,
Third = 3,
Fourth = 4,
Fifth = 5
}
// Globale Touch-Info (static für alle Forms)
public static class TouchHelper
{
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetRawInputDeviceList(IntPtr pRawInputDeviceList, ref uint puiNumDevices, uint cbSize);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);
private const int SM_DIGITIZER = 94;
private const int SM_MAXIMUMTOUCHES = 95;
private const int SM_CONVERTIBLESLATEMODE = 125;
private const int RIM_TYPEKEYBOARD = 1;
[StructLayout(LayoutKind.Sequential)]
private struct RAWINPUTDEVICELIST
{
public IntPtr hDevice;
public uint dwType;
}
public static readonly bool HasTouchHardware = (GetSystemMetrics(SM_DIGITIZER) & 0x80) != 0;
public static readonly int TouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
public static readonly bool IsTabletMode = GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 1;
public static bool IsTouchActive()
{
if (IsRegistryDisabled()) return false;
if (TouchPoints <= 0) return false;
int digitizer = GetSystemMetrics(SM_DIGITIZER);
bool touchReady = (digitizer & 0x00000001) != 0;
bool penReady = (digitizer & 0x00000002) != 0;
return touchReady || penReady;
}
public static bool IsTouchDeviceReady() => HasTouchHardware && IsTouchActive();
private static bool IsRegistryDisabled()
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Wisp\TouchGate"))
{
if (key != null)
{
object value = key.GetValue("TouchGate");
return value != null && Convert.ToInt32(value) == 0;
}
}
return false;
}
public static string GetStatus()
{
return $"Hardware: {HasTouchHardware}, TouchActive: {IsTouchActive()}, Points: {TouchPoints}, TabletMode: {IsTabletMode}";
}
}
static class Program
{
public static readonly UserSettingsManager _settings = new UserSettingsManager();
private static Mutex mutex;
public static Color Wirlblau = Settings.Default.Wirlblau;
public static ImageList imagelist = new ImageList();
public static string userid;
public static Benutzer benutzer;
public static bool Artikelliste_Importiert = false;
public static bool Kundenliste_Importiert = false;
public static bool Software_Updated = false;
private static readonly DateTime zielZeit = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day, 22, 0, 0);
private static System.Timers.Timer timer;
//public static string vaultPath = @"N:\TECHNIK\Software\Wirl-Verwaltung\Feedback";
private static readonly string savePath = ConfigurationManager.AppSettings["DateiSavePfad"];
private static readonly bool istest = false;
public static bool istTouch = TouchHelper.IsTouchDeviceReady();
public static int scrollBar = 25;
public static string title;
public static string caption;
public static string todo;
public static string[] buttons;
///
/// Der Haupteinstiegspunkt für die Anwendung.
///
[STAThread]
static void Main()
{
userid = ConfigurationManager.AppSettings["ConnectionString"].Split(';')[0];
userid = userid.Split('=')[1];
timer = new System.Timers.Timer
{
Interval = 1000
};
timer.Elapsed += Timer_Elapsed;
timer.Start();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Screen[] screens = Screen.AllScreens;
Cursor.Current = Cursors.WaitCursor;
string assemblyGUID = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).Cast().First().Value;
mutex = new Mutex(true, $"Global\\{assemblyGUID}");
if (!mutex.WaitOne(TimeSpan.Zero, true))
{
MessageBox.Show("Diese Anwendung ist bereits laufend. Nur eine Instanz darf gleichzeitig ausgeführt werden.",
"Nur eine Instanz", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
//FormLaden laden = new FormLaden();
//laden.Show();
_settings.Load();
// Laden der Translation.json
ConvertTranslationJson();
// Check, Install und Update wenn Update vorhanden.
if (CheckAndInstallUpdate())
{
CustomMessageBox.Show("Titel.Achtung", "Text.Achtung.UpdateFertig", "ToDo.UpdateFertig", new string[] { "Ok" });
Software_Updated = true;
Settings.Default.LastSoftwareUpdate = DateTime.Now;
Cursor.Current = Cursors.Default;
return;
}
// Laden der Image-Liste mit Icons für ObjectListView in Export etc.
ImageList_Laden();
// Importieren und Updaten der Kundenliste wenn Datei vorhanden.
KundenList_Laden();
// Importieren und Updaten der Artikelliste wenn Datei vorhanden.
ArtikelList_Laden();
// EINMALIG BEI SWITCH AUF NW_Artikel
DateTime timestamp = DateTime.Today;
List artikellist = Artikel.GetArtikelList("MitNachwaesche");
foreach (Artikel art in artikellist)
{
ArtikelNachwaesche nw = ArtikelNachwaesche.FindeDatensatz(art.ArtikelID, timestamp);
if (nw.NachwaescheID != null) nw.Nachwaesche++;
else
{
nw = new ArtikelNachwaesche()
{
ArtikelID = art.ArtikelID,
Datum = timestamp,
Nachwaesche = art.Nachwaesche
};
}
if (nw.Save() == 1)
{
art.Nachwaesche = 0;
art.Save();
}
}
Settings.Default.Save();
Application.UseWaitCursor = false;
if (istest) { Application.Run(new FormAufleger()); return; }
//laden.Close();
if (userid.Contains("geschaeft")) Application.Run(new FormGeschaeftMain());
if (userid.StartsWith("ms") | userid.StartsWith("ps"))
{
FormShowUserControl showControl = new FormShowUserControl("Sprache");
showControl.ShowDialog();
Maschine maschine = Maschine.GetMaschine(null, userid);
if (maschine == null)
{
maschine = new Maschine()
{
Faecher = 1,
Bezeichnung = userid,
TrocknerKaputt = false,
};
maschine.Save();
}
switch (userid)
{
case var s when s.Contains("wstrasse"):
//benutzer = Benutzer.GetBenutzer(null, 4);
Application.Run(new FormAufleger(userid));
break;
case var s when s.Contains("frottee"):
Application.Run(new FormFehlmengeCount(userid));
break;
case var s when s.Contains("kleinteile"):
Application.Run(new FormFehlmengeCount(userid));
break;
case var s when s.Contains("grossteile"):
Application.Run(new FormFehlmengeCount(userid));
break;
case var s when s.Contains("spannleintuch"):
Application.Run(new FormFehlmengeCount(userid));
break;
default:
break;
}
}
else
{
// Öffnen der ReadMe wenn noch nicht geöffnet wurde.
//Open_ReadMe();
FormLogin loginForm = new FormLogin();
if (loginForm.ShowDialog() == DialogResult.OK)
{
benutzer = loginForm.Person;
// Switch on BenutzerRolle für Weiterleitung zum richtigen Screen
switch (loginForm.Person.Rolle)
{
case BenutzerRolle.Verwaltung: //Büropersonal ohne aktive Hallenbeschäftigung
Application.Run(new FormMain(loginForm.Person));
break;
case BenutzerRolle.Fahrer: //Zustellfahrer
Application.Run(new FormMain(loginForm.Person));
break;
case BenutzerRolle.Admin: //Höheres Büropersonal oder Claudia und Kevin
Application.Run(new FormMain(loginForm.Person));
break;
case BenutzerRolle.Waschstrasse: //Bediener einer Waschstraße
Application.Run(new FormNeuerAuftrag(loginForm.Person, AuftragTyp.Standart));
break;
case BenutzerRolle.Master: //Entwickler oder Claudia und Kevin
Application.Run(new FormMain(loginForm.Person));
break;
case BenutzerRolle.Expedit: //Endkontrolle Lieferungen und Lieferscheine (Mirka)
Application.Run(new FormExpedit(loginForm.Person, screens));
break;
case BenutzerRolle.Frottee: //Containerbestückung Frotteewäsche
//BenutzerRolle Frottee = Expedit Frottee da die Maschine keine Anmeldung erfordert.
Application.Run(new FormExpedit(loginForm.Person, screens));
break;
case BenutzerRolle.Flach: //Containerbestückung Flachwäsche
//BenutzerRolle Flach = Expedit Frottee da die Maschine keine Anmeldung erfordert.
Application.Run(new FormExpedit(loginForm.Person, screens));
break;
default:
break;
}
}
}
}
private static void ConvertTranslationJson()
{
//TODO: Pfad anpassen wenn LIVE.
TranslationService.Convert(@"N:\TECHNIK\Software\Wirl-Verwaltung\Test\TranslationExcel.xlsx", @"N:\TECHNIK\Software\Wirl-Verwaltung\Test\translations.json", "Sheet1");
if (_settings.Culture == null) { _settings.Culture = "de-AT"; }
TranslationService.Load();
TranslationService.SetLanguage(_settings.Culture);
}
#region private-Funktionen
private static void Open_ReadMe()
{
string readmePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Verwaltung_ReadMe.txt");
// Prüfe, ob ReadMe schon einmal geöffnet wurde
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\KilianWirlGmbH\Verwaltung"))
{
if (key == null || key.GetValue("ReadMeShown") == null)
{
// Erstes Mal nach Installation
if (File.Exists(readmePath))
{
Process.Start(new ProcessStartInfo
{
FileName = readmePath,
UseShellExecute = true
});
// WICHTIG: Warte 2 Sekunden (ReadMe öffnen)
System.Threading.Thread.Sleep(2000);
// Abbruch-Dialog
DialogResult result = MessageBox.Show(
"ReadMe wurde geöffnet.\n\n" +
"Falls INSTALL-REMINDER noch Änderungen enthält,\n" +
"soll die Anwendung jetzt ABGEBROCHEN werden?\n\n" +
"[JA = Abbruch | NEIN = Fortfahren]",
"Nach Installation - Update prüfen",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1 // Standard: Abbruch
);
if (result == DialogResult.Yes)
{
MessageBox.Show("Installation wurde abgebrochen.\nBitte Änderungen vornehmen und neu installieren.",
"Abbruch", MessageBoxButtons.OK, MessageBoxIcon.Information);
return; // App beenden
}
// Markiere als gezeigt
Registry.CurrentUser.CreateSubKey(@"Software\KilianWirlGmbH\Verwaltung")
.SetValue("ReadMeShown", 1);
}
}
}
}
private static void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (DateTime.Now >= zielZeit)
{
timer.Stop();
timer.Dispose();
Application.Exit(); // Schließt alle Forms und beendet die App
}
}
private static void ArtikelList_Laden()
{
string updatePath = Path.Combine(savePath, "Listen");
string dateiName = "Artikelkurzliste.csv";
string row;
string[] rows;
try
{
// Prüfen ob File Artikelkurzliste existiert.
if (File.Exists(Path.Combine(updatePath, dateiName)))
{
string filename = Path.Combine(updatePath, dateiName);
StreamReader streamReader = new StreamReader(filename, Encoding.GetEncoding("iso-8859-1"));
row = string.Empty;
rows = new string[0];
int saved = 0;
int tosave = 0;
int idx = 1;
while (!streamReader.EndOfStream)
{
Array.Resize(ref rows, idx);
row = streamReader.ReadLine();
if (row.StartsWith("60") || row.StartsWith("10"))
{
rows[idx - 1] = row;
idx++;
}
}
streamReader.Close();
// Zeilen der Datei durchiterieren.
foreach (string line in rows)
{
string[] linedata = line.Split(';');
// ArtikelGruppen 60 und 10 werden weiterverarbeitet.
if (linedata[0] == "60" || linedata[0] == "10")
{
tosave++;
// Artikel wird in DB gesucht und geholt.
Artikel art = Artikel.GetArtikel(Convert.ToInt32(linedata[1]), null) ?? new Artikel();
art.Nummer = Convert.ToInt32(linedata[1]);
art.Bezeichnung = linedata[3];
// Kategorie wird nach Artikelnummer zugeordnet.
switch (art.Nummer)
{
case var nr when nr.ToString()[1] == '3': // 2.Stelle wird auf 3 überprüft
art.Kategorie = ArtikelKategorie.Frottee;
break;
case var nr when nr.ToString()[1] == '1' & nr.ToString()[2] == '1': // 2. und 3. Stelle wird auf 1 überprüft
if (nr.ToString()[4] == '5' || nr.ToString()[4] == '6') // 4. Stelle wird auf 5 oder 6 überprüft
{
if (nr.ToString()[4] == '5') art.Kategorie = ArtikelKategorie.Frottee; // Wenn 4. Stelle 5 dann Single Spannleintuch und ArtikelKategorie Frottee
else art.Kategorie = ArtikelKategorie.Spannleintuch;
}
else art.Kategorie = ArtikelKategorie.Grossteile;
break;
case var nr when nr.ToString()[1] == '1' & nr.ToString()[2] == '2': // 2. und 3. Stelle wird auf 2 überprüft
art.Kategorie = ArtikelKategorie.Kleinteile;
break;
default:
break;
}
// Wenn Artikel Shortbezeichnung ist vorhanden dann leeren damit neue Bezeichnung erstellt werden kann.
if (!string.IsNullOrWhiteSpace(art.Short)) art.Short = string.Empty;
// Erstellen der Shortbezeichnung für Buttons etc.
if (art.Bezeichnung.Contains("DOPPEL") | art.Bezeichnung.Contains("D-")) art.Short = art.Short + "D-";
if (art.Bezeichnung.Contains("SPANN")) art.Short = art.Short + "SP";
if (art.Bezeichnung.Contains("LEINTUCH")) art.Short = art.Short + "LT";
if (art.Bezeichnung.Contains("SPANN"))
{
string[] s = art.Bezeichnung.Split(' ');
if (s.Length == 3) art.Short = art.Short + " " + s[2];
} //Farben zuordnen und zu Short hinzufügen
if (art.Bezeichnung.Contains("HANDTUCH")) art.Short = art.Short + "HT";
if (art.Bezeichnung.Contains("DUSCHTUCH")) art.Short = art.Short + "DT";
if (art.Bezeichnung.Contains("BADETUCH")) art.Short = art.Short + "BT";
if (art.Bezeichnung.Contains("BADEVORLEGER")) art.Short = art.Short + "BV";
if (art.Bezeichnung.Contains("BADEMANTEL")) art.Short = art.Short + "BM";
if (art.Bezeichnung.Contains("SAUNATUCH")) art.Short = art.Short + "ST";
if (art.Bezeichnung.Contains("GESICHTSTUCH")) art.Short = art.Short + "GT";
if (art.Bezeichnung.Contains("POLSTERBEZUG"))
{
string extra;
int index = art.Bezeichnung.IndexOf(" ") + 1;
int length = art.Bezeichnung.IndexOf(" ", index + 1) - index;
art.Short = art.Short + "PB";
if (index > 0 & length > 0)
{
extra = art.Bezeichnung.Substring(index, length);
art.Short += " " + extra;
}
switch (art.Bezeichnung)
{
case var bez when bez.Contains("60x80"):
art.Short = art.Short + " 60x80";
break;
case var bez when bez.Contains("40x60"):
art.Short = art.Short + " 40x60";
break;
case var bez when bez.Contains("40x40"):
art.Short = art.Short + " 40x40";
break;
case var bez when bez.Contains("40x50"):
art.Short = art.Short + " 40x50";
break;
case var bez when bez.Contains("40x70"):
art.Short = art.Short + " 40x70";
break;
default:
break;
}
} //Größen zuordnen und zu Short hinzufügen
if (art.Bezeichnung.Contains("DECKENBEZUG"))
{
string extra;
int index = art.Bezeichnung.IndexOf(" ") + 1;
int length = art.Bezeichnung.IndexOf(" ", index + 1) - index;
art.Short = art.Short + "DB";
if (index > 0 & length > 0)
{
extra = art.Bezeichnung.Substring(index, length);
art.Short += " " + extra;
}
}
if (art.Bezeichnung.Contains("TISCHTUCH"))
{
art.Short = art.Short + "TT";
int index = art.Bezeichnung.IndexOf("x");
if (index > 0) art.Short = art.Short + art.Bezeichnung.Substring(index - 4, 8);
} //Tischtücher und Größen zuordnen und zu Short hinzufügen
if (art.Bezeichnung.Contains("MUNDSERVIETTE")) art.Short = art.Short + "MS";
if (art.Bezeichnung.Contains("DECKSERVIETTE")) art.Short = art.Short + "DS";
if (art.Save() == 1) saved++;
}
}
if (saved == tosave) { Artikelliste_Importiert = true; Settings.Default.LastArtikelUpdate = DateTime.Now; }
}
}
catch (Exception ex)
{
MessageBox.Show($"Import fehlgeschlagen: {ex.Message}\nPfad: {updatePath}\nDatei: {dateiName}", "IMPORT FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
// Wenn alles funktioniert hat wird die Datei gelöscht.
if (Artikelliste_Importiert) File.Delete(Path.Combine(updatePath, dateiName));
}
}
private static void KundenList_Laden()
{
string updatePath = Path.Combine(savePath, "Listen");
updatePath = @"N:\TECHNIK\Software\Wirl-Verwaltung\Listen"; //Pfad zu Listen
string dateiName = "Kundenstammblatt.csv";
string row;
string[] rows;
try
{
// Prüfen ob File Kundenstammblatt existiert.
if (File.Exists(Path.Combine(updatePath, dateiName)))
{
string filename = Path.Combine(updatePath, dateiName);
StreamReader sr = new StreamReader(filename, Encoding.GetEncoding("iso-8859-1"));
row = string.Empty;
rows = new string[0];
int saved = 0;
int tosave = 0;
int idx = 0;
while (!sr.EndOfStream)
{
Array.Resize(ref rows, ++idx);
row = sr.ReadLine();
rows[idx - 1] = row;
}
sr.Close();
// Jede Zeile der Datei wird durchiteriert.
foreach (string line in rows)
{
string[] linedata = line.Split(';');
// Wenn 1. Datensatz von linedata keine Zahlen sind oder 6. Datensatz Preisgruppe enthält wird Zeile ignoriert.
if (!int.TryParse(linedata[0], out _)) continue;
if (linedata[5].Contains("Preisgruppe")) continue;
tosave++;
// Kunde wird gesucht und aus DB geholt.
Kunde kunde = Kunde.GetKunde(linedata[0], null, null) ?? new Kunde();
kunde.KundeNummer = linedata[0];
kunde.KundeGruppe = linedata[3];
kunde.PLZ = int.TryParse(linedata[4], out int tmp2) ? tmp2 : 00;
kunde.KundeName = linedata[5];
kunde.KundeName2 = linedata[6];
kunde.Strasse = linedata[8];
kunde.Land = linedata[9];
kunde.Ort = linedata[10];
kunde.Bettenanzahl = int.TryParse(linedata[45], out int bett) ? bett : 0;
kunde.Waescheart = linedata[46];
if (kunde.Waescheart == "Miete") kunde.HatNachwaesche = true;
else kunde.HatNachwaesche = false;
if (kunde.Service != linedata[47])
{
if (MessageBox.Show($"Beim Kunde {kunde.KundeName} hat sich der Service geändert. Welcher Service soll gespeichert werden?\n\n{kunde.Service} => [JA]\n{linedata[47]} => [NEIN]", "SERVICE WÄHLEN", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) kunde.Service = linedata[47];
}
kunde.Region = linedata[48];
if (kunde.Suchtext != linedata[55]) kunde.Suchtext = linedata[55];
kunde.Aktiv = linedata[56] == "1";
if (kunde.Save() == 1) saved++;
}
if (saved == tosave) { Kundenliste_Importiert = true; Settings.Default.LastKundeUpdate = DateTime.Now; }
}
}
catch (Exception ex)
{
MessageBox.Show($"Import fehlgeschlagen: {ex.Message}\nPfad: {updatePath}\nDatei: {dateiName}", "IMPORT FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
// Wenn alles funktioniert hat wird die Datei gelöscht.
if (Kundenliste_Importiert) File.Delete(Path.Combine(updatePath, dateiName));
}
}
private static bool CheckAndInstallUpdate()
{
string updatePath = Path.Combine(savePath, "Setup");
if (ConfigurationManager.AppSettings["ConnectionString"].Split(';')[4].Split('=')[1] == "Test_Wirl") updatePath = Path.Combine(ConfigurationManager.AppSettings["DateiSavePfad"], "Test") ?? "Test";
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
//updatePath = @"N:\TECHNIK\Software\Wirl-Verwaltung\Setup"; // Ihr interner UNC-Pfad
try
{
string newVersion = File.Exists(Path.Combine(updatePath, "Version.txt")) ? File.ReadAllText(Path.Combine(updatePath, "Version.txt")).Trim() : string.Empty;
if (string.IsNullOrWhiteSpace(newVersion))
{
// Alle msi Files auflisten.
string[] msiFiles = Directory.GetFiles(updatePath, "SetupVerwaltung*.msi");
if (msiFiles.Length == 0) return false;
// Neueste Version aus Dateiname finden
string validMsis = msiFiles
.Select(f => new { Path = f, Version = GetVersionFromMsiFilename(f) })
.Where(x => IsValidVersion(x.Version))
.OrderByDescending(x => new Version(x.Version))
.FirstOrDefault()?.Version;
// Wenn Version ist valide wird sie als neue Version gführt.
if (validMsis != null) newVersion = validMsis;
}
// Prüfen ob neue Version ist größer als aktuelle Version.
if (new Version(newVersion).CompareTo(new Version(currentVersion)) > 0)
{
DialogResult result = CustomMessageBox.Show("Titel.Achtung", "Text.Achtung.Update", "ToDo.Update", new string[] { "Ok" });
string msiPath = Path.Combine(updatePath, $"SetupVerwaltung{newVersion}.msi");
if (result == DialogResult.OK)
{
try
{
// 1. MSI lokal kopieren (umgeht UNC-Fehler 2203)
string localMsi = Path.Combine(@"C:\tmp", $"SetupVerwaltung{newVersion}.msi");
File.Copy(msiPath, localMsi, true);
// 2. MSI starten
var psi = new ProcessStartInfo
{
FileName = "msiexec.exe",
Arguments = $"/i \"{localMsi}\" /norestart ALLUSERS=1 /L*v \"C:\\tmp\\update.log\"",
Verb = "runas",
UseShellExecute = true
};
// 3. 10 Sekunden warten (Restart Manager)
Thread.Sleep(10000);
using (var proc = Process.Start(psi))
{
proc.WaitForExit(); // Blockiert bis Installation beendet
}
string csvPath = Path.Combine(updatePath, "Install_Historie.txt");
if (File.Exists(csvPath))
{
File.AppendAllText(csvPath, $"\n{DateTime.Now} {userid} hat Version: {newVersion} erfolgreich installiert.\n", Encoding.UTF8);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show($"Start fehlgeschlagen: {ex.Message}", "UPDATE FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Update-Prüfung fehlgeschlagen: {ex.Message}\nPfad: {updatePath}",
"UPDATE FEHLER", MessageBoxButtons.OK, MessageBoxIcon.Warning);
AddFehler(null, ex.Message, ex.StackTrace, null);
}
return false;
}
private static string GetVersionFromMsiFilename(string msiFilePath)
{
string filename = Path.GetFileNameWithoutExtension(msiFilePath);
// Pattern: SetupVerwaltung1.0.44.msi → 1.0.44
// Oder: SetupVerwaltung_v1_0_44.msi → 1.0.44
Match match = Regex.Match(filename, @"(\d+(?:\.\d+){2,3})");
if (match.Success)
return match.Groups[1].Value;
return "0.0.0"; // Fallback
}
private static bool IsValidVersion(string version)
{
return Version.TryParse(version, out _);
}
private static void ImageList_Laden()
{
imagelist.Images.Add(Resources.Exclamation_Red);
imagelist.Images.Add(Resources.InformationSymbol_16x);
imagelist.Images.Add("print", Resources.PrintTag1);
imagelist.Images.Add("abschließen", Resources.checkmark);
imagelist.Images.Add("dirt", Resources.dirt);
imagelist.Images.Add("clean", Resources.clean);
imagelist.Images.Add("close", Resources.Close_red_16x);
}
#endregion
#region public-Funktion
public static void InventurFertig(Auftrag auftrag)
{
string savePath = Path.Combine(ConfigurationManager.AppSettings["DateiSavePfad"], "Listen\\Inventuren") ?? "Inventuren";
if (ConfigurationManager.AppSettings["ConnectionString"].Split(';')[4].Split('=')[1] == "Test_Wirl") savePath = Path.Combine(ConfigurationManager.AppSettings["DateiSavePfad"], "Test\\Inventuren") ?? "Inventuren";
Kunde kunde = Kunde.GetKunde(null, auftrag.KundeID, null);
string delPath = Path.Combine(savePath, $"Herrichten-{auftrag.AuftragID}-{kunde.KundeNummer}.csv");
string[] lines = null;
if (File.Exists(delPath))
{
lines = File.ReadAllLines(delPath, Encoding.UTF8);
lines[7] += auftrag.AuftragID.ToString();
string fileName = $"Fertig-{auftrag.AuftragID}-{kunde.KundeNummer}.csv"; // Dateiname: Status-AuftragID-KundeNummer.csv
string csvPath;
csvPath = Path.Combine(savePath, fileName);
var csv = new StringBuilder();
foreach (string line in lines) csv.AppendLine(line);
File.WriteAllText(csvPath, csv.ToString(), Encoding.UTF8);
if (File.Exists(delPath)) File.Delete(delPath);
}
}
public static void AddFeedback(Benutzer user, string feedbackText, string bildDateiname, string timeStamp)
{
string vaultPath = Path.Combine(savePath, "Feedback\\VerwaltungFeedback.md");
Benutzer ben = benutzer;
// Wenn User existiert wird dieser Verwendet. Sonst der bei Anmeldung registrierte Benutzer.
if (user != null) ben = user;
string feedback;
// Wenn der Bilddateiname leer ist wird feedback ohne Bilddateiname erstellt.
if (string.IsNullOrWhiteSpace(bildDateiname))
{
feedback = $@"- [ ] **Zeitpunkt:** {timeStamp} **| User:** {ben.Vorname} {ben.Nachname} **| Text:** {feedbackText}{Environment.NewLine}";
}
else feedback = $@" - [ ] **Zeitpunkt:** {timeStamp} **| User:** {ben.Vorname} {ben.Nachname} **| Text:** {feedbackText} **| Bild:** ![[{bildDateiname}.png]]{Environment.NewLine}";
// Test wenn Image mitgegeben wird wird es hier gespeichert. (Pfadprobleme)
File.AppendAllText(vaultPath, feedback);
}
public static DialogResult ShowOnBoarding(string userid, OnboardingSchritt onBoardingArt)
{
FormOnBoarding formOnBoarding = new FormOnBoarding(userid.ToLower(), onBoardingArt);
if (formOnBoarding.ShowDialog() == DialogResult.Cancel) return DialogResult.Cancel;
else return DialogResult.OK;
}
///
/// Fehler werden in Obsidian Fehlerliste Importiert.
///
/// wenn null dann in Program registrierter User
/// Fehlertext aus Exception oder individuell erstellen
/// wenn null wird StackTrace nicht eingefügt. Kann auch individuell verwendet werden (Ort des Fehlers)
/// wenn null wird TimeStamp hier erstellt
public static void AddFehler(Benutzer user, string fehlerText, string fehlerStackTrace, string timeStamp)
{
string path = Path.Combine(savePath, "Feedback");
string vaultPath = Path.Combine(path, "VerwaltungFehler.md");
Benutzer ben = benutzer;
// Wenn User existiert wird dieser Verwendet. Sonst der bei Anmeldung registrierte Benutzer.
if (user != null) ben = user;
string benutzerKennung;
if (ben == null) benutzerKennung = userid;
else benutzerKennung = ben.Vorname + " " + ben.Nachname;
if (timeStamp == null) timeStamp = DateTime.Now.ToString("dd.MM.yyyy-HH-mm");
//string bildPath = Path.Combine(savePath, bildDateiname);
string fehler;
// Wenn der Bilddateiname leer ist wird feedback ohne Bilddateiname erstellt.
if (string.IsNullOrWhiteSpace(fehlerStackTrace))
{
fehler = $@"- [ ] **Zeitpunkt:** {timeStamp} **| User:** {benutzerKennung} **| Fehler:** {fehlerText}{Environment.NewLine}";
}
else
{
string filename = $"fehler-{timeStamp}.txt";
string txtfile = Path.Combine(path, filename);
File.WriteAllText(txtfile, fehlerStackTrace);
fehler = $@" - [ ] **Zeitpunkt:** {timeStamp} **| User:** {benutzerKennung} **| Fehler:** {fehlerText} **| StackTrace:** [[{filename}]]{Environment.NewLine}";
}
// Test wenn Image mitgegeben wird wird es hier gespeichert. (Pfadprobleme)
File.AppendAllText(vaultPath, fehler);
}
#endregion
}
}
//DOEN: Mit AddFehler in Obsidian eine Fehlerliste betreiben. (Wichtige Infos feststellen und bereitstellen)
//DONE: Mit AddFehler können Fehler aus try/chatch in Obsidian eingefügt werden. (Timestamp, PC-Name, Ex-Message)